Reasonably major refactoring of the Felix class to implement the Bundle 
interface; now the Felix instance is the System Bundle instance. This
involved creating a new abstract Bundle base class, called FelixBundle,
which both Felix and BundleImpl now implement. 


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@553333 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/pom.xml b/framework/pom.xml
index f801259..53e1d7d 100644
--- a/framework/pom.xml
+++ b/framework/pom.xml
@@ -55,6 +55,28 @@
           </instructions>
         </configuration>
       </plugin>
+      <plugin>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>unpack</id>
+            <phase>package</phase>
+            <goals>
+              <goal>unpack</goal>
+            </goals>
+            <configuration>
+               <outputDirectory>${project.build.outputDirectory}</outputDirectory>
+              <artifactItems>
+                <artifactItem>
+                  <groupId>${project.groupId}</groupId>
+                  <artifactId>${project.artifactId}</artifactId>
+                  <version>${project.version}</version>
+                </artifactItem>
+              </artifactItems>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>  
 </project>
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index 64ad7af..e039b53 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -27,12 +27,14 @@
 
 class BundleContextImpl implements FelixBundleContext
 {
+    private Logger m_logger = null;
     private Felix m_felix = null;
-    private BundleImpl m_bundle = null;
+    private FelixBundle m_bundle = null;
     private boolean m_valid = true;
 
-    protected BundleContextImpl(Felix felix, BundleImpl bundle)
+    protected BundleContextImpl(Logger logger, Felix felix, FelixBundle bundle)
     {
+        m_logger = logger;
         m_felix = felix;
         m_bundle = bundle;
     }
@@ -99,7 +101,7 @@
     {
         checkValidity();
 
-        return new FilterImpl(m_felix.getLogger(), expr);
+        return new FilterImpl(m_logger, expr);
     }
 
     public Bundle installBundle(String location)
@@ -263,7 +265,7 @@
         }
         catch (InvalidSyntaxException ex)
         {
-            m_felix.getLogger().log(Logger.LOG_ERROR, "BundleContextImpl: " + ex);
+            m_logger.log(Logger.LOG_ERROR, "BundleContextImpl: " + ex);
         }
         return null;
     }
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index b55dabc..5de3b50 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -23,10 +23,9 @@
 import java.net.URL;
 import java.util.*;
 
-import org.apache.felix.framework.util.MapToDictionary;
 import org.osgi.framework.*;
 
-class BundleImpl implements Bundle
+class BundleImpl extends FelixBundle
 {
     private Felix m_felix = null;
     private BundleInfo m_info = null;
@@ -37,23 +36,22 @@
         m_info = info;
     }
 
-    Felix getFelix() // package protected
-    {
-        return m_felix;
-    }
-
-    BundleInfo getInfo() // package protected
+    /* package private */ BundleInfo getInfo()
     {
         return m_info;
     }
 
-    void setInfo(BundleInfo info) // package protected
+    /*
+     * Only used when refreshing a bundle.
+    **/
+    /* package private */ void setInfo(BundleInfo info)
     {
         m_info = info;
     }
 
     public BundleContext getBundleContext()
     {
+// TODO: SECURITY - We need a security check here.
         return m_info.getBundleContext();
     }
 
@@ -228,9 +226,9 @@
 
                         break;
                     }
-                    catch (Exception e)
+                    catch (Exception ex)
                     {
-
+                        // Silently ignore.
                     }
                 }
             }
@@ -284,9 +282,9 @@
 
                         break;
                     }
-                    catch (Exception e)
+                    catch (Exception ex)
                     {
-
+                        // Silently ignore.
                     }
                 }
             }
@@ -399,17 +397,8 @@
         return m_felix.getBundleSymbolicName(this) + " [" + getBundleId() +"]";
     }
 
-    public boolean equals(Object obj)
-    {
-        if (obj instanceof BundleImpl)
-        {
-            return (((BundleImpl) obj).getInfo().getBundleId() == getInfo().getBundleId());
-        }
-        return false;
-    }
-
     Object getSignerMatcher()
     {
         return null;
     }
-}
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleInfo.java b/framework/src/main/java/org/apache/felix/framework/BundleInfo.java
index 8697012..1f3aaeb 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleInfo.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleInfo.java
@@ -52,7 +52,6 @@
     private Thread m_lockThread = null;
 
     protected BundleInfo(Logger logger, BundleArchive archive, IModule module)
-        throws Exception
     {
         m_logger = logger;
         m_archive = archive;
@@ -85,7 +84,7 @@
      * no limit on the potential number of bundle JAR file revisions.
      * @return array of modules corresponding to the bundle JAR file revisions.
     **/
-    public IModule[] getModules()
+    public synchronized IModule[] getModules()
     {
         return m_modules;
     }
@@ -96,7 +95,7 @@
      * @return <tt>true</tt> if the specified module is in the array of modules
      *         associated with this bundle, <tt>false</tt> otherwise.
     **/
-    public boolean hasModule(IModule module)
+    public synchronized boolean hasModule(IModule module)
     {
         for (int i = 0; i < m_modules.length; i++)
         {
@@ -113,7 +112,7 @@
      * in the module array.
      * @return the newest module.
     **/
-    public IModule getCurrentModule()
+    public synchronized IModule getCurrentModule()
     {
         return m_modules[m_modules.length - 1];
     }
@@ -123,7 +122,7 @@
      * the bundle associated with this <tt>BundleInfo</tt> object.
      * @param module the module to add.
     **/
-    public void addModule(IModule module)
+    public synchronized void addModule(IModule module)
     {
         IModule[] dest = new IModule[m_modules.length + 1];
         System.arraycopy(m_modules, 0, dest, 0, m_modules.length);
@@ -349,12 +348,12 @@
         return result;
     }
 
-    public int getState()
+    public synchronized int getState()
     {
         return m_state;
     }
 
-    public void setState(int i)
+    public synchronized void setState(int i)
     {
         m_state = i;
     }
@@ -450,42 +449,42 @@
         }
     }
 
-    public BundleContext getBundleContext()
+    public synchronized BundleContext getBundleContext()
     {
         return m_context;
     }
 
-    public void setBundleContext(BundleContext context)
+    public synchronized void setBundleContext(BundleContext context)
     {
         m_context = context;
     }
 
-    public BundleActivator getActivator()
+    public synchronized BundleActivator getActivator()
     {
         return m_activator;
     }
 
-    public void setActivator(BundleActivator activator)
+    public synchronized void setActivator(BundleActivator activator)
     {
         m_activator = activator;
     }
 
-    public boolean isStale()
+    public synchronized boolean isStale()
     {
         return m_stale;
     }
 
-    public void setStale()
+    public synchronized void setStale()
     {
         m_stale = true;
     }
 
-    public boolean isExtension()
+    public synchronized boolean isExtension()
     {
         return m_extension;
     }
 
-    public void setExtension(boolean extension)
+    public synchronized void setExtension(boolean extension)
     {
         m_extension = extension;
     }
@@ -496,12 +495,12 @@
     // will only ever be called when the caller is in a synchronized block.
     //
 
-    public boolean isLockable()
+    public synchronized boolean isLockable()
     {
         return (m_lockCount == 0) || (m_lockThread == Thread.currentThread());
     }
 
-    public void lock()
+    public synchronized void lock()
     {
         if ((m_lockCount > 0) && (m_lockThread != Thread.currentThread()))
         {
@@ -511,7 +510,7 @@
         m_lockThread = Thread.currentThread();
     }
 
-    public void unlock()
+    public synchronized void unlock()
     {
         if (m_lockCount == 0)
         {
@@ -528,7 +527,7 @@
         }
     }
 
-    public void syncLock(BundleInfo info)
+    public synchronized void syncLock(BundleInfo info)
     {
         m_lockCount = info.m_lockCount;
         m_lockThread = info.m_lockThread;
diff --git a/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java b/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
index 3d92ecc..84dcbfd 100644
--- a/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ExportedPackageImpl.java
@@ -27,14 +27,15 @@
 class ExportedPackageImpl implements ExportedPackage
 {
     private Felix m_felix = null;
-    private BundleImpl m_exportingBundle = null;
+    private FelixBundle m_exportingBundle = null;
     private IModule m_exportingModule = null;
     private Capability m_export = null;
     private String m_toString = null;
     private String m_versionString = null;
 
     public ExportedPackageImpl(
-        Felix felix, BundleImpl exporter, IModule module, Capability export)
+        
+        Felix felix, FelixBundle exporter, IModule module, Capability export)
     {
         m_felix = felix;
         m_exportingBundle = exporter;
diff --git a/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
new file mode 100644
index 0000000..31a47fd
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/ExtensionManager.java
@@ -0,0 +1,570 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.security.AllPermission;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.framework.util.PropertyResolver;
+import org.apache.felix.framework.util.Util;
+import org.apache.felix.framework.util.manifestparser.Capability;
+import org.apache.felix.framework.util.manifestparser.ManifestParser;
+import org.apache.felix.framework.util.manifestparser.R4Directive;
+import org.apache.felix.framework.util.manifestparser.R4Library;
+import org.apache.felix.moduleloader.ICapability;
+import org.apache.felix.moduleloader.IContent;
+import org.apache.felix.moduleloader.IContentLoader;
+import org.apache.felix.moduleloader.IModuleDefinition;
+import org.apache.felix.moduleloader.IRequirement;
+import org.apache.felix.moduleloader.ISearchPolicy;
+import org.apache.felix.moduleloader.IURLPolicy;
+import org.osgi.framework.AdminPermission;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.Constants;
+
+/**
+ * The ExtensionManager class is used in several ways. 
+ * <p>
+ * First, a private instance is added (as URL with the instance as 
+ * URLStreamHandler) to the classloader that loaded the class. 
+ * It is assumed that this is an instance of URLClassloader (if not extension 
+ * bundles will not work). Subsequently, extension bundles can be managed by 
+ * instances of this class (their will be one instance per framework instance). 
+ * </p>
+ * <p>
+ * Second, it is used as module definition of the systembundle. Added extension
+ * bundles with exported packages will contribute their exports to the 
+ * systembundle export.
+ * </p>
+ * <p>
+ * Third, it is used as content loader of the systembundle. Added extension 
+ * bundles exports will be available via this loader.
+ * </p>
+ */
+// The general approach is to have one private static instance that we register 
+// with the parent classloader and one instance per framework instance that
+// keeps track of extension bundles and systembundle exports for that framework
+// instance.
+class ExtensionManager extends URLStreamHandler implements IModuleDefinition, IContentLoader
+{
+    // The private instance that is added to Felix.class.getClassLoader() -
+    // will be null if extension bundles are not supported (i.e., we are not 
+    // loaded by an instance of URLClassLoader)
+    private static final ExtensionManager m_extensionManager;
+    
+    static
+    {
+        // We use the secure action of Felix to add a new instance to the parent 
+        // classloader. 
+        ExtensionManager extensionManager = new ExtensionManager();
+        try
+        {
+            Felix.m_secureAction.addURLToURLClassLoader(Felix.m_secureAction.createURL(
+                Felix.m_secureAction.createURL(null, "felix:", extensionManager),
+                "felix://extensions/", extensionManager),
+                Felix.class.getClassLoader());
+        }
+        catch (Exception ex) 
+        {
+            // extension bundles will not be supported. 
+            extensionManager = null;
+        }
+        m_extensionManager = extensionManager;
+    }
+
+    private Logger m_logger = null;
+    private BundleInfo m_systemBundleInfo = null;
+    private ICapability[] m_capabilities = null;
+    private Set m_exportNames = null;
+    private ISearchPolicy m_searchPolicy = null;
+    private IURLPolicy m_urlPolicy = null;
+    private final List m_extensions = new ArrayList();
+    private final Set m_names = new HashSet();
+    private final Map m_sourceToExtensions = new HashMap();
+    
+    // This constructor is only used for the private instance added to the parent
+    // classloader.
+    private ExtensionManager()
+    {
+        
+    }
+    
+    /**
+     * This constructor is used to create one instance per framework instance.
+     * The general approach is to have one private static instance that we register 
+     * with the parent classloader and one instance per framework instance that
+     * keeps track of extension bundles and systembundle exports for that framework
+     * instance.
+     * 
+     * @param logger the logger to use.
+     * @param config the configuration to read properties from.
+     * @param systemBundleInfo the info to change if we need to add exports.
+     */
+    ExtensionManager(Logger logger, PropertyResolver config, BundleInfo systemBundleInfo)
+    {
+        m_logger = logger;
+        m_systemBundleInfo = systemBundleInfo;
+
+// TODO: FRAMEWORK - Not all of this stuff really belongs here, probably only exports.
+        // Populate system bundle header map.
+        Map map = ((SystemBundleArchive) m_systemBundleInfo.getArchive()).getManifestHeader(0);
+        // Initialize header map as a case insensitive map.
+        map.put(FelixConstants.BUNDLE_VERSION,
+            config.get(FelixConstants.FELIX_VERSION_PROPERTY));
+        map.put(FelixConstants.BUNDLE_SYMBOLICNAME,
+            FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME);
+        map.put(FelixConstants.BUNDLE_NAME, "System Bundle");
+        map.put(FelixConstants.BUNDLE_DESCRIPTION,
+            "This bundle is system specific; it implements various system services.");
+        map.put(FelixConstants.EXPORT_SERVICE,
+            "org.osgi.service.packageadmin.PackageAdmin," +
+            "org.osgi.service.startlevel.StartLevel," +
+            "org.osgi.service.url.URLHandlers");
+
+        // The system bundle exports framework packages as well as
+        // arbitrary user-defined packages from the system class path.
+        // We must construct the system bundle's export metadata.
+        // Get system property that specifies which class path
+        // packages should be exported by the system bundle.
+        try
+        {
+            setCapabilities(ManifestParser.parseExportHeader(
+                config.get(Constants.FRAMEWORK_SYSTEMPACKAGES)));
+        }
+        catch (Exception ex)
+        {
+            m_capabilities = new ICapability[0];
+            m_logger.log(
+                Logger.LOG_ERROR,
+                "Error parsing system bundle export statement: "
+                + config.get(Constants.FRAMEWORK_SYSTEMPACKAGES), ex);
+        }
+    }
+
+    /**
+     * Check whether the given manifest headers are from an extension bundle.
+     */
+    boolean isExtensionBundle(Map headers)
+    {
+        R4Directive dir = ManifestParser.parseExtensionBundleHeader((String)
+            headers.get(Constants.FRAGMENT_HOST));
+    
+        return (dir != null) && (Constants.EXTENSION_FRAMEWORK.equals(
+            dir.getValue()) || Constants.EXTENSION_BOOTCLASSPATH.equals(
+            dir.getValue()));
+    }
+
+    /**
+     * Add an extension bundle. The bundle will be added to the parent classloader
+     * and it's exported packages will be added to the module definition 
+     * exports of this instance. Subsequently, they are available form the 
+     * instance in it's role as content loader.
+     * 
+     * @param felix the framework instance the given extension bundle comes from.
+     * @param bundle the extension bundle to add.
+     * @throws BundleException if extension bundles are not supported or this is
+     *          not a framework extension.
+     * @throws SecurityException if the caller does not have the needed 
+     *          AdminPermission.EXTENSIONLIFECYCLE and security is enabled.
+     * @throws Exception in case something goes wrong.
+     */
+    void addExtensionBundle(Felix felix, FelixBundle bundle) 
+        throws SecurityException, BundleException, Exception
+    {
+        Object sm = System.getSecurityManager();
+        if (sm != null)
+        {
+            ((SecurityManager) sm).checkPermission(
+                new AdminPermission(bundle, AdminPermission.EXTENSIONLIFECYCLE));
+        }
+    
+        ProtectionDomain pd = (ProtectionDomain)
+        bundle.getInfo().getCurrentModule().getSecurityContext();
+    
+        if (pd != null)
+        {
+            if (!pd.implies(new AllPermission()))
+            {
+                throw new SecurityException("Extension Bundles must have AllPermission");
+            }
+        }
+    
+        R4Directive dir = ManifestParser.parseExtensionBundleHeader((String)
+            bundle.getInfo().getCurrentHeader().get(Constants.FRAGMENT_HOST));
+    
+        // We only support classpath extensions (not bootclasspath).
+        if (!Constants.EXTENSION_FRAMEWORK.equals(dir.getValue()))
+        {
+            throw new BundleException("Unsupported Extension Bundle type: " +
+                dir.getValue(), new UnsupportedOperationException(
+                "Unsupported Extension Bundle type!"));
+        }
+    
+        // Not sure whether this is a good place to do it but we need to lock
+        felix.acquireBundleLock(felix);
+    
+        try
+        {
+            bundle.getInfo().setExtension(true);
+    
+            SystemBundleArchive systemArchive =
+                (SystemBundleArchive) felix.getInfo().getArchive();
+        
+            // Merge the exported packages with the exported packages of the systembundle.
+            Map headers = null;
+            ICapability[] exports = null;
+            try
+            {
+                exports = ManifestParser.parseExportHeader((String)
+                    bundle.getInfo().getCurrentHeader().get(Constants.EXPORT_PACKAGE));
+            }
+            catch (Exception ex)
+            {
+                m_logger.log(
+                    Logger.LOG_ERROR,
+                    "Error parsing extension bundle export statement: "
+                    + bundle.getInfo().getCurrentHeader().get(Constants.EXPORT_PACKAGE), ex);
+                return;
+            }
+        
+            // Add the bundle as extension if we support extensions
+            if (this != null) 
+            {
+                // This needs to be the private instance.
+                m_extensionManager.addExtension(felix, bundle);
+            }
+            else
+            {
+                // We don't support extensions (i.e., the parent is not an URLClassLoader).
+                m_logger.log(Logger.LOG_WARNING,
+                    "Unable to add extension bundle to FrameworkClassLoader - Maybe not an URLClassLoader?");
+                throw new UnsupportedOperationException(
+                    "Unable to add extension bundle to FrameworkClassLoader - Maybe not an URLClassLoader?");
+            }
+            ICapability[] temp = new ICapability[getCapabilities().length + exports.length];
+            System.arraycopy(getCapabilities(), 0, temp, 0, getCapabilities().length);
+            System.arraycopy(exports, 0, temp, getCapabilities().length, exports.length);
+            setCapabilities(temp);
+        }
+        catch (Exception ex)
+        {
+            bundle.getInfo().setExtension(false);
+            throw ex;
+        }
+        finally
+        {
+            felix.releaseBundleLock(felix);
+        }
+    
+        bundle.getInfo().setState(Bundle.RESOLVED);
+    }
+
+    /**
+     * This is a Felix specific extension mechanism that allows extension bundles
+     * to have activators and be started via this method.
+     * 
+     * @param felix the framework instance the extension bundle is installed in.
+     * @param bundle the extension bundle to start if it has a Felix specific activator.
+     */
+    void startExtensionBundle(Felix felix, FelixBundle bundle)
+    {
+        String activatorClass = (String)
+        bundle.getInfo().getCurrentHeader().get(
+            FelixConstants.FELIX_EXTENSION_ACTIVATOR);
+        
+        if (activatorClass != null)
+        {
+            try
+            {
+                BundleActivator activator = (BundleActivator)
+                    felix.getClass().getClassLoader().loadClass(
+                        activatorClass.trim()).newInstance();
+                felix.m_activatorList.add(activator);
+                if (felix.m_activatorContextMap == null)
+                {
+                    felix.m_activatorContextMap = new HashMap();
+                }
+                BundleContext context = new BundleContextImpl(m_logger, felix, bundle);
+                felix.m_activatorContextMap.put(activator, context);
+                Felix.m_secureAction.startActivator(activator, context);
+            }
+            catch (Throwable ex)
+            {
+                m_logger.log(Logger.LOG_WARNING,
+                    "Unable to start Felix Extension Activator", ex);
+            }
+        }
+    }
+    
+    /**
+     * Remove all extension registered by the given framework instance. Note, it
+     * is not possible to unregister allready loaded classes form those extensions.
+     * That is why the spec requires a JVM restart.
+     * 
+     * @param felix the framework instance whose extensions need to be unregistered. 
+     */
+    void removeExtensions(Felix felix) 
+    {
+        m_extensionManager._removeExtensions(felix);
+    }
+
+    //
+    // IModuleDefinition
+    //
+    public ICapability[] getCapabilities()
+    {
+        return m_capabilities;
+    }
+
+    void setCapabilities(ICapability[] capabilities)
+    {
+        m_capabilities = capabilities;
+
+        Map map = ((SystemBundleArchive) m_systemBundleInfo.getArchive()).getManifestHeader(0);
+        map.put(FelixConstants.EXPORT_PACKAGE, convertCapabilitiesToHeaders(map));
+        ((SystemBundleArchive) m_systemBundleInfo.getArchive()).setManifestHeader(map);
+    }
+
+    public IRequirement[] getDynamicRequirements()
+    {
+        return null;
+    }
+
+    public R4Library[] getLibraries()
+    {
+        return null;
+    }
+
+    public IRequirement[] getRequirements()
+    {
+        return null;
+    }
+
+    private String convertCapabilitiesToHeaders(Map headers)
+    {
+        StringBuffer exportSB = new StringBuffer("");
+        Set exportNames = new HashSet();
+
+        for (int i = 0; (m_capabilities != null) && (i < m_capabilities.length); i++)
+        {
+            if (i > 0)
+            {
+                exportSB.append(", ");
+            }
+
+            exportSB.append(((Capability) m_capabilities[i]).getPackageName());
+            exportSB.append("; version=\"");
+            exportSB.append(((Capability) m_capabilities[i]).getPackageVersion().toString());
+            exportSB.append("\"");
+
+            exportNames.add(((Capability) m_capabilities[i]).getPackageName());
+        }
+
+        m_exportNames = exportNames;
+
+        return exportSB.toString();
+    }
+    
+    //
+    // IContentLoader
+    //
+    
+    public void open()
+    {
+        // Nothing needed here.
+    }
+
+    public void close()
+    {
+        // Nothing needed here.
+    }
+
+    public IContent getContent()
+    {
+        return null;
+    }
+
+    public ISearchPolicy getSearchPolicy()
+    {
+        return m_searchPolicy;
+    }
+
+    public void setSearchPolicy(ISearchPolicy searchPolicy)
+    {
+        m_searchPolicy = searchPolicy;
+    }
+
+    public IURLPolicy getURLPolicy()
+    {
+        return m_urlPolicy;
+    }
+
+    public void setURLPolicy(IURLPolicy urlPolicy)
+    {
+        m_urlPolicy = urlPolicy;
+    }
+
+    public Class getClass(String name)
+    {
+        if (!m_exportNames.contains(Util.getClassPackage(name)))
+        {
+            return null;
+        }
+
+        try
+        {
+            return getClass().getClassLoader().loadClass(name);
+        }
+        catch (ClassNotFoundException ex)
+        {
+            m_logger.log(
+                Logger.LOG_WARNING,
+                ex.getMessage(),
+                ex);
+        }
+        return null;
+    }
+
+    public URL getResource(String name)
+    {
+        return getClass().getClassLoader().getResource(name);
+    }
+
+    public Enumeration getResources(String name)
+    {
+       try
+       {
+           return getClass().getClassLoader().getResources(name);
+       }
+       catch (IOException ex)
+       {
+           return null;
+       }
+    }
+
+    public URL getResourceFromContent(String name)
+    {
+        // There is no content for the system bundle, so return null.
+        return null;
+    }
+
+    public boolean hasInputStream(int index, String urlPath) throws IOException
+    {
+        return (getClass().getClassLoader().getResource(urlPath) != null);
+    }
+
+    public InputStream getInputStream(int index, String urlPath) throws IOException
+    {
+        return getClass().getClassLoader().getResourceAsStream(urlPath);
+    }
+
+    public String findLibrary(String name)
+    {
+        // No native libs associated with the system bundle.
+        return null;
+    }
+    
+    //
+    // Classpath Extension
+    //
+
+    /*
+     * See whether any registered extension provides the class requested. If not
+     * throw an IOException.
+     */
+    protected synchronized URLConnection openConnection(URL url) throws IOException
+    {
+        String path = url.getPath();
+
+        if (path.trim().equals("/"))
+        {
+            throw new IOException("Resource not provided by any extension!");
+        }
+
+        for (Iterator iter = m_extensions.iterator(); iter.hasNext();)
+        {
+            URL result = ((Bundle) iter.next()).getEntry(path);
+
+            if (result != null)
+            {
+                return result.openConnection();
+            }
+        }
+
+        throw new IOException("Resource not provided by any extension!");
+    }
+
+    private synchronized void addExtension(Object source, Bundle extension)
+    {
+        List sourceExtensions = (List) m_sourceToExtensions.get(source);
+
+        if (sourceExtensions == null)
+        {
+            sourceExtensions = new ArrayList();
+            m_sourceToExtensions.put(source, sourceExtensions);
+        }
+
+        sourceExtensions.add(extension);
+
+        _add(extension.getSymbolicName(), extension);
+    }
+
+    private synchronized void _removeExtensions(Object source)
+    {
+        if (m_sourceToExtensions.remove(source) == null)
+        {
+            return;
+        }
+
+        m_extensions.clear();
+        m_names.clear();
+
+        for (Iterator iter = m_sourceToExtensions.values().iterator(); iter.hasNext();)
+        {
+            Bundle bundle = (Bundle) iter.next();
+            _add(bundle.getSymbolicName(), bundle);
+        }
+    }
+
+    private void _add(String name, Bundle extension)
+    {
+        if (!m_names.contains(name))
+        {
+            m_names.add(name);
+            m_extensions.add(extension);
+        }
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 5e0d5d8..e8c6cdb 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -33,15 +33,18 @@
 import org.osgi.service.packageadmin.ExportedPackage;
 import org.osgi.service.startlevel.StartLevel;
 
-public class Felix
+public class Felix extends FelixBundle
 {
     // The secure action used to do privileged calls
     static SecureAction m_secureAction = new SecureAction();
+
+    // The extension manager to handle extension bundles
+    private ExtensionManager m_extensionManager;
     
     // Logging related member variables.
-    private Logger m_logger = null;
+    private Logger m_logger = null; // TODO: KARL - Why package private?
     // Config properties.
-    private PropertyResolver m_config = new ConfigImpl();
+    private PropertyResolver m_config = null;
     // Configuration properties passed into constructor.
     private MutablePropertyResolver m_configMutable = null;
 
@@ -69,19 +72,12 @@
     private Object[] m_installedBundleLock_Priority2 = new Object[0];
 
     // An array of uninstalled bundles before a refresh occurs.
-    private BundleImpl[] m_uninstalledBundles = null;
+    private FelixBundle[] m_uninstalledBundles = null;
     // This lock must be acquired to modify m_uninstalledBundles;
     // to help avoid deadlock this lock as priority 3 and should
     // be acquired before locks with lower priority.
     private Object[] m_uninstalledBundlesLock_Priority3 = new Object[0];
 
-    // Status flag for framework.
-    public static final int INITIAL_STATUS  = -1;
-    public static final int RUNNING_STATUS  = 0;
-    public static final int STARTING_STATUS = 1;
-    public static final int STOPPING_STATUS = 2;
-    private int m_frameworkStatus = INITIAL_STATUS;
-
     // Framework's active start level.
     private int m_activeStartLevel =
         FelixConstants.FRAMEWORK_INACTIVE_STARTLEVEL;
@@ -89,6 +85,12 @@
     // Local file system cache.
     private BundleCache m_cache = null;
 
+    // System bundle bundle info instance.
+    private BundleInfo m_systemBundleInfo = null;
+    // System bundle activator list.
+    List m_activatorList = null;
+    Map m_activatorContextMap = null;
+
     // Next available bundle identifier.
     private long m_nextId = 1L;
     private Object m_nextIdLock = new Object[0];
@@ -106,6 +108,9 @@
     private String m_executionEnvironment = "";
     private Set m_executionEnvironmentCache = new HashSet();
 
+    // Shutdown thread.
+    private Thread m_shutdownThread = null;
+
     /**
      * <p>
      * This method starts the framework instance; instances of the framework
@@ -204,25 +209,16 @@
      *
      * @param configMutable An object for obtaining configuration properties,
      *        may be <tt>null</tt>.
-     * @param frameworkProps An object for obtaining framework properties,
-     *        may be <tt>null</tt>.
      * @param activatorList A list of System Bundle activators.
     **/
-    public synchronized void start(MutablePropertyResolver configMutable,
-        List activatorList)
+    public Felix(MutablePropertyResolver configMutable, List activatorList)
     {
-        if (m_frameworkStatus != INITIAL_STATUS)
-        {
-            throw new IllegalStateException("Invalid framework status: " + m_frameworkStatus);
-        }
-
-        // The framework is now in its startup sequence.
-        m_frameworkStatus = STARTING_STATUS;
-
         // Initialize member variables.
         m_factory = null;
         m_configMutable = (configMutable == null)
             ? new MutablePropertyResolverImpl(new StringMap(false)) : configMutable;
+        m_config = new PropertyResolverImpl(m_configMutable);
+        m_activatorList = activatorList;
 
         // Create logger with appropriate log level. Even though the
         // logger needs the system bundle's context for tracking log
@@ -237,11 +233,338 @@
         m_installedBundleMap = new HashMap();
         m_uninstalledBundles = null;
         m_cache = null;
+        m_systemBundleInfo = null;
         m_nextId = 1L;
         m_dispatcher = null;
-        m_bundleStreamHandler = new URLHandlersBundleStreamHandler(this);
-        m_registry = new ServiceRegistry(m_logger);
 
+        // Initialize framework properties.
+        initializeFrameworkProperties();
+
+        // Create the module factory and add the system bundle
+        // module to it, since we need the system bundle info
+        // object to keep track of the framework state.
+        m_factory = new ModuleFactoryImpl(m_logger);
+        m_systemBundleInfo = new BundleInfo(
+            m_logger, new SystemBundleArchive(), null);
+        m_extensionManager = 
+            new ExtensionManager(m_logger, m_config, m_systemBundleInfo);
+        m_systemBundleInfo.addModule(
+            m_factory.createModule("0", m_extensionManager));
+    }
+
+    //
+    // System Bundle methods.
+    //
+
+    /* package private */ BundleInfo getInfo()
+    {
+        return m_systemBundleInfo;
+    }
+
+    public BundleContext getBundleContext()
+    {
+// TODO: SECURITY - We need a security check here.
+        if (m_systemBundleInfo != null)
+        {
+            return m_systemBundleInfo.getBundleContext();
+        }
+        return null;
+    }
+
+    public long getBundleId()
+    {
+        return 0;
+    }
+
+    public URL getEntry(String name)
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            try
+            {
+                ((SecurityManager) sm).checkPermission(new AdminPermission(this,
+                    AdminPermission.RESOURCE));
+            }
+            catch (Exception e)
+            {
+                return null; // No permission
+            }
+        }
+
+        return getBundleEntry(this, name);
+    }
+
+    public Enumeration getEntryPaths(String path)
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            try
+            {
+                ((SecurityManager) sm).checkPermission(new AdminPermission(this,
+                    AdminPermission.RESOURCE));
+            }
+            catch (Exception e)
+            {
+                return null; // No permission
+            }
+        }
+
+        return getBundleEntryPaths(this, path);
+    }
+
+    public Enumeration findEntries(String path, String filePattern, boolean recurse)
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            try
+            {
+                ((SecurityManager) sm).checkPermission(new AdminPermission(this,
+                    AdminPermission.RESOURCE));
+            }
+            catch (Exception e)
+            {
+                return null; // No permission
+            }
+        }
+
+        return findBundleEntries(this, path, filePattern, recurse);
+    }
+
+    public Dictionary getHeaders()
+    {
+        return getHeaders(Locale.getDefault().toString());
+    }
+
+    public Dictionary getHeaders(String locale)
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            ((SecurityManager) sm).checkPermission(new AdminPermission(this,
+                AdminPermission.METADATA));
+        }
+        return getBundleHeaders(this, locale);
+    }
+
+    public long getLastModified()
+    {
+        if (m_systemBundleInfo != null)
+        {
+            return m_systemBundleInfo.getLastModified();
+        }
+        return -1;
+    }
+
+    public String getLocation()
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            ((SecurityManager) sm).checkPermission(new AdminPermission(this,
+                AdminPermission.METADATA));
+        }
+        return Constants.SYSTEM_BUNDLE_LOCATION;
+    }
+
+    public URL getResource(String name)
+    {
+        return getBundleResource(this, name);
+    }
+
+    public Enumeration getResources(String name) throws IOException
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            try
+            {
+                ((SecurityManager) sm).checkPermission(new AdminPermission(this,
+                    AdminPermission.RESOURCE));
+            }
+            catch (Exception e)
+            {
+                return null; // No permission
+            }
+        }
+
+        return getBundleResources(this, name);
+    }
+
+    public ServiceReference[] getRegisteredServices()
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            ServiceReference[] refs = getBundleRegisteredServices(this);
+
+            if (refs == null)
+            {
+                return refs;
+            }
+
+            List result = new ArrayList();
+
+            for (int i = 0;i < refs.length;i++)
+            {
+                String[] objectClass = (String[]) refs[i].getProperty(
+                    Constants.OBJECTCLASS);
+
+                if (objectClass == null)
+                {
+                    continue;
+                }
+
+                for (int j = 0;j < objectClass.length;j++)
+                {
+                    try
+                    {
+                        ((SecurityManager) sm).checkPermission(new ServicePermission(
+                            objectClass[j], ServicePermission.GET));
+
+                        result.add(refs[i]);
+
+                        break;
+                    }
+                    catch (Exception ex)
+                    {
+                        // Silently ignore.
+                    }
+                }
+            }
+
+            if (result.isEmpty())
+            {
+                return null;
+            }
+
+            return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
+        }
+        else
+        {
+            return getBundleRegisteredServices(this);
+        }
+    }
+
+    public ServiceReference[] getServicesInUse()
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            ServiceReference[] refs = getBundleServicesInUse(this);
+
+            if (refs == null)
+            {
+                return refs;
+            }
+
+            List result = new ArrayList();
+
+            for (int i = 0;i < refs.length;i++)
+            {
+                String[] objectClass = (String[]) refs[i].getProperty(
+                    Constants.OBJECTCLASS);
+
+                if (objectClass == null)
+                {
+                    continue;
+                }
+
+                for (int j = 0;j < objectClass.length;j++)
+                {
+                    try
+                    {
+                        ((SecurityManager) sm).checkPermission(new ServicePermission(
+                            objectClass[j], ServicePermission.GET));
+
+                        result.add(refs[i]);
+
+                        break;
+                    }
+                    catch (Exception e)
+                    {
+                        // Silently ignore.
+                    }
+                }
+            }
+
+            if (result.isEmpty())
+            {
+                return null;
+            }
+
+            return (ServiceReference[]) result.toArray(new ServiceReference[result.size()]);
+        }
+
+        return getBundleServicesInUse(this);
+    }
+
+    public int getState()
+    {
+        return m_systemBundleInfo.getState();
+    }
+
+    public String getSymbolicName()
+    {
+        return Constants.SYSTEM_BUNDLE_LOCATION;
+    }
+
+    public boolean hasPermission(Object obj)
+    {
+        return true;
+    }
+
+    public Class loadClass(String name) throws ClassNotFoundException
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            try
+            {
+                ((SecurityManager) sm).checkPermission(new AdminPermission(this,
+                    AdminPermission.CLASS));
+            }
+            catch (Exception e)
+            {
+                throw new ClassNotFoundException("No permission.", e);
+            }
+        }
+
+        return loadBundleClass(this, name);
+    }
+
+    public synchronized void start() throws BundleException
+    {
+        // The system bundle is only started once and it
+        // is started by the framework.
+        if (getState() == Bundle.ACTIVE)
+        {
+            return;
+        }
+        else if (m_systemBundleInfo.getState() != Bundle.INSTALLED)
+        {
+            throw new IllegalStateException("Invalid framework state: " + m_systemBundleInfo.getState());
+        }
+
+        // The framework is now in its startup sequence.
+        m_systemBundleInfo.setState(Bundle.STARTING);
+
+        // Create default bundle stream handler.
+        m_bundleStreamHandler = new URLHandlersBundleStreamHandler(this);
+
+        // Create service registry.
+        m_registry = new ServiceRegistry(m_logger);
         // Add a listener to the service registry; this is
         // used to distribute service registry events to
         // service listeners.
@@ -254,7 +577,7 @@
 
         try
         {
-            m_cache = new BundleCache(m_config, m_logger);
+            m_cache = new BundleCache(m_logger, m_config);
         }
         catch (Exception ex)
         {
@@ -285,19 +608,19 @@
         m_policyCore.addResolverListener(new ResolveListener() {
             public void moduleResolved(ModuleEvent event)
             {
-                BundleImpl bundle = null;
+                FelixBundle bundle = null;
                 try
                 {
                     long id = Util.getBundleIdFromModuleId(
                         event.getModule().getId());
-                    if (id >= 0)
+                    if (id > 0)
                     {
                         // Update the bundle's state to resolved when the
                         // current module is resolved; just ignore resolve
                         // events for older revisions since this only occurs
                         // when an update is done on an unresolved bundle
                         // and there was no refresh performed.
-                        bundle = (BundleImpl) getBundle(id);
+                        bundle = (FelixBundle) getBundle(id);
 
                         // Lock the bundle first.
                         try
@@ -332,45 +655,34 @@
             }
         });
 
-        m_factory = new ModuleFactoryImpl(m_logger);
         m_policyCore.setModuleFactory(m_factory);
 
         // Initialize event dispatcher.
         m_dispatcher = EventDispatcher.start(m_logger);
 
-        // Initialize framework properties.
-        initializeFrameworkProperties();
-
         // Before we reload any cached bundles, let's create a system
         // bundle that is responsible for providing specific container
         // related services.
-        SystemBundle systembundle = null;
         try
         {
-            // Create a simple bundle info for the system bundle.
-            BundleInfo info = new BundleInfo(
-                m_logger, new SystemBundleArchive(), null);
-            systembundle = new SystemBundle(this, info, activatorList);
-            systembundle.getInfo().addModule(m_factory.createModule("0",
-                systembundle));
-            systembundle.getContentLoader().setSearchPolicy(
+            IContentLoader cl = m_extensionManager;
+            cl.setSearchPolicy(
                 new R4SearchPolicy(
-                    m_policyCore, systembundle.getInfo().getCurrentModule()));
+                    m_policyCore, m_systemBundleInfo.getCurrentModule()));
             m_factory.setContentLoader(
-                systembundle.getInfo().getCurrentModule(),
-                systembundle.getContentLoader());
+                m_systemBundleInfo.getCurrentModule(),
+                cl);
             m_factory.setSecurityContext(
-                systembundle.getInfo().getCurrentModule(),
-                systembundle.getClass().getProtectionDomain());
+                m_systemBundleInfo.getCurrentModule(),
+                getClass().getProtectionDomain());
 
             m_installedBundleMap.put(
-                systembundle.getInfo().getLocation(), systembundle);
-
+                m_systemBundleInfo.getLocation(), this);
             // Manually resolve the System Bundle, which will cause its
             // state to be set to RESOLVED.
             try
             {
-                m_policyCore.resolve(systembundle.getInfo().getCurrentModule());
+                m_policyCore.resolve(m_systemBundleInfo.getCurrentModule());
             }
             catch (ResolveException ex)
             {
@@ -380,12 +692,15 @@
                         + ex.getRequirement());
             }
 
-            // Start the system bundle; this will set its state
-            // to STARTING, we must set its state to ACTIVE after
-            // all bundles are restarted below according to the spec.
-            systembundle.start();
+            // Create system bundle activator.
+            m_systemBundleInfo.setActivator(new SystemBundleActivator());
+
+            // Create the bundle context for the system bundle and
+            // then activate it.
+            m_systemBundleInfo.setBundleContext(new BundleContextImpl(m_logger, this, this));
+            Felix.m_secureAction.startActivator(m_systemBundleInfo.getActivator(), m_systemBundleInfo.getBundleContext());
         }
-        catch (Exception ex)
+        catch (Throwable ex)
         {
             m_factory = null;
             EventDispatcher.shutdown();
@@ -395,7 +710,7 @@
 
         // Now that the system bundle is successfully created we can give
         // its bundle context to the logger so that it can track log services.
-        m_logger.setSystemBundleContext(systembundle.getInfo().getBundleContext());
+        m_logger.setSystemBundleContext(m_systemBundleInfo.getBundleContext());
 
         // Now reload the cached bundles.
         BundleArchive[] archives = null;
@@ -413,7 +728,7 @@
             archives = null;
         }
 
-        BundleImpl bundle = null;
+        FelixBundle bundle = null;
 
         // Now install all cached bundles.
         for (int i = 0; (archives != null) && (i < archives.length); i++)
@@ -421,7 +736,7 @@
             try
             {
                 // Make sure our id generator is not going to overlap.
-                // TODO: This is not correct since it may lead to re-used
+                // TODO: FRAMEWORK - This is not correct since it may lead to re-used
                 // ids, which is not okay according to OSGi.
                 m_nextId = Math.max(m_nextId, archives[i].getId() + 1);
 
@@ -438,7 +753,7 @@
                 else
                 {
                     // Install the cached bundle.
-                    bundle = (BundleImpl) installBundle(
+                    bundle = (FelixBundle) installBundle(
                         archives[i].getId(), archives[i].getLocation(), null);
                 }
             }
@@ -462,7 +777,7 @@
                         "Unable to re-install cached bundle.",
                         ex);
                 }
-                // TODO: Perhaps we should remove the cached bundle?
+                // TODO: FRAMEWORK - Perhaps we should remove the cached bundle?
             }
         }
 
@@ -490,8 +805,7 @@
         try
         {
             StartLevel sl = (StartLevel) getService(
-                getBundle(0),
-                getServiceReferences((BundleImpl) getBundle(0), StartLevel.class.getName(), null, true)[0]);
+                getBundle(0),getServiceReferences((FelixBundle) getBundle(0), StartLevel.class.getName(), null, true)[0]);
             if (sl instanceof StartLevelImpl)
             {
                 ((StartLevelImpl) sl).setStartLevelAndWait(startLevel);
@@ -507,23 +821,33 @@
         }
 
         // The framework is now running.
-        m_frameworkStatus = RUNNING_STATUS;
-
-        // Set the system bundle state to ACTIVE.
-        systembundle.getInfo().setState(Bundle.ACTIVE);
+        m_systemBundleInfo.setState(Bundle.ACTIVE);
 
         // Fire started event for system bundle.
-        fireBundleEvent(BundleEvent.STARTED, systembundle);
+        fireBundleEvent(BundleEvent.STARTED, this);
 
         // Send a framework event to indicate the framework has started.
-        fireFrameworkEvent(FrameworkEvent.STARTED, getBundle(0), null);
+        fireFrameworkEvent(FrameworkEvent.STARTED, this, null);
     }
 
     /**
      * This method cleanly shuts down the framework, it must be called at the
      * end of a session in order to shutdown all active bundles.
     **/
-    public void shutdown()
+    public void stop() throws BundleException
+    {
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            ((SecurityManager) sm).checkPermission(new AdminPermission(this,
+                AdminPermission.EXECUTE));
+        }
+
+        stopBundle(this, true);
+    }
+
+    public void stopAndWait()
     {
         // Shut the framework down by calling stop() on the system bundle.
         // Since stop() on the system bundle will return immediately, we
@@ -531,7 +855,7 @@
         // be notified when the shutdown is complete.
         synchronized (this)
         {
-            if (m_frameworkStatus == RUNNING_STATUS)
+            if (m_systemBundleInfo.getState() == Bundle.ACTIVE)
             {
                 try
                 {
@@ -547,7 +871,7 @@
                 }
             }
 
-            while (m_frameworkStatus != INITIAL_STATUS)
+            while (m_systemBundleInfo.getState() != Bundle.UNINSTALLED)
             {
                 try
                 {
@@ -561,133 +885,33 @@
         }
     }
 
-    /**
-     * This method actually performs the real shutdown operations of the
-     * framework in terms of setting the start level to zero, really stopping
-     * the system bundle, cleaning up any bundle remains and shutting down event
-     * dispatching.
-     */
-    void shutdownInternalStart()
+    public void uninstall() throws BundleException
     {
-        synchronized (this)
-        {
-            // Change framework status from running to stopping.
-            // If framework is not running, then just return.
-            if (m_frameworkStatus != RUNNING_STATUS)
-            {
-                return;
-            }
-
-            // The framework is now in its shutdown sequence.
-            m_frameworkStatus = STOPPING_STATUS;
-        }
-
-        // Use the start level service to set the start level to zero
-        // in order to stop all bundles in the framework. Since framework
-        // shutdown happens on its own thread, we can wait for the start
-        // level service to finish before proceeding by calling the
-        // non-spec setStartLevelAndWait() method.
-        try
-        {
-            StartLevelImpl sl = (StartLevelImpl) getService(
-                getBundle(0),
-                getServiceReferences((BundleImpl) getBundle(0), StartLevel.class.getName(), null, true)[0]);
-            sl.setStartLevelAndWait(0);
-        }
-        catch (InvalidSyntaxException ex)
-        {
-            // Should never happen.
-        }
-
-        // Since they may be updated and uninstalled bundles that
-        // have not been refreshed, we will take care of refreshing
-        // them during shutdown.
-
-        // First loop through all bundled and purge old revisions
-        // from updated bundles.
-        Bundle[] bundles = getBundles();
-        for (int i = 0; i < bundles.length; i++)
-        {
-            BundleImpl bundle = (BundleImpl) bundles[i];
-            if (bundle.getInfo().getArchive().getRevisionCount() > 1)
-            {
-                try
-                {
-                    purgeBundle(bundle);
-                }
-                catch (Exception ex)
-                {
-                    fireFrameworkEvent(FrameworkEvent.ERROR, bundle, ex);
-                    m_logger.log(Logger.LOG_ERROR, "Unable to purge bundle "
-                        + bundle.getInfo().getLocation(), ex);
-                }
-            }
-        }
-
-        // Next garbage collection any uninstalled bundles.
-        for (int i = 0;
-            (m_uninstalledBundles != null) && (i < m_uninstalledBundles.length);
-            i++)
-        {
-            try
-            {
-                garbageCollectBundle(m_uninstalledBundles[i]);
-            }
-            catch (Exception ex)
-            {
-                m_logger.log(
-                    Logger.LOG_ERROR,
-                    "Unable to remove "
-                    + m_uninstalledBundles[i].getInfo().getLocation(), ex);
-            }
-        }
-
-        // Shutdown event dispatching queue.
-        EventDispatcher.shutdown();
-
-        // Remove all bundles from the module factory so that any
-        // open resources will be closed.
-        bundles = getBundles();
-        for (int i = 0; i < bundles.length; i++)
-        {
-            BundleImpl bundle = (BundleImpl) bundles[i];
-            IModule[] modules = bundle.getInfo().getModules();
-            for (int j = 0; j < modules.length; j++)
-            {
-                try
-                {
-                    m_factory.removeModule(modules[j]);
-                }
-                catch (Exception ex)
-                {
-                    m_logger.log(Logger.LOG_ERROR,
-                       "Unable to clean up " + bundle.getInfo().getLocation(), ex);
-                }
-            }
-        }
+        throw new BundleException("Cannot uninstall the system bundle.");
     }
 
-    void shutdownInternalFinish()
+    public void update() throws BundleException
     {
-        // Notify any waiters that the framework is back in its initial state.
-        synchronized (this)
-        {
-            m_frameworkStatus = INITIAL_STATUS;
-            notifyAll();
-        }
-
-        // Finally shutdown the JVM if the framework is running stand-alone.
-        String embedded = m_config.get(FelixConstants.EMBEDDED_EXECUTION_PROP);
-        boolean isEmbedded = (embedded == null) ? false : embedded.equals("true");
-        if (!isEmbedded)
-        {
-            m_secureAction.exit(0);
-        }
+        update(null);
     }
 
-    public int getStatus()
+    public void update(InputStream is) throws BundleException
     {
-        return m_frameworkStatus;
+        Object sm = System.getSecurityManager();
+
+        if (sm != null)
+        {
+            ((SecurityManager) sm).checkPermission(new AdminPermission(this,
+                AdminPermission.EXECUTE));
+        }
+
+        // TODO: FRAMEWORK - This is supposed to stop and then restart the framework.
+        throw new BundleException("System bundle update not implemented yet.");
+    }
+
+    public String toString()
+    {
+        return getSymbolicName() + " [" + getBundleId() +"]";
     }
 
     /**
@@ -760,8 +984,8 @@
                 comparator = new Comparator() {
                     public int compare(Object o1, Object o2)
                     {
-                        BundleImpl b1 = (BundleImpl) o1;
-                        BundleImpl b2 = (BundleImpl) o2;
+                        FelixBundle b1 = (FelixBundle) o1;
+                        FelixBundle b2 = (FelixBundle) o2;
                         if (b1.getInfo().getStartLevel(getInitialBundleStartLevel())
                             < b2.getInfo().getStartLevel(getInitialBundleStartLevel()))
                         {
@@ -786,8 +1010,8 @@
                 comparator = new Comparator() {
                     public int compare(Object o1, Object o2)
                     {
-                        BundleImpl b1 = (BundleImpl) o1;
-                        BundleImpl b2 = (BundleImpl) o2;
+                        FelixBundle b1 = (FelixBundle) o1;
+                        FelixBundle b2 = (FelixBundle) o2;
                         if (b1.getInfo().getStartLevel(getInitialBundleStartLevel())
                             > b2.getInfo().getStartLevel(getInitialBundleStartLevel()))
                         {
@@ -813,7 +1037,7 @@
         // Stop or start the bundles according to the start level.
         for (int i = 0; (bundles != null) && (i < bundles.length); i++)
         {
-            BundleImpl impl = (BundleImpl) bundles[i];
+            FelixBundle impl = (FelixBundle) bundles[i];
 
             // Ignore the system bundle, since its start() and
             // stop() methods get called explicitly in Felix.start()
@@ -869,7 +1093,7 @@
             }
         }
 
-        if (m_frameworkStatus == RUNNING_STATUS)
+        if (m_systemBundleInfo.getState() == Bundle.ACTIVE)
         {
             fireFrameworkEvent(FrameworkEvent.STARTLEVEL_CHANGED, getBundle(0), null);
         }
@@ -938,7 +1162,7 @@
             throw new IllegalArgumentException("Bundle is uninstalled.");
         }
 
-        return ((BundleImpl) bundle).getInfo().getStartLevel(getInitialBundleStartLevel());
+        return ((FelixBundle) bundle).getInfo().getStartLevel(getInitialBundleStartLevel());
     }
 
     /**
@@ -955,7 +1179,7 @@
     protected void setBundleStartLevel(Bundle bundle, int startLevel)
     {
         // Acquire bundle lock.
-        acquireBundleLock((BundleImpl) bundle);
+        acquireBundleLock((FelixBundle) bundle);
 
         Throwable rethrow = null;
 
@@ -968,7 +1192,7 @@
 
             if (startLevel >= 1)
             {
-                BundleImpl impl = (BundleImpl) bundle;
+                FelixBundle impl = (FelixBundle) bundle;
                 impl.getInfo().setStartLevel(startLevel);
 
                 try
@@ -1001,7 +1225,7 @@
         finally
         {
             // Always release bundle lock.
-            releaseBundleLock((BundleImpl) bundle);
+            releaseBundleLock((FelixBundle) bundle);
         }
 
         if (rethrow != null)
@@ -1026,7 +1250,7 @@
             throw new IllegalArgumentException("Bundle is uninstalled.");
         }
 
-        return (((BundleImpl) bundle).getInfo().getPersistentState() == Bundle.ACTIVE);
+        return (((FelixBundle) bundle).getInfo().getPersistentState() == Bundle.ACTIVE);
     }
 
     //
@@ -1036,7 +1260,7 @@
     /**
      * Implementation for Bundle.getSymbolicName().
     **/
-    protected String getBundleSymbolicName(BundleImpl bundle)
+    protected String getBundleSymbolicName(FelixBundle bundle)
     {
         return (String) bundle.getInfo().getCurrentHeader().get(Constants.BUNDLE_SYMBOLICNAME);
     }
@@ -1047,7 +1271,7 @@
      * @param locale
      * @return localized bundle headers dictionary.
     **/
-    protected Dictionary getBundleHeaders(BundleImpl bundle, String locale)
+    protected Dictionary getBundleHeaders(FelixBundle bundle, String locale)
     {
         return new MapToDictionary(bundle.getInfo().getCurrentLocalizedHeader(locale));
     }
@@ -1055,7 +1279,7 @@
     /**
      * Implementation for Bundle.getLocation().
     **/
-    protected String getBundleLocation(BundleImpl bundle)
+    protected String getBundleLocation(FelixBundle bundle)
     {
         return bundle.getInfo().getLocation();
     }
@@ -1063,7 +1287,7 @@
     /**
      * Implementation for Bundle.getResource().
     **/
-    protected URL getBundleResource(BundleImpl bundle, String name)
+    protected URL getBundleResource(FelixBundle bundle, String name)
     {
         if (bundle.getInfo().getState() == Bundle.UNINSTALLED)
         {
@@ -1075,7 +1299,7 @@
     /**
      * Implementation for Bundle.getResources().
     **/
-    protected Enumeration getBundleResources(BundleImpl bundle, String name)
+    protected Enumeration getBundleResources(FelixBundle bundle, String name)
     {
         if (bundle.getInfo().getState() == Bundle.UNINSTALLED)
         {
@@ -1087,7 +1311,7 @@
     /**
      * Implementation for Bundle.getEntry().
     **/
-    protected URL getBundleEntry(BundleImpl bundle, String name)
+    protected URL getBundleEntry(FelixBundle bundle, String name)
     {
         if (bundle.getInfo().getState() == Bundle.UNINSTALLED)
         {
@@ -1100,7 +1324,7 @@
     /**
      * Implementation for Bundle.getEntryPaths().
     **/
-    protected Enumeration getBundleEntryPaths(BundleImpl bundle, String path)
+    protected Enumeration getBundleEntryPaths(FelixBundle bundle, String path)
     {
         if (bundle.getInfo().getState() == Bundle.UNINSTALLED)
         {
@@ -1118,8 +1342,8 @@
     /**
      * Implementation for findEntries().
     **/
-    public Enumeration findBundleEntries(
-        BundleImpl bundle, String path, String filePattern, boolean recurse)
+    protected Enumeration findBundleEntries(
+        FelixBundle bundle, String path, String filePattern, boolean recurse)
     {
         // Try to resolve the bundle per the spec.
         resolveBundles(new Bundle[] { bundle });
@@ -1133,7 +1357,7 @@
         return (!enumeration.hasMoreElements()) ? null : enumeration;
     }
 
-    protected ServiceReference[] getBundleRegisteredServices(BundleImpl bundle)
+    protected ServiceReference[] getBundleRegisteredServices(FelixBundle bundle)
     {
         if (bundle.getInfo().getState() == Bundle.UNINSTALLED)
         {
@@ -1154,7 +1378,7 @@
         return refs;
     }
 
-    protected boolean bundleHasPermission(BundleImpl bundle, Object obj)
+    protected boolean bundleHasPermission(FelixBundle bundle, Object obj)
     {
         if (bundle.getInfo().getState() == Bundle.UNINSTALLED)
         {
@@ -1187,7 +1411,7 @@
     /**
      * Implementation for Bundle.loadClass().
     **/
-    protected Class loadBundleClass(BundleImpl bundle, String name) throws ClassNotFoundException
+    protected Class loadBundleClass(FelixBundle bundle, String name) throws ClassNotFoundException
     {
         Class clazz = bundle.getInfo().getCurrentModule().getClass(name);
         if (clazz == null)
@@ -1208,7 +1432,7 @@
     /**
      * Implementation for Bundle.start().
     **/
-    protected void startBundle(BundleImpl bundle, boolean record)
+    protected void startBundle(FelixBundle bundle, boolean record)
         throws BundleException
     {
         // CONCURRENCY NOTE:
@@ -1249,7 +1473,7 @@
         }
     }
 
-    private void _startBundle(BundleImpl bundle, boolean record)
+    private void _startBundle(FelixBundle bundle, boolean record)
         throws BundleException
     {
         // The spec doesn't say whether it is possible to start an extension
@@ -1298,7 +1522,7 @@
         try
         {
             // Set the bundle's context.
-            info.setBundleContext(new BundleContextImpl(this, bundle));
+            info.setBundleContext(new BundleContextImpl(m_logger, this, bundle));
 
             // Set the bundle's activator.
             info.setActivator(createBundleActivator(bundle.getInfo()));
@@ -1354,7 +1578,7 @@
         }
     }
 
-    protected void _resolveBundle(BundleImpl bundle)
+    protected void _resolveBundle(FelixBundle bundle)
         throws BundleException
     {
         // If a security manager is installed, then check for permission
@@ -1432,7 +1656,7 @@
         }
     }
 
-    protected void updateBundle(BundleImpl bundle, InputStream is)
+    protected void updateBundle(FelixBundle bundle, InputStream is)
         throws BundleException
     {
         // Acquire bundle lock.
@@ -1449,7 +1673,7 @@
         }
     }
 
-    protected void _updateBundle(BundleImpl bundle, InputStream is)
+    protected void _updateBundle(FelixBundle bundle, InputStream is)
         throws BundleException
     {
         // We guarantee to close the input stream, so put it in a
@@ -1509,7 +1733,7 @@
                         archive.getRevisionCount() - 1,
                         info.getCurrentHeader(),
                         createBundleProtectionDomain(archive),
-                        bundle.getInfo().isExtension() || isExtensionBundle(
+                        bundle.getInfo().isExtension() || m_extensionManager.isExtensionBundle(
                             bundle.getInfo().getCurrentHeader()));
 
                     // Add module to bundle info.
@@ -1520,14 +1744,14 @@
                     // an extension bundle then done allow it to be resolved 
                     // again as per spec.
                     if (!bundle.getInfo().isExtension() &&
-                        isExtensionBundle(bundle.getInfo().getCurrentHeader()))
+                        m_extensionManager.isExtensionBundle(bundle.getInfo().getCurrentHeader()))
                     {
-                        attachExtensionBundle(bundle);
-                        bundle.getInfo().setState(BundleImpl.RESOLVED);
+                        m_extensionManager.addExtensionBundle(this, bundle);
+                        bundle.getInfo().setState(Bundle.RESOLVED);
                     }
                     else if (bundle.getInfo().isExtension())
                     {
-                        bundle.getInfo().setState(BundleImpl.INSTALLED);
+                        bundle.getInfo().setState(Bundle.INSTALLED);
                     }
                 }
                 catch (Throwable ex)
@@ -1629,7 +1853,7 @@
         }
     }
 
-    protected void stopBundle(BundleImpl bundle, boolean record)
+    protected void stopBundle(FelixBundle bundle, boolean record)
         throws BundleException
     {
         // Acquire bundle lock.
@@ -1646,7 +1870,7 @@
         }
     }
 
-    private void _stopBundle(BundleImpl bundle, boolean record)
+    private void _stopBundle(FelixBundle bundle, boolean record)
         throws BundleException
     {
         Throwable rethrow = null;
@@ -1698,7 +1922,7 @@
                 catch (Exception ex)
                 {
                     // Problem saving activator, so ignore it.
-                    // TODO: Perhaps we should handle this some other way?
+                    // TODO: FRAMEWORK - Perhaps we should handle this some other way?
                 }
             }
         }
@@ -1754,7 +1978,7 @@
         }
     }
 
-    protected void uninstallBundle(BundleImpl bundle) throws BundleException
+    protected void uninstallBundle(FelixBundle bundle) throws BundleException
     {
         // Acquire bundle lock.
         acquireBundleLock(bundle);
@@ -1770,7 +1994,7 @@
         }
     }
 
-    private void _uninstallBundle(BundleImpl bundle) throws BundleException
+    private void _uninstallBundle(FelixBundle bundle) throws BundleException
     {
         BundleInfo info = bundle.getInfo();
         if (info.getState() == Bundle.UNINSTALLED)
@@ -1799,10 +2023,10 @@
         }
 
         // Remove the bundle from the installed map.
-        BundleImpl target = null;
+        FelixBundle target = null;
         synchronized (m_installedBundleLock_Priority2)
         {
-            target = (BundleImpl) m_installedBundleMap.remove(info.getLocation());
+            target = (FelixBundle) m_installedBundleMap.remove(info.getLocation());
         }
 
         // Finally, put the uninstalled bundle into the
@@ -1865,7 +2089,7 @@
     // Implementation of BundleContext interface methods.
     //
 
-    protected void addRequirement(BundleImpl bundle, String s) throws BundleException
+    protected void addRequirement(FelixBundle bundle, String s) throws BundleException
     {
         // TODO: EXPERIMENTAL - Experimental implicit wire concept to try
         //       to deal with code generation.
@@ -1914,7 +2138,7 @@
     private Bundle installBundle(long id, String location, InputStream is)
         throws BundleException
     {
-        BundleImpl bundle = null;
+        FelixBundle bundle = null;
 
         // Acquire an install lock.
         acquireInstallLock(location);
@@ -1922,15 +2146,15 @@
         try
         {
             // Check to see if the framework is still running;
-            if ((getStatus() == Felix.STOPPING_STATUS) ||
-                (getStatus() == Felix.INITIAL_STATUS))
+            if ((getState() == Bundle.STOPPING) ||
+                (getState() == Bundle.UNINSTALLED))
             {
                 throw new BundleException("The framework has been shutdown.");
             }
 
             // If bundle location is already installed, then
             // return it as required by the OSGi specification.
-            bundle = (BundleImpl) getBundle(location);
+            bundle = (FelixBundle) getBundle(location);
             if (bundle != null)
             {
                 return bundle;
@@ -1995,7 +2219,7 @@
             {
                 BundleArchive archive = m_cache.getArchive(id);
                 bundle = new BundleImpl(this, createBundleInfo(archive,
-                    isExtensionBundle(archive.getRevision(
+                    m_extensionManager.isExtensionBundle(archive.getRevision(
                     archive.getRevisionCount() - 1).getManifestHeader())));
 
                 verifyExecutionEnvironment(bundle);
@@ -2011,14 +2235,14 @@
                 }
                 else
                 {
-                    attachExtensionBundle(bundle);
+                    m_extensionManager.addExtensionBundle(this, bundle);
                 }
 
             }
             catch (Throwable ex)
             {
                 // If the bundle is new, then remove it from the cache.
-                // TODO: Perhaps it should be removed if it is not new too.
+                // TODO: FRAMEWORK - Perhaps it should be removed if it is not new too.
                 if (isNew)
                 {
                     try
@@ -2065,12 +2289,12 @@
             
             if (bundle.getInfo().isExtension()) 
             {
-                BundleImpl systemBundle = (BundleImpl) getBundle(0);
+                FelixBundle systemBundle = (FelixBundle) getBundle(0);
                 acquireBundleLock(systemBundle);
 
                 try
                 {
-                    ((SystemBundle) getBundle(0)).startExtensionBundle(bundle);
+                    m_extensionManager.startExtensionBundle(this, bundle);
                 }
                 finally
                 {
@@ -2104,68 +2328,6 @@
         return bundle;
     }
 
-    private boolean isExtensionBundle(Map headers)
-    {
-        R4Directive dir = ManifestParser.parseExtensionBundleHeader((String)
-            headers.get(Constants.FRAGMENT_HOST));
-
-        return (dir != null) && (Constants.EXTENSION_FRAMEWORK.equals(
-            dir.getValue()) || Constants.EXTENSION_BOOTCLASSPATH.equals(
-            dir.getValue()));
-    }
-
-    private void attachExtensionBundle(BundleImpl bundle) throws Exception
-    {
-        Object sm = System.getSecurityManager();
-        if (sm != null)
-        {
-            ((SecurityManager) sm).checkPermission(
-                new AdminPermission(bundle, AdminPermission.EXTENSIONLIFECYCLE));
-        }
-
-        ProtectionDomain pd = (ProtectionDomain)
-        bundle.getInfo().getCurrentModule().getSecurityContext();
-
-        if (pd != null)
-        {
-            if (!pd.implies(new AllPermission()))
-            {
-                throw new SecurityException("Extension Bundles must have AllPermission");
-            }
-        }
-
-        R4Directive dir = ManifestParser.parseExtensionBundleHeader((String)
-            bundle.getInfo().getCurrentHeader().get(Constants.FRAGMENT_HOST));
-
-        if (!Constants.EXTENSION_FRAMEWORK.equals(dir.getValue()))
-        {
-            throw new BundleException("Unsupported Extension Bundle type: " +
-                dir.getValue(), new UnsupportedOperationException(
-                "Unsupported Extension Bundle type!"));
-        }
-
-        BundleImpl systemBundle = (BundleImpl) getBundle(0);
-        acquireBundleLock(systemBundle);
-
-        try
-        {
-            bundle.getInfo().setExtension(true);
-
-            ((SystemBundle) getBundle(0)).addExtensionBundle(bundle);
-        }
-        catch (Exception ex)
-        {
-            bundle.getInfo().setExtension(false);
-            throw ex;
-        }
-        finally
-        {
-            releaseBundleLock(systemBundle);
-        }
-
-        bundle.getInfo().setState(Bundle.RESOLVED);
-    }
-
     /**
      * Checks the passed in bundle and checks to see if there is a required execution environment.
      * If there is, it gets the execution environment string and verifies that the framework provides it.
@@ -2173,7 +2335,7 @@
      * @throws BundleException if the bundle's required execution environment does
      *         not match the current execution environment.
     **/
-    private void verifyExecutionEnvironment(BundleImpl bundle)
+    private void verifyExecutionEnvironment(FelixBundle bundle)
         throws BundleException
     {
         String bundleEnvironment = (String)
@@ -2283,11 +2445,11 @@
     {
         synchronized (m_installedBundleLock_Priority2)
         {
-            BundleImpl bundle = null;
+            FelixBundle bundle = null;
 
             for (Iterator i = m_installedBundleMap.values().iterator(); i.hasNext(); )
             {
-                bundle = (BundleImpl) i.next();
+                bundle = (FelixBundle) i.next();
                 if (bundle.getInfo().getBundleId() == id)
                 {
                     return bundle;
@@ -2421,7 +2583,7 @@
      * @return A <code>ServiceRegistration</code> object or null.
     **/
     protected ServiceRegistration registerService(
-        BundleImpl bundle, String[] classNames, Object svcObj, Dictionary dict)
+        FelixBundle bundle, String[] classNames, Object svcObj, Dictionary dict)
     {
         if (classNames == null)
         {
@@ -2499,7 +2661,7 @@
      * @throws InvalidSyntaxException
      */
     protected ServiceReference[] getServiceReferences(
-        BundleImpl bundle, String className, String expr, boolean checkAssignable)
+        FelixBundle bundle, String className, String expr, boolean checkAssignable)
         throws InvalidSyntaxException
     {
         // Define filter if expression is not null.
@@ -2550,7 +2712,7 @@
      * @throws InvalidSyntaxException
      */
     protected ServiceReference[] getAllowedServiceReferences(
-        BundleImpl bundle, String className, String expr, boolean checkAssignable)
+        FelixBundle bundle, String className, String expr, boolean checkAssignable)
         throws InvalidSyntaxException
     {
         ServiceReference[] refs = getServiceReferences(bundle, className, expr, checkAssignable);
@@ -2649,7 +2811,7 @@
         return m_registry.ungetService(bundle, ref);
     }
 
-    protected File getDataFile(BundleImpl bundle, String s)
+    protected File getDataFile(FelixBundle bundle, String s)
     {
         // The spec says to throw an error if the bundle
         // is stopped, which I assume means not active,
@@ -2735,7 +2897,7 @@
             for (int pkgIdx = 0; pkgIdx < pkgs.length; pkgIdx++)
             {
                 // Get the bundle associated with the current exporting module.
-                BundleImpl bundle = (BundleImpl) getBundle(
+                FelixBundle bundle = (FelixBundle) getBundle(
                     Util.getBundleIdFromModuleId(exporters[pkgIdx].m_module.getId()));
 
                 // We need to find the version of the exported package, but this
@@ -2790,7 +2952,7 @@
         // exported packages.
         if (b != null)
         {
-            BundleImpl bundle = (BundleImpl) b;
+            FelixBundle bundle = (FelixBundle) b;
             getExportedPackages(bundle, list);
         }
         // Otherwise return all exported packages.
@@ -2810,7 +2972,7 @@
                         (m_uninstalledBundles != null) && (bundleIdx < m_uninstalledBundles.length);
                         bundleIdx++)
                     {
-                        BundleImpl bundle = m_uninstalledBundles[bundleIdx];
+                        FelixBundle bundle = m_uninstalledBundles[bundleIdx];
                         getExportedPackages(bundle, list);
                     }
                 }
@@ -2819,7 +2981,7 @@
                 Bundle[] bundles = getBundles();
                 for (int bundleIdx = 0; bundleIdx < bundles.length; bundleIdx++)
                 {
-                    BundleImpl bundle = (BundleImpl) bundles[bundleIdx];
+                    FelixBundle bundle = (FelixBundle) bundles[bundleIdx];
                     getExportedPackages(bundle, list);
                 }
             }
@@ -2834,7 +2996,7 @@
      * @param bundle The bundle from which to retrieve exported packages.
      * @param list The list to which the exported packages are added
     **/
-    private void getExportedPackages(BundleImpl bundle, List list)
+    private void getExportedPackages(FelixBundle bundle, List list)
     {
         // Since a bundle may have many modules associated with it,
         // one for each revision in the cache, search each module
@@ -2874,7 +3036,7 @@
         }
     }
 
-    protected Bundle[] getDependentBundles(BundleImpl exporter)
+    protected Bundle[] getDependentBundles(FelixBundle exporter)
     {
         // Get exporting bundle.
         BundleInfo exporterInfo = exporter.getInfo();
@@ -2911,7 +3073,7 @@
         List list = new ArrayList();
 
         // Get exporting bundle information.
-        BundleImpl exporter = (BundleImpl)
+        FelixBundle exporter = (FelixBundle)
             ((ExportedPackage) ep).getExportingBundle();
 
         // Search the dependents of the exporter's module revisions
@@ -2946,7 +3108,7 @@
     protected boolean resolveBundles(Bundle[] targets)
     {
         // Acquire locks for all bundles to be resolved.
-        BundleImpl[] bundles = acquireBundleResolveLocks(targets);
+        FelixBundle[] bundles = acquireBundleResolveLocks(targets);
 
         try
         {
@@ -2984,7 +3146,7 @@
     protected void refreshPackages(Bundle[] targets)
     {
         // Acquire locks for all impacted bundles.
-        BundleImpl[] bundles = acquireBundleRefreshLocks(targets);
+        FelixBundle[] bundles = acquireBundleRefreshLocks(targets);
 
         boolean restart = false;
         
@@ -3004,8 +3166,8 @@
                 Bundle[] allBundles = getBundles();
                 for (int j = 0; !restart && j < allBundles.length; j++)
                 {
-                    if (((BundleImpl) allBundles[j]).getInfo().isExtension() &&
-                        (allBundles[j].getState() == BundleImpl.INSTALLED))
+                    if (((FelixBundle) allBundles[j]).getInfo().isExtension() &&
+                        (allBundles[j].getState() == Bundle.INSTALLED))
                     {
                         restart = true;
                     }
@@ -3076,7 +3238,7 @@
         fireFrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED, getBundle(0), null);
     }
 
-    private void populateImportGraph(BundleImpl exporter, Map map)
+    private void populateImportGraph(FelixBundle exporter, Map map)
     {
         // Get all dependent bundles of this bundle.
         Bundle[] importers = getDependentBundles(exporter);
@@ -3092,7 +3254,7 @@
                 map.put(importers[impIdx], importers[impIdx]);
                 // Now recurse into each bundle to get its importers.
                 populateImportGraph(
-                    (BundleImpl) importers[impIdx], map);
+                    (FelixBundle) importers[impIdx], map);
             }
         }
     }
@@ -3140,7 +3302,7 @@
     private ProtectionDomain createBundleProtectionDomain(BundleArchive archive)
         throws Exception
     {
-//      TODO: Security - create a real ProtectionDomain for the Bundle
+// TODO: Security - create a real ProtectionDomain for the Bundle
         FakeURLStreamHandler handler = new FakeURLStreamHandler();
         URL context = new URL(null, "location:", handler);
         CodeSource codesource = new CodeSource(m_secureAction.createURL(context,
@@ -3178,10 +3340,10 @@
             Bundle[] bundles = getBundles();
             for (int i = 0; (bundles != null) && (i < bundles.length); i++)
             {
-                long id = ((BundleImpl) bundles[i]).getInfo().getBundleId();
-                String sym = (String) ((BundleImpl) bundles[i])
+                long id = ((FelixBundle) bundles[i]).getInfo().getBundleId();
+                String sym = (String) ((FelixBundle) bundles[i])
                     .getInfo().getCurrentHeader().get(Constants.BUNDLE_SYMBOLICNAME);
-                Version ver = Version.parseVersion((String) ((BundleImpl) bundles[i])
+                Version ver = Version.parseVersion((String) ((FelixBundle) bundles[i])
                     .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION));
                 if (symName.equals(sym) && bundleVersion.equals(ver) && (targetId != id))
                 {
@@ -3288,7 +3450,7 @@
         return activator;
     }
 
-    private void purgeBundle(BundleImpl bundle) throws Exception
+    private void purgeBundle(FelixBundle bundle) throws Exception
     {
         // Acquire bundle lock.
         acquireBundleLock(bundle);
@@ -3324,7 +3486,7 @@
         }
     }
 
-    private void garbageCollectBundle(BundleImpl bundle) throws Exception
+    private void garbageCollectBundle(FelixBundle bundle) throws Exception
     {
         // CONCURRENCY NOTE: There is no reason to lock this bundle,
         // because this method is only called during shutdown or a
@@ -3469,7 +3631,7 @@
                         {
                             try
                             {
-                                BundleImpl b = (BundleImpl) installBundle(location, null);
+                                FelixBundle b = (FelixBundle) installBundle(location, null);
                                 b.getInfo().setStartLevel(startLevel);
                             }
                             catch (Exception ex)
@@ -3515,7 +3677,7 @@
                         {
                             try
                             {
-                                BundleImpl b = (BundleImpl) installBundle(location, null);
+                                FelixBundle b = (FelixBundle) installBundle(location, null);
                                 b.getInfo().setStartLevel(startLevel);
                             }
                             catch (Exception ex)
@@ -3546,7 +3708,7 @@
                             // Installing twice just returns the same bundle.
                             try
                             {
-                                BundleImpl bundle = (BundleImpl) installBundle(location, null);
+                                FelixBundle bundle = (FelixBundle) installBundle(location, null);
                                 if (bundle != null)
                                 {
                                     startBundle(bundle, true);
@@ -3637,34 +3799,194 @@
     }
 
     //
-    // Configuration methods and inner classes.
+    // Miscellaneous inner classes.
     //
 
-    public PropertyResolver getConfig()
+    class SystemBundleActivator implements BundleActivator, Runnable
     {
-        return m_config;
-    }
-
-    private class ConfigImpl implements PropertyResolver
-    {
-        public String get(String key)
+        public void start(BundleContext context) throws Exception
         {
-            return (m_configMutable == null) ? null : m_configMutable.get(key);
+            // Create an activator list if necessary.
+            if (m_activatorList == null)
+            {
+                m_activatorList = new ArrayList();
+            }
+
+            // Add the bundle activator for the package admin service.
+            m_activatorList.add(new PackageAdminActivator(Felix.this));
+            // Add the bundle activator for the start level service.
+            m_activatorList.add(new StartLevelActivator(m_logger, Felix.this));
+            // Add the bundle activator for the url handler service.
+            m_activatorList.add(new URLHandlersActivator(m_config, Felix.this));
+
+            // Start all activators.
+            for (int i = 0; i < m_activatorList.size(); i++)
+            {
+                Felix.m_secureAction.startActivator(
+                    (BundleActivator) m_activatorList.get(i), context);
+            }
         }
 
-        public String[] getKeys()
+        public void stop(BundleContext context)
         {
-            return m_configMutable.getKeys();
+            // Spec says stop() on SystemBundle should return immediately and
+            // shutdown framework on another thread.
+            if (m_shutdownThread == null)
+            {
+                // Initial call of stop, so kick off shutdown.
+                m_shutdownThread = new Thread(this, "FelixShutdown");
+                m_shutdownThread.start();
+            }
         }
-    }
 
-    //
-    // Logging methods and inner classes.
-    //
+        public void run()
+        {
+            // First, start the framework shutdown, which will
+            // stop all bundles.
+            synchronized (this)
+            {
+                // Change framework state from active to stopping.
+                // If framework is not active, then just return.
+                if (m_systemBundleInfo.getState() != Bundle.STOPPING)
+                {
+                    return;
+                }
+            }
 
-    public Logger getLogger()
-    {
-        return m_logger;
+            // Use the start level service to set the start level to zero
+            // in order to stop all bundles in the framework. Since framework
+            // shutdown happens on its own thread, we can wait for the start
+            // level service to finish before proceeding by calling the
+            // non-spec setStartLevelAndWait() method.
+            try
+            {
+                StartLevelImpl sl = (StartLevelImpl) getService(
+                    Felix.this,
+                    getServiceReferences(Felix.this, StartLevel.class.getName(), null, true)[0]);
+                sl.setStartLevelAndWait(0);
+            }
+            catch (InvalidSyntaxException ex)
+            {
+                // Should never happen.
+            }
+
+            // Since there may be updated and uninstalled bundles that
+            // have not been refreshed, we will take care of refreshing
+            // them during shutdown.
+
+            // First loop through all bundled and purge old revisions
+            // from updated bundles.
+            Bundle[] bundles = getBundles();
+            for (int i = 0; i < bundles.length; i++)
+            {
+                FelixBundle bundle = (FelixBundle) bundles[i];
+                if (bundle.getInfo().getArchive().getRevisionCount() > 1)
+                {
+                    try
+                    {
+                        purgeBundle(bundle);
+                    }
+                    catch (Exception ex)
+                    {
+                        fireFrameworkEvent(FrameworkEvent.ERROR, bundle, ex);
+                        m_logger.log(Logger.LOG_ERROR, "Unable to purge bundle "
+                            + bundle.getInfo().getLocation(), ex);
+                    }
+                }
+            }
+
+            // Next garbage collection any uninstalled bundles.
+            for (int i = 0;
+                (m_uninstalledBundles != null) && (i < m_uninstalledBundles.length);
+                i++)
+            {
+                try
+                {
+                    garbageCollectBundle(m_uninstalledBundles[i]);
+                }
+                catch (Exception ex)
+                {
+                    m_logger.log(
+                        Logger.LOG_ERROR,
+                        "Unable to remove "
+                        + m_uninstalledBundles[i].getInfo().getLocation(), ex);
+                }
+            }
+
+            // Shutdown event dispatching queue.
+            EventDispatcher.shutdown();
+
+            // Remove all bundles from the module factory so that any
+            // open resources will be closed.
+            bundles = getBundles();
+            for (int i = 0; i < bundles.length; i++)
+            {
+                FelixBundle bundle = (FelixBundle) bundles[i];
+                IModule[] modules = bundle.getInfo().getModules();
+                for (int j = 0; j < modules.length; j++)
+                {
+                    try
+                    {
+                        m_factory.removeModule(modules[j]);
+                    }
+                    catch (Exception ex)
+                    {
+                        m_logger.log(Logger.LOG_ERROR,
+                           "Unable to clean up " + bundle.getInfo().getLocation(), ex);
+                    }
+                }
+            }
+
+            // Next, stop all system bundle activators.
+            if (m_activatorList != null)
+            {
+                // Stop all activators.
+                for (int i = 0; i < m_activatorList.size(); i++)
+                {
+                    try
+                    {
+                        if ((m_activatorContextMap != null) &&
+                            m_activatorContextMap.containsKey(m_activatorList.get(i)))
+                        {
+                            Felix.m_secureAction.stopActivator((BundleActivator) m_activatorList.get(i),
+                                (BundleContext) m_activatorContextMap.get(m_activatorList.get(i)));
+                        }
+                        else
+                        {
+                            Felix.m_secureAction.stopActivator((BundleActivator) m_activatorList.get(i),
+                                getInfo().getBundleContext());
+                        }
+                    }
+                    catch (Throwable throwable)
+                    {
+                        m_logger.log(
+                            Logger.LOG_WARNING,
+                            "Exception stopping a system bundle activator.",
+                            throwable);
+                    }
+                }
+            }
+
+            if (m_extensionManager != null)
+            {
+                m_extensionManager.removeExtensions(Felix.this);
+            }
+
+            // Notify any waiters that the framework is back in its initial state.
+            synchronized (this)
+            {
+                m_systemBundleInfo.setState(Bundle.UNINSTALLED);
+                notifyAll();
+            }
+
+            // Finally shutdown the JVM if the framework is running stand-alone.
+            String embedded = m_config.get(FelixConstants.EMBEDDED_EXECUTION_PROP);
+            boolean isEmbedded = (embedded == null) ? false : embedded.equals("true");
+            if (!isEmbedded)
+            {
+                m_secureAction.exit(0);
+            }
+        }
     }
 
     /**
@@ -3674,11 +3996,11 @@
     **/
     private class RefreshHelper
     {
-        private BundleImpl m_bundle = null;
+        private FelixBundle m_bundle = null;
 
         public RefreshHelper(Bundle bundle)
         {
-            m_bundle = (BundleImpl) bundle;
+            m_bundle = (FelixBundle) bundle;
         }
 
         public void stop()
@@ -3738,7 +4060,7 @@
                     BundleInfo newInfo = createBundleInfo(info.getArchive(),
                         info.isExtension());
                     newInfo.syncLock(info);
-                    m_bundle.setInfo(newInfo);
+                    ((BundleImpl) m_bundle).setInfo(newInfo);
                     fireBundleEvent(BundleEvent.UNRESOLVED, m_bundle);
                 }
                 catch (Exception ex)
@@ -3768,7 +4090,7 @@
     // Locking related methods.
     //
 
-    private void rememberUninstalledBundle(BundleImpl bundle)
+    private void rememberUninstalledBundle(FelixBundle bundle)
     {
         synchronized (m_uninstalledBundlesLock_Priority3)
         {
@@ -3785,8 +4107,8 @@
 
             if (m_uninstalledBundles != null)
             {
-                BundleImpl[] newBundles =
-                    new BundleImpl[m_uninstalledBundles.length + 1];
+                FelixBundle[] newBundles =
+                    new FelixBundle[m_uninstalledBundles.length + 1];
                 System.arraycopy(m_uninstalledBundles, 0,
                     newBundles, 0, m_uninstalledBundles.length);
                 newBundles[m_uninstalledBundles.length] = bundle;
@@ -3794,12 +4116,12 @@
             }
             else
             {
-                m_uninstalledBundles = new BundleImpl[] { bundle };
+                m_uninstalledBundles = new FelixBundle[] { bundle };
             }
         }
     }
 
-    private void forgetUninstalledBundle(BundleImpl bundle)
+    private void forgetUninstalledBundle(FelixBundle bundle)
     {
         synchronized (m_uninstalledBundlesLock_Priority3)
         {
@@ -3823,13 +4145,13 @@
                 // If this is the only bundle, then point to empty list.
                 if ((m_uninstalledBundles.length - 1) == 0)
                 {
-                    m_uninstalledBundles = new BundleImpl[0];
+                    m_uninstalledBundles = new FelixBundle[0];
                 }
                 // Otherwise, we need to do some array copying.
                 else
                 {
-                    BundleImpl[] newBundles =
-                        new BundleImpl[m_uninstalledBundles.length - 1];
+                    FelixBundle[] newBundles =
+                        new FelixBundle[m_uninstalledBundles.length - 1];
                     System.arraycopy(m_uninstalledBundles, 0, newBundles, 0, idx);
                     if (idx < newBundles.length)
                     {
@@ -3873,7 +4195,7 @@
         }
     }
 
-    protected void acquireBundleLock(BundleImpl bundle)
+    protected void acquireBundleLock(FelixBundle bundle)
     {
         synchronized (m_bundleLock)
         {
@@ -3892,7 +4214,7 @@
         }
     }
 
-    protected boolean acquireBundleLockOrFail(BundleImpl bundle)
+    protected boolean acquireBundleLockOrFail(FelixBundle bundle)
     {
         synchronized (m_bundleLock)
         {
@@ -3905,7 +4227,7 @@
         }
     }
 
-    protected void releaseBundleLock(BundleImpl bundle)
+    protected void releaseBundleLock(FelixBundle bundle)
     {
         synchronized (m_bundleLock)
         {
@@ -3914,17 +4236,17 @@
         }
     }
 
-    protected BundleImpl[] acquireBundleResolveLocks(Bundle[] targets)
+    protected FelixBundle[] acquireBundleResolveLocks(Bundle[] targets)
     {
         // Hold bundles to be locked.
-        BundleImpl[] bundles = null;
+        FelixBundle[] bundles = null;
         // Convert existing target bundle array to bundle impl array.
         if (targets != null)
         {
-            bundles = new BundleImpl[targets.length];
+            bundles = new FelixBundle[targets.length];
             for (int i = 0; i < targets.length; i++)
             {
-                bundles[i] = (BundleImpl) targets[i];
+                bundles[i] = (FelixBundle) targets[i];
             }
         }
 
@@ -3944,7 +4266,7 @@
                         Iterator iter = m_installedBundleMap.values().iterator();
                         while (iter.hasNext())
                         {
-                            BundleImpl bundle = (BundleImpl) iter.next();
+                            FelixBundle bundle = (FelixBundle) iter.next();
                             if (bundle.getInfo().getState() == Bundle.INSTALLED)
                             {
                                 list.add(bundle);
@@ -3955,7 +4277,7 @@
                     // Create an array.
                     if (list.size() > 0)
                     {
-                        bundles = (BundleImpl[]) list.toArray(new BundleImpl[list.size()]);
+                        bundles = (FelixBundle[]) list.toArray(new FelixBundle[list.size()]);
                     }
                 }
 
@@ -4002,10 +4324,10 @@
         return bundles;
     }
 
-    protected BundleImpl[] acquireBundleRefreshLocks(Bundle[] targets)
+    protected FelixBundle[] acquireBundleRefreshLocks(Bundle[] targets)
     {
         // Hold bundles to be locked.
-        BundleImpl[] bundles = null;
+        FelixBundle[] bundles = null;
 
         synchronized (m_bundleLock)
         {
@@ -4035,7 +4357,7 @@
                         Iterator iter = m_installedBundleMap.values().iterator();
                         while (iter.hasNext())
                         {
-                            BundleImpl bundle = (BundleImpl) iter.next();
+                            FelixBundle bundle = (FelixBundle) iter.next();
                             if (bundle.getInfo().getArchive().getRevisionCount() > 1)
                             {
                                 list.add(bundle);
@@ -4061,13 +4383,13 @@
                     {
                         // Add the current target bundle to the map of
                         // bundles to be refreshed.
-                        BundleImpl target = (BundleImpl) newTargets[targetIdx];
+                        FelixBundle target = (FelixBundle) newTargets[targetIdx];
                         map.put(target, target);
                         // Add all importing bundles to map.
                         populateImportGraph(target, map);
                     }
 
-                    bundles = (BundleImpl[]) map.values().toArray(new BundleImpl[map.size()]);
+                    bundles = (FelixBundle[]) map.values().toArray(new FelixBundle[map.size()]);
                 }
 
                 // Check if all corresponding bundles can be locked.
@@ -4113,7 +4435,7 @@
         return bundles;
     }
 
-    protected void releaseBundleLocks(BundleImpl[] bundles)
+    protected void releaseBundleLocks(FelixBundle[] bundles)
     {
         // Always unlock any locked bundles.
         synchronized (m_bundleLock)
@@ -4125,4 +4447,4 @@
             m_bundleLock.notifyAll();
         }
     }
-}
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/FelixBundle.java b/framework/src/main/java/org/apache/felix/framework/FelixBundle.java
new file mode 100644
index 0000000..7810548
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/FelixBundle.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework;
+
+import org.osgi.framework.Bundle;
+
+abstract class FelixBundle implements Bundle
+{
+    /* package private */ abstract BundleInfo getInfo();
+}
diff --git a/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java b/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java
index a8a251b..325533e 100644
--- a/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java
+++ b/framework/src/main/java/org/apache/felix/framework/FindEntriesEnumeration.java
@@ -22,7 +22,7 @@
 
 class FindEntriesEnumeration implements Enumeration
 {
-    private BundleImpl m_bundle = null;
+    private FelixBundle m_bundle = null;
     private Enumeration m_enumeration = null;
     private String m_path = null;
     private String[] m_filePattern = null;
@@ -30,7 +30,7 @@
     private Object m_next = null;
 
     public FindEntriesEnumeration(
-        BundleImpl bundle, String path, String filePattern, boolean recurse)
+        FelixBundle bundle, String path, String filePattern, boolean recurse)
     {
         m_bundle = bundle;
         m_path = path;
diff --git a/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java b/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java
index 94fb242..bbae4c6 100644
--- a/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java
+++ b/framework/src/main/java/org/apache/felix/framework/GetEntryPathsEnumeration.java
@@ -23,12 +23,12 @@
 
 class GetEntryPathsEnumeration implements Enumeration
 {
-    private BundleImpl m_bundle = null;
+    private FelixBundle m_bundle = null;
     private Enumeration m_enumeration = null;
     private String m_path = null;
     private Object m_next = null;
 
-    public GetEntryPathsEnumeration(BundleImpl bundle, String path)
+    public GetEntryPathsEnumeration(FelixBundle bundle, String path)
     {
         m_bundle = bundle;
         m_path = path;
diff --git a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
index 8611ecd..ea4ff3a 100644
--- a/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/PackageAdminImpl.java
@@ -96,11 +96,11 @@
         List list = new ArrayList();
         for (int i = 0; (bundles != null) && (i < bundles.length); i++)
         {
-            String sym = (String) ((BundleImpl) bundles[i])
+            String sym = (String) ((FelixBundle) bundles[i])
                 .getInfo().getCurrentHeader().get(Constants.BUNDLE_SYMBOLICNAME);
             if ((sym != null) && sym.equals(symbolicName))
             {
-                String s = (String) ((BundleImpl) bundles[i])
+                String s = (String) ((FelixBundle) bundles[i])
                     .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
                 Version v = (s == null) ? new Version("0.0.0") : new Version(s);
                 if ((vr == null) || vr.isInRange(v))
@@ -114,12 +114,12 @@
             return null;
         }
         bundles = (Bundle[]) list.toArray(new Bundle[list.size()]);
-        Arrays.sort(bundles, new Comparator() {
+        Arrays.sort(bundles,new Comparator() {
             public int compare(Object o1, Object o2)
             {
-                String s1 = (String) ((BundleImpl) o1)
+                String s1 = (String) ((FelixBundle) o1)
                     .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
-                String s2 = (String) ((BundleImpl) o2)
+                String s2 = (String) ((FelixBundle) o2)
                     .getInfo().getCurrentHeader().get(Constants.BUNDLE_VERSION);
                 Version v1 = (s1 == null) ? new Version("0.0.0") : new Version(s1);
                 Version v2 = (s2 == null) ? new Version("0.0.0") : new Version(s2);
diff --git a/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java b/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
index e171684..6ac93af 100644
--- a/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/ServiceReferenceImpl.java
@@ -122,10 +122,10 @@
             Util.getClassPackage(className);
         // Get package wiring from service requester.
         IWire requesterWire = Util.getWire(
-            ((BundleImpl) requester).getInfo().getCurrentModule(), pkgName);
+            ((FelixBundle) requester).getInfo().getCurrentModule(), pkgName);
         // Get package wiring from service provider.
         IWire providerWire = Util.getWire(
-            ((BundleImpl) m_bundle).getInfo().getCurrentModule(), pkgName);
+            ((FelixBundle) m_bundle).getInfo().getCurrentModule(), pkgName);
 
         // There are three situations that may occur here:
         //   1. The requester does not have a wire for the package.
@@ -153,13 +153,13 @@
             // If the provider is not the exporter of the requester's package,
             // then try to use the service registration to see if the requester's
             // class is accessible.
-            if (!((BundleImpl) m_bundle).getInfo().hasModule(requesterWire.getExporter()))
+            if (!((FelixBundle) m_bundle).getInfo().hasModule(requesterWire.getExporter()))
             {
                 try
                 {
                     // Load the class from the requesting bundle.
                     Class requestClass =
-                        ((BundleImpl) requester).getInfo().getCurrentModule().getClass(className);
+                        ((FelixBundle) requester).getInfo().getCurrentModule().getClass(className);
                     // Get the service registration and ask it to check
                     // if the service object is assignable to the requesting
                     // bundle's class.
diff --git a/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java b/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
index 61e8046..13e6918 100644
--- a/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
+++ b/framework/src/main/java/org/apache/felix/framework/StartLevelActivator.java
@@ -22,18 +22,20 @@
 
 class StartLevelActivator implements BundleActivator
 {
+    private Logger m_logger = null;
     private Felix m_felix = null;
     private StartLevelImpl m_startLevel = null;
     private ServiceRegistration m_reg = null;
 
-    public StartLevelActivator(Felix felix)
+    public StartLevelActivator(Logger logger, Felix felix)
     {
+        m_logger = logger;
         m_felix = felix;
     }
 
     public void start(BundleContext context) throws Exception
     {
-        m_startLevel = new StartLevelImpl(m_felix);
+        m_startLevel = new StartLevelImpl(m_logger, m_felix);
         m_reg = context.registerService(
             org.osgi.service.startlevel.StartLevel.class.getName(),
             m_startLevel, null);
diff --git a/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java b/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
index 5be90ff..34a61b3 100644
--- a/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/StartLevelImpl.java
@@ -36,13 +36,15 @@
     private static final int BUNDLE_IDX = 0;
     private static final int STARTLEVEL_IDX = 1;
 
+    private Logger m_logger = null;
     private Felix m_felix = null;
     private List m_requestList = null;
     private Bundle m_systemBundle = null;
     private Thread m_thread = null;
 
-    public StartLevelImpl(Felix felix)
+    public StartLevelImpl(Logger logger, Felix felix)
     {
+        m_logger = logger;
         m_felix = felix;
         m_requestList = new ArrayList();
         m_systemBundle = m_felix.getBundle(0);
@@ -136,7 +138,7 @@
             catch (InterruptedException ex)
             {
                 // Log it and ignore since it won't cause much of an issue.
-                m_felix.getLogger().log(
+                m_logger.log(
                     Logger.LOG_WARNING,
                     "Wait for start level change during shutdown interrupted.",
                     ex);
diff --git a/framework/src/main/java/org/apache/felix/framework/SystemBundle.java b/framework/src/main/java/org/apache/felix/framework/SystemBundle.java
deleted file mode 100644
index 57b2d25..0000000
--- a/framework/src/main/java/org/apache/felix/framework/SystemBundle.java
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.framework;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.URLStreamHandler;
-import java.util.*;
-
-import org.apache.felix.framework.cache.*;
-import org.apache.felix.framework.util.*;
-import org.apache.felix.framework.util.manifestparser.*;
-import org.apache.felix.moduleloader.*;
-import org.osgi.framework.*;
-
-class SystemBundle extends BundleImpl implements IModuleDefinition
-{
-    private static final ExtensionManager m_extensionManager;
-
-    static 
-    {
-        ExtensionManager extensionManager = new ExtensionManager();
-        try 
-        {
-            Felix.m_secureAction.addURLToURLClassLoader(Felix.m_secureAction.createURL(
-                Felix.m_secureAction.createURL(null, "felix:", extensionManager),
-                "felix://extensions/", extensionManager), 
-                SystemBundle.class.getClassLoader());
-        } 
-        catch (Exception ex) 
-        {
-            extensionManager = null;
-        }
-        m_extensionManager = extensionManager;
-    }
-    
-    private List m_activatorList = null;
-    private Map m_activatorContextMap = null;
-    private IContentLoader m_contentLoader = null;
-    private ICapability[] m_exports = null;
-    private Set m_exportNames = null;
-    private Thread m_shutdownThread = null;
-
-    protected SystemBundle(Felix felix, BundleInfo info, List activatorList)
-    {
-        super(felix, info);
-
-        // Create an activator list if necessary.
-        if (activatorList == null)
-        {
-            activatorList = new ArrayList();
-        }
-
-        // Add the bundle activator for the package admin service.
-        activatorList.add(new PackageAdminActivator(felix));
-
-        // Add the bundle activator for the start level service.
-        activatorList.add(new StartLevelActivator(felix));
-
-        // Add the bundle activator for the url handler service.
-        activatorList.add(new URLHandlersActivator(felix));
-
-        m_activatorList = activatorList;
-
-        info.setActivator(new SystemBundleActivator());
-        
-        // The system bundle exports framework packages as well as
-        // arbitrary user-defined packages from the system class path.
-        // We must construct the system bundle's export metadata.
-
-        // Get system property that specifies which class path
-        // packages should be exported by the system bundle.
-        try
-        {
-            m_exports = ManifestParser.parseExportHeader(
-                getFelix().getConfig().get(Constants.FRAMEWORK_SYSTEMPACKAGES));
-        }
-        catch (Exception ex)
-        {
-            m_exports = new ICapability[0];
-            getFelix().getLogger().log(
-                Logger.LOG_ERROR,
-                "Error parsing system bundle export statement: "
-                + getFelix().getConfig().get(Constants.FRAMEWORK_SYSTEMPACKAGES), ex);
-        }
-
-        m_contentLoader = new SystemBundleContentLoader();
-
-        // Initialize header map as a case insensitive map.
-        Map map = new StringMap(false);
-        map.put(FelixConstants.BUNDLE_VERSION,
-            getFelix().getConfig().get(FelixConstants.FELIX_VERSION_PROPERTY));
-        map.put(FelixConstants.BUNDLE_SYMBOLICNAME,
-            FelixConstants.SYSTEM_BUNDLE_SYMBOLICNAME);
-        map.put(FelixConstants.BUNDLE_NAME, "System Bundle");
-        map.put(FelixConstants.BUNDLE_DESCRIPTION,
-            "This bundle is system specific; it implements various system services.");
-        map.put(FelixConstants.EXPORT_SERVICE, "org.osgi.service.packageadmin.PackageAdmin,org.osgi.service.startlevel.StartLevel");
-
-        parseAndAddExports(map);
-
-        ((SystemBundleArchive) getInfo().getArchive()).setManifestHeader(map);
-    }
-
-    private void parseAndAddExports(Map headers)
-    {
-        StringBuffer exportSB = new StringBuffer("");
-        Set exportNames = new HashSet();
-
-        for (int i = 0; i < m_exports.length; i++)
-        {
-            if (i > 0)
-            {
-                exportSB.append(", ");
-            }
-
-            exportSB.append(((Capability) m_exports[i]).getPackageName());
-            exportSB.append("; version=\"");
-            exportSB.append(((Capability) m_exports[i]).getPackageVersion().toString());
-            exportSB.append("\"");
-
-            exportNames.add(((Capability) m_exports[i]).getPackageName());
-        }
-
-        m_exportNames = exportNames;
-
-        headers.put(FelixConstants.EXPORT_PACKAGE, exportSB.toString());
-    }
-
-    public IContentLoader getContentLoader()
-    {
-        return m_contentLoader;
-    }
-
-    public void start() throws BundleException
-    {
-        // The system bundle is only started once and it
-        // is started by the framework.
-        if (getState() == Bundle.ACTIVE)
-        {
-            return;
-        }
-
-        getInfo().setState(Bundle.STARTING);
-
-        try
-        {
-            getInfo().setBundleContext(new BundleContextImpl(getFelix(), this));
-            Felix.m_secureAction.startActivator(getInfo().getActivator(), getInfo().getBundleContext());
-        }
-        catch (Throwable throwable)
-        {
-            throw new BundleException(
-                "Unable to start system bundle.", throwable);
-        }
-
-        // Do NOT set the system bundle state to active yet, this
-        // must be done after all other bundles have been restarted.
-        // This will be done after the framework is initialized.
-    }
-
-    public void stop() throws BundleException
-    {
-        super.stop();
-    }
-
-    public void uninstall() throws BundleException
-    {
-        throw new BundleException("Cannot uninstall the system bundle.");
-    }
-
-    public void update() throws BundleException
-    {
-        update(null);
-    }
-
-    public void update(InputStream is) throws BundleException
-    {
-        Object sm = System.getSecurityManager();
-
-        if (sm != null)
-        {
-            ((SecurityManager) sm).checkPermission(new AdminPermission(this,
-                AdminPermission.EXECUTE));
-        }
-
-        // TODO: This is supposed to stop and then restart the framework.
-        throw new BundleException("System bundle update not implemented yet.");
-    }
-
-    public ICapability[] getCapabilities()
-    {
-        return m_exports;
-    }
-
-    public IRequirement[] getDynamicRequirements()
-    {
-        return null;
-    }
-
-    public R4Library[] getLibraries()
-    {
-        return null;
-    }
-
-    public IRequirement[] getRequirements()
-    {
-        return null;
-    }
-
-    void addExtensionBundle(BundleImpl bundle)
-    {
-        SystemBundleArchive systemArchive =
-            (SystemBundleArchive) getInfo().getArchive();
-
-        Map headers;
-        ICapability[] exports;
-        try
-        {
-            headers = new StringMap(systemArchive.getManifestHeader(
-                systemArchive.getRevisionCount() - 1), false);
-
-            exports = ManifestParser.parseExportHeader((String)
-                bundle.getInfo().getCurrentHeader().get(Constants.EXPORT_PACKAGE));
-        }
-        catch (Exception ex)
-        {
-            getFelix().getLogger().log(
-                Logger.LOG_ERROR,
-                "Error parsing extension bundle export statement: "
-                + bundle.getInfo().getCurrentHeader().get(Constants.EXPORT_PACKAGE), ex);
-
-            return;
-        }
-
-        if (m_extensionManager != null) 
-        {
-            m_extensionManager.addExtension(getFelix(), bundle);
-        }
-        else {
-            getFelix().getLogger().log(Logger.LOG_WARNING,
-                "Unable to add extension bundle to FrameworkClassLoader - Maybe not an URLClassLoader?");
-            throw new UnsupportedOperationException(
-                "Unable to add extension bundle to FrameworkClassLoader - Maybe not an URLClassLoader?");
-        }
-
-        ICapability[] temp = new ICapability[m_exports.length + exports.length];
-
-        System.arraycopy(m_exports, 0, temp, 0, m_exports.length);
-        System.arraycopy(exports, 0, temp, m_exports.length, exports.length);
-
-        m_exports = temp;
-
-        parseAndAddExports(headers);
-
-        systemArchive.setManifestHeader(headers);
-    }
-
-    void startExtensionBundle(BundleImpl bundle)
-    {
-        String activatorClass = (String)
-        bundle.getInfo().getCurrentHeader().get(
-            FelixConstants.FELIX_EXTENSION_ACTIVATOR);
-        
-        if (activatorClass != null)
-        {
-            try
-            {
-                BundleActivator activator = (BundleActivator)
-                    getClass().getClassLoader().loadClass(
-                        activatorClass.trim()).newInstance();
-                m_activatorList.add(activator);
-                if (m_activatorContextMap == null)
-                {
-                    m_activatorContextMap = new HashMap();
-                }
-                BundleContext context = new BundleContextImpl(getFelix(), bundle);
-                m_activatorContextMap.put(activator, context);
-                Felix.m_secureAction.startActivator(activator, context);
-            }
-            catch (Throwable ex)
-            {
-                getFelix().getLogger().log(Logger.LOG_WARNING,
-                    "Unable to start Felix Extension Activator", ex);
-            }
-        }
-    }
-
-    private class SystemBundleActivator implements BundleActivator, Runnable
-    {
-        public void start(BundleContext context) throws Exception
-        {
-            getInfo().setBundleContext(context);
-
-            // Start all activators.
-            for (int i = 0; i < m_activatorList.size(); i++)
-            {
-                Felix.m_secureAction.startActivator(
-                    (BundleActivator) m_activatorList.get(i), context);
-            }
-        }
-
-        public void stop(BundleContext context) throws Exception
-        {
-            getInfo().setBundleContext(context);
-
-            // Spec says stop() on SystemBundle should return immediately and
-            // shutdown framework on another thread.
-            if (getFelix().getStatus() == Felix.RUNNING_STATUS)
-            {
-                // Initial call of stop, so kick off shutdown.
-                m_shutdownThread = new Thread(this, "FelixShutdown");
-                m_shutdownThread.start();
-            }
-        }
-
-        public void run()
-        {
-            // First, start the framework shutdown, which will
-            // stop all bundles.
-            try
-            {
-                getFelix().shutdownInternalStart();
-            }
-            catch (Exception ex)
-            {
-                getFelix().getLogger().log(
-                    Logger.LOG_ERROR,
-                    "SystemBundle: Error while shutting down.", ex);
-            }
-
-            // Next, stop all system bundle activators.
-            if (m_activatorList != null)
-            {
-                // Stop all activators.
-                for (int i = 0; i < m_activatorList.size(); i++)
-                {
-                    try
-                    {
-                        if ((m_activatorContextMap != null) &&
-                            m_activatorContextMap.containsKey(m_activatorList.get(i)))
-                        {
-                            Felix.m_secureAction.stopActivator((BundleActivator) m_activatorList.get(i),
-                                (BundleContext) m_activatorContextMap.get(m_activatorList.get(i)));
-                        }
-                        else
-                        {
-                            Felix.m_secureAction.stopActivator((BundleActivator) m_activatorList.get(i),
-                                getInfo().getBundleContext());
-                        }
-                    }
-                    catch (Throwable throwable)
-                    {
-                        getFelix().getLogger().log(
-                            Logger.LOG_WARNING,
-                            "Exception stopping a system bundle activator.",
-                            throwable);
-                    }
-                }
-            }
-             
-            if (m_extensionManager != null)
-            {
-                m_extensionManager.removeExtensions(getFelix());
-            }
-
-            // Lastly, complete the shutdown.
-            try
-            {
-                getFelix().shutdownInternalFinish();
-            }
-            catch (Exception ex)
-            {
-                getFelix().getLogger().log(
-                    Logger.LOG_ERROR,
-                    "SystemBundle: Error while shutting down.", ex);
-            }
-        }
-    }
-
-    private class SystemBundleContentLoader implements IContentLoader
-    {
-        private ISearchPolicy m_searchPolicy = null;
-        private IURLPolicy m_urlPolicy = null;
-
-        public void open()
-        {
-            // Nothing needed here.
-        }
-
-        public void close()
-        {
-            // Nothing needed here.
-        }
-
-        public IContent getContent()
-        {
-            return null;
-        }
-
-        public ISearchPolicy getSearchPolicy()
-        {
-            return m_searchPolicy;
-        }
-
-        public void setSearchPolicy(ISearchPolicy searchPolicy)
-        {
-            m_searchPolicy = searchPolicy;
-        }
-
-        public IURLPolicy getURLPolicy()
-        {
-            return m_urlPolicy;
-        }
-
-        public void setURLPolicy(IURLPolicy urlPolicy)
-        {
-            m_urlPolicy = urlPolicy;
-        }
-
-        public Class getClass(String name)
-        {
-            if (!m_exportNames.contains(Util.getClassPackage(name)))
-            {
-                return null;
-            }
-
-            try
-            {
-                return getClass().getClassLoader().loadClass(name);
-            }
-            catch (ClassNotFoundException ex)
-            {
-                getFelix().getLogger().log(
-                    Logger.LOG_WARNING,
-                    ex.getMessage(),
-                    ex);
-            }
-            return null;
-        }
-
-        public URL getResource(String name)
-        {
-            return getClass().getClassLoader().getResource(name);
-        }
-
-        public Enumeration getResources(String name)
-        {
-           try
-           {
-               return getClass().getClassLoader().getResources(name);
-           }
-           catch (IOException ex)
-           {
-               return null;
-           }
-        }
-
-        public URL getResourceFromContent(String name)
-        {
-            // There is no content for the system bundle, so return null.
-            return null;
-        }
-
-        public boolean hasInputStream(int index, String urlPath) throws IOException
-        {
-            return (getClass().getClassLoader().getResource(urlPath) != null);
-        }
-
-        public InputStream getInputStream(int index, String urlPath) throws IOException
-        {
-            return getClass().getClassLoader().getResourceAsStream(urlPath);
-        }
-
-        public String findLibrary(String name)
-        {
-            // No native libs associated with the system bundle.
-            return null;
-        }
-    }
-
-    private static class ExtensionManager extends URLStreamHandler 
-    {
-        private final List m_extensions = new ArrayList();
-        private final Set m_names = new HashSet();
-        private final Map m_sourceToExtensions = new HashMap();
-
-        protected synchronized URLConnection openConnection(URL url) throws IOException
-        {
-            String path = url.getPath();
-
-            if (path.trim().equals("/"))
-            {
-                throw new IOException("Resource not provided by any extension!");
-            }
-
-            for (Iterator iter = m_extensions.iterator(); iter.hasNext();)
-            {
-                URL result = ((Bundle) iter.next()).getEntry(path);
-
-                if (result != null)
-                {
-                    return result.openConnection();
-                }
-            }
-
-            throw new IOException("Resource not provided by any extension!");
-        }
-        
-        synchronized void addExtension(Object source, Bundle extension)
-        {
-            List sourceExtensions = (List) m_sourceToExtensions.get(source);
-
-            if (sourceExtensions == null)
-            {
-                sourceExtensions = new ArrayList();
-                m_sourceToExtensions.put(source, sourceExtensions);
-            }
-
-            sourceExtensions.add(extension);
-
-            _add(extension.getSymbolicName(), extension);
-        }
-
-        synchronized void removeExtensions(Object source)
-        {
-            if (m_sourceToExtensions.remove(source) == null)
-            {
-                return;
-            }
-
-            m_extensions.clear();
-            m_names.clear();
-
-            for (Iterator iter = m_sourceToExtensions.values().iterator(); iter.hasNext();)
-            {
-                Bundle bundle = (Bundle) iter.next();
-                _add(bundle.getSymbolicName(), bundle);
-            }
-        }
-
-        private void _add(String name, Bundle extension)
-        {
-            if (!m_names.contains(name))
-            {
-                m_names.add(name);
-                m_extensions.add(extension);
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/SystemBundleArchive.java b/framework/src/main/java/org/apache/felix/framework/SystemBundleArchive.java
similarity index 72%
rename from framework/src/main/java/org/apache/felix/framework/cache/SystemBundleArchive.java
rename to framework/src/main/java/org/apache/felix/framework/SystemBundleArchive.java
index de060c9..402ba62 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/SystemBundleArchive.java
+++ b/framework/src/main/java/org/apache/felix/framework/SystemBundleArchive.java
@@ -16,14 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.framework.cache;
+package org.apache.felix.framework;
 
+import org.apache.felix.framework.cache.*;
 import java.io.File;
 import java.io.InputStream;
 import java.security.cert.X509Certificate;
 import java.util.Map;
 
 import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.framework.util.StringMap;
 import org.apache.felix.moduleloader.IContent;
 import org.apache.felix.moduleloader.IModule;
 import org.osgi.framework.Bundle;
@@ -38,42 +40,49 @@
 **/
 public class SystemBundleArchive extends BundleArchive
 {
-    private Map m_headerMap = null;
+    private Map m_headerMap = new StringMap(false);
     private BundleRevision m_revision = null;
 
     public SystemBundleArchive()
     {
-        m_revision = new BundleRevision() {
+        try
+        {
+            m_revision = new BundleRevision(null, null, null) {
 
-            public Map getManifestHeader() throws Exception
-            {
-                return m_headerMap;
-            }
+                public Map getManifestHeader() throws Exception
+                {
+                    return m_headerMap;
+                }
 
-            public IContent getContent() throws Exception
-            {
-                return null;
-            }
+                public IContent getContent() throws Exception
+                {
+                    return null;
+                }
 
-            public IContent[] getContentPath() throws Exception
-            {
-                return null;
-            }
+                public IContent[] getContentPath() throws Exception
+                {
+                    return null;
+                }
 
-            public String findLibrary(String libName) throws Exception
-            {
-                return null;
-            }
+                public String findLibrary(String libName) throws Exception
+                {
+                    return null;
+                }
 
-            public void dispose() throws Exception
-            {
-            }
+                public void dispose() throws Exception
+                {
+                }
 
-            protected X509Certificate[] getRevisionCertificates()
-            {
-                return null;
-            }
-        };
+                protected X509Certificate[] getRevisionCertificates()
+                {
+                    return null;
+                }
+            };
+        }
+        catch (Exception ex)
+        {
+            // This should never happen.
+        }
     }
 
     public long getId()
@@ -152,7 +161,6 @@
     }
 
     public Map getManifestHeader(int revision)
-        throws Exception
     {
         return m_headerMap;
     }
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java
index da68a5e..f801134 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersActivator.java
@@ -19,6 +19,7 @@
 package org.apache.felix.framework;
 
 import org.apache.felix.framework.util.FelixConstants;
+import org.apache.felix.framework.util.PropertyResolver;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 
@@ -33,11 +34,13 @@
 **/
 class URLHandlersActivator implements BundleActivator
 {
+    private PropertyResolver m_config = null;
     private Felix m_framework = null;
     private BundleContext m_context = null;
 
-    public URLHandlersActivator(Felix framework)
+    public URLHandlersActivator(PropertyResolver config, Felix framework)
     {
+        m_config = config;
         m_framework = framework;
     }
 
@@ -50,10 +53,10 @@
         m_context = context;
         // Only register the framework with the URL Handlers service
         // if the service is enabled.
-        boolean enable = (m_framework.getConfig().get(
+        boolean enable = (m_config.get(
                 FelixConstants.SERVICE_URLHANDLERS_PROP) == null)
                 ? true
-                : !m_framework.getConfig().get(FelixConstants.SERVICE_URLHANDLERS_PROP).equals("false");
+                : !m_config.get(FelixConstants.SERVICE_URLHANDLERS_PROP).equals("false");
         URLHandlers.registerInstance(m_framework, m_context, enable);
     }
 
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
index 4bb813a..ec5a30a 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersBundleURLConnection.java
@@ -58,7 +58,7 @@
         //     bundle://<module-id>:<bundle-classpath-index>/<resource-path>
         // Where <module-id> = <bundle-id>.<revision>
         long bundleId = Util.getBundleIdFromModuleId(url.getHost());
-        BundleImpl bundle = (BundleImpl) m_framework.getBundle(bundleId);
+        FelixBundle bundle = (FelixBundle) m_framework.getBundle(bundleId);
         if (bundle == null)
         {
             throw new IOException("No bundle associated with resource: " + url);
@@ -80,7 +80,7 @@
         //     bundle://<module-id>:<module-classpath-index>/<resource-path>
             // Where <module-id> = <bundle-id>.<revision>
             long bundleId = Util.getBundleIdFromModuleId(url.getHost());
-            BundleImpl bundle = (BundleImpl) m_framework.getBundle(bundleId);
+            FelixBundle bundle = (FelixBundle) m_framework.getBundle(bundleId);
             if (bundle == null)
             {
                 throw new IOException("No bundle associated with resource: " + url);
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
index f8c8a97..0a1d2e7 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersContentHandlerProxy.java
@@ -103,7 +103,7 @@
         {
             // Get the framework's system bundle context.
             BundleContext context =
-                ((BundleImpl) framework.getBundle(0)).getInfo().getBundleContext();
+                ((FelixBundle) framework.getBundle(0)).getInfo().getBundleContext();
             // Create a filter for the mime type.
             String filter = 
                 "(&(objectClass="
diff --git a/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java b/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
index 61b87ca..08a99ed 100644
--- a/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
+++ b/framework/src/main/java/org/apache/felix/framework/URLHandlersStreamHandlerProxy.java
@@ -203,7 +203,7 @@
         {
             // Get the framework's system bundle context.
             BundleContext context =
-                ((BundleImpl) framework.getBundle(0)).getInfo().getBundleContext();
+                ((FelixBundle) framework.getBundle(0)).getInfo().getBundleContext();
             // Create a filter for the protocol.
             String filter = 
                 "(&(objectClass="
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java b/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
index bbc08dc..bd9268f 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/BundleArchive.java
@@ -102,7 +102,7 @@
      * because it is special an is not really an archive.
      * </p>
     **/
-    BundleArchive()
+    public BundleArchive()
     {
     }
 
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java b/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
index b48a070..2b70548 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/BundleCache.java
@@ -88,7 +88,7 @@
 
     private static SecureAction m_secureAction = new SecureAction();
 
-    public BundleCache(PropertyResolver cfg, Logger logger)
+    public BundleCache(Logger logger, PropertyResolver cfg)
         throws Exception
     {
         m_cfg = cfg;
diff --git a/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java b/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
index d907dbd..3c77884 100644
--- a/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
+++ b/framework/src/main/java/org/apache/felix/framework/cache/BundleRevision.java
@@ -51,15 +51,6 @@
 
     /**
      * <p>
-     * This constructor is only used by the system bundle archive.
-     * </p>
-    **/
-    BundleRevision()
-    {
-    }
-
-    /**
-     * <p>
      * This class is abstract and cannot be created. It represents a revision
      * of a bundle, i.e., its content. A revision is associated with a particular
      * location string, which is typically in URL format. Subclasses of this
diff --git a/framework/src/main/java/org/apache/felix/framework/util/MutablePropertyResolverImpl.java b/framework/src/main/java/org/apache/felix/framework/util/MutablePropertyResolverImpl.java
index d0962e7..16f6ff1 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/MutablePropertyResolverImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/MutablePropertyResolverImpl.java
@@ -23,7 +23,7 @@
 public class MutablePropertyResolverImpl implements MutablePropertyResolver
 {
     private Map m_props = null;
-    
+
     public MutablePropertyResolverImpl(Map props)
     {
         m_props = props;
diff --git a/framework/src/main/java/org/apache/felix/framework/util/PropertyResolverImpl.java b/framework/src/main/java/org/apache/felix/framework/util/PropertyResolverImpl.java
new file mode 100644
index 0000000..416e7cc
--- /dev/null
+++ b/framework/src/main/java/org/apache/felix/framework/util/PropertyResolverImpl.java
@@ -0,0 +1,39 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.framework.util;
+
+public class PropertyResolverImpl implements PropertyResolver
+{
+    private MutablePropertyResolver m_resolver = null;
+
+    public PropertyResolverImpl(MutablePropertyResolver resolver)
+    {
+        m_resolver = resolver;
+    }
+
+    public String get(String key)
+    {
+        return (m_resolver == null) ? null : m_resolver.get(key);
+    }
+
+    public String[] getKeys()
+    {
+        return (m_resolver == null) ? null : m_resolver.getKeys();
+    }
+}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
index 745018d..34db5fc 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/SecureAction.java
@@ -676,8 +676,7 @@
                 URLClassLoader.class.getDeclaredMethod("addURL",
                 new Class[] {URL.class});
             addURL.setAccessible(true);
-            addURL.invoke(getClass().getClassLoader(), 
-                new Object[]{extension, loader});
+            addURL.invoke(loader, new Object[]{extension});
         }
     }
     
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Requirement.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Requirement.java
index 2bef0ce..2e14740 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Requirement.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Requirement.java
@@ -88,8 +88,8 @@
         return m_filter;
     }
 
-//  TODO: RB - We need to verify that the resolver code does not
-//  touch these implementation-specific methods.
+// TODO: RB - We need to verify that the resolver code does not
+// touch these implementation-specific methods.
 
     public String getPackageName()
     {
diff --git a/main/src/main/java/org/apache/felix/main/Main.java b/main/src/main/java/org/apache/felix/main/Main.java
index 04a5496..d70eacd 100644
--- a/main/src/main/java/org/apache/felix/main/Main.java
+++ b/main/src/main/java/org/apache/felix/main/Main.java
@@ -191,10 +191,11 @@
         try
         {
             // Now create an instance of the framework.
-            m_felix = new Felix();
-            m_felix.start(
-                new MutablePropertyResolverImpl(new StringMap(configProps, false)),
+            m_felix = new Felix(
+                new MutablePropertyResolverImpl(
+                    new StringMap(configProps, false)),
                 null);
+            m_felix.start();
         }
         catch (Exception ex)
         {