diff --git a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
index e095b52..fb8e1fe 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/Activator.java
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.scr.impl;
 
-
 import java.io.PrintStream;
 import java.text.MessageFormat;
 import java.util.HashMap;
@@ -44,7 +43,6 @@
 import org.osgi.service.log.LogService;
 import org.osgi.util.tracker.ServiceTracker;
 
-
 /**
  * This activator is used to cover requirement described in section 112.8.1 @@ -27,14
  * 37,202 @@ in active bundles.
@@ -63,7 +61,7 @@
 
     // this bundle's context
     private static BundleContext m_context;
-    
+
     //Either this bundle's context or the framework bundle context, depending on the globalExtender setting.
     private BundleContext m_globalContext;
 
@@ -89,8 +87,9 @@
 
     private ScrCommand m_scrCommand;
 
-    public Activator() {
-        m_configuration = new ScrConfiguration( this );
+    public Activator()
+    {
+        m_configuration = new ScrConfiguration(this);
         setSynchronous(true);
     }
 
@@ -102,79 +101,87 @@
      *      bundle.
      */
     @Override
-    public void start( BundleContext context ) throws Exception
+    public void start(BundleContext context) throws Exception
     {
         m_context = context;
         m_bundle = context.getBundle();
         // require the log service
-        m_logService = new ServiceTracker<LogService, LogService>( m_context, LOGSERVICE_CLASS, null );
+        m_logService = new ServiceTracker<LogService, LogService>(m_context,
+            LOGSERVICE_CLASS, null);
         m_logService.open();
         // get the configuration
-        m_configuration.start( m_context ); //this will call restart, which calls super.start.
+        m_configuration.start(m_context); //this will call restart, which calls super.start.
     }
 
-    public void restart( boolean globalExtender )
+    public void restart(boolean globalExtender)
     {
-    	BundleContext context = m_globalContext;
-        if ( globalExtender )
+        BundleContext context = m_globalContext;
+        if (globalExtender)
         {
-        	m_globalContext = m_context.getBundle( Constants.SYSTEM_BUNDLE_LOCATION ).getBundleContext();
+            m_globalContext = m_context.getBundle(
+                Constants.SYSTEM_BUNDLE_LOCATION).getBundleContext();
         }
         else
         {
-        	m_globalContext = m_context;
+            m_globalContext = m_context;
         }
-        if ( m_packageAdmin != null )
+        if (m_packageAdmin != null)
         {
-            log( LogService.LOG_INFO, m_bundle, "Stopping to restart with new globalExtender setting: " + globalExtender, null );
+            log(LogService.LOG_INFO, m_bundle,
+                "Stopping to restart with new globalExtender setting: " + globalExtender,
+                null);
             //this really is a restart, not the initial start
             // the initial start where m_globalContext is null should skip this as m_packageAdmin should not yet be set.
             try
             {
                 super.stop(context);
             }
-            catch ( Exception e )
+            catch (Exception e)
             {
-                log( LogService.LOG_ERROR, m_bundle, "Exception stopping during restart", e );
+                log(LogService.LOG_ERROR, m_bundle, "Exception stopping during restart",
+                    e);
             }
         }
         try
         {
-            log( LogService.LOG_INFO, m_bundle, "Starting with globalExtender setting: " + globalExtender, null );
-            super.start( m_globalContext );
+            log(LogService.LOG_INFO, m_bundle,
+                "Starting with globalExtender setting: " + globalExtender, null);
+            super.start(m_globalContext);
         }
-        catch ( Exception e )
+        catch (Exception e)
         {
-            log( LogService.LOG_ERROR, m_bundle, "Exception starting during restart", e );
+            log(LogService.LOG_ERROR, m_bundle, "Exception starting during restart", e);
         }
 
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doStart() throws Exception
+    {
 
         // prepare component registry
         m_componentBundles = new HashMap<Long, BundleComponentActivator>();
-        m_componentRegistry = new ComponentRegistry( );
+        m_componentRegistry = new ComponentRegistry();
 
-        final ServiceComponentRuntime runtime = new ServiceComponentRuntimeImpl(m_globalContext, m_componentRegistry);
-        m_runtime_reg = m_context.registerService(ServiceComponentRuntime.class,
-                runtime, null);
+        final ServiceComponentRuntime runtime = new ServiceComponentRuntimeImpl(
+            m_globalContext, m_componentRegistry);
+        m_runtime_reg = m_context.registerService(ServiceComponentRuntime.class, runtime,
+            null);
 
         // log SCR startup
-        log( LogService.LOG_INFO, m_bundle, " Version = {0}",
-            new Object[] {m_bundle.getHeaders().get( Constants.BUNDLE_VERSION )}, null );
+        log(LogService.LOG_INFO, m_bundle, " Version = {0}",
+            new Object[] { m_bundle.getHeaders().get(Constants.BUNDLE_VERSION) }, null);
 
         // create and start the component actor
         m_componentActor = new ComponentActorThread();
         Thread t = new Thread(m_componentActor, "SCR Component Actor");
-        t.setDaemon( true );
+        t.setDaemon(true);
         t.start();
 
         super.doStart();
 
         m_scrCommand = ScrCommand.register(m_context, runtime, m_configuration);
-        m_configuration.setScrCommand( m_scrCommand );
+        m_configuration.setScrCommand(m_scrCommand);
     }
 
     @Override
@@ -185,7 +192,6 @@
         m_configuration = null;
     }
 
-
     /**
      * Unregisters this instance as a bundle listener and unloads all components
      * which have been registered during the active life time of the SCR
@@ -197,38 +203,38 @@
         // stop tracking
         super.doStop();
 
-        if (m_scrCommand !=  null)
+        if (m_scrCommand != null)
         {
             m_scrCommand.unregister();
             m_scrCommand = null;
         }
-    	if (m_runtime_reg != null)
-    	{
-			m_runtime_reg.unregister();
-			m_runtime_reg = null;
-		}
-		// dispose component registry
-    	if ( m_componentRegistry != null )
-    	{
-    	    m_componentRegistry = null;
-    	}
+        if (m_runtime_reg != null)
+        {
+            m_runtime_reg.unregister();
+            m_runtime_reg = null;
+        }
+        // dispose component registry
+        if (m_componentRegistry != null)
+        {
+            m_componentRegistry = null;
+        }
 
         // terminate the actor thread
-        if ( m_componentActor != null )
+        if (m_componentActor != null)
         {
             m_componentActor.terminate();
             m_componentActor = null;
         }
 
         // close the LogService tracker now
-        if ( m_logService != null )
+        if (m_logService != null)
         {
             m_logService.close();
             m_logService = null;
         }
 
         // close the PackageAdmin tracker now
-        if ( m_packageAdmin != null )
+        if (m_packageAdmin != null)
         {
             m_packageAdmin.close();
             m_packageAdmin = null;
@@ -238,10 +244,9 @@
         m_context = null;
     }
 
-
     //---------- Component Management -----------------------------------------
 
-    private volatile boolean gogoMissing =true;
+    private volatile boolean gogoMissing = true;
 
     @Override
     protected Extension doCreateExtension(final Bundle bundle) throws Exception
@@ -254,37 +259,49 @@
                 gogoMissing = false;
             }
             catch (Throwable e)
-            {}
+            {
+            }
         }
         return new ScrExtension(bundle);
     }
 
-    protected class ScrExtension implements Extension {
+    protected class ScrExtension implements Extension
+    {
 
         private final Bundle bundle;
         private final CountDownLatch started;
 
-        public ScrExtension(Bundle bundle) {
+        public ScrExtension(Bundle bundle)
+        {
             this.bundle = bundle;
             this.started = new CountDownLatch(1);
         }
 
-        public void start() {
-            try {
-                loadComponents( ScrExtension.this.bundle );
-            } finally {
+        public void start()
+        {
+            try
+            {
+                loadComponents(ScrExtension.this.bundle);
+            }
+            finally
+            {
                 started.countDown();
             }
         }
 
-        public void destroy() {
-            try {
+        public void destroy()
+        {
+            try
+            {
                 this.started.await(m_configuration.stopTimeout(), TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {
-                log( LogService.LOG_WARNING, m_bundle, "The wait for bundle {0}/{1} being started before destruction has been interrupted.",
-                        new Object[] {bundle.getSymbolicName(), bundle.getBundleId()}, e );
             }
-            disposeComponents( this.bundle );
+            catch (InterruptedException e)
+            {
+                log(LogService.LOG_WARNING, m_bundle,
+                    "The wait for bundle {0}/{1} being started before destruction has been interrupted.",
+                    new Object[] { bundle.getSymbolicName(), bundle.getBundleId() }, e);
+            }
+            disposeComponents(this.bundle);
         }
     }
 
@@ -297,9 +314,9 @@
      * the <code>BundleContext</code> of the bundle. If the context cannot be
      * found, this method does not load components for the bundle.
      */
-    private void loadComponents( Bundle bundle )
+    private void loadComponents(Bundle bundle)
     {
-        if ( bundle.getHeaders().get( ComponentConstants.SERVICE_COMPONENT ) == null )
+        if (bundle.getHeaders().get(ComponentConstants.SERVICE_COMPONENT) == null)
         {
             // no components in the bundle, abandon
             return;
@@ -307,36 +324,43 @@
 
         // there should be components, load them with a bundle context
         BundleContext context = bundle.getBundleContext();
-        if ( context == null )
+        if (context == null)
         {
-            log( LogService.LOG_ERROR, m_bundle, "Cannot get BundleContext of bundle {0}/{1}",
-                new Object[] {bundle.getSymbolicName(), bundle.getBundleId()}, null );
+            log(LogService.LOG_ERROR, m_bundle,
+                "Cannot get BundleContext of bundle {0}/{1}",
+                new Object[] { bundle.getSymbolicName(), bundle.getBundleId() }, null);
             return;
         }
-        
+
         //Examine bundle for extender requirement; if present check if bundle is wired to us.
         BundleWiring wiring = bundle.adapt(BundleWiring.class);
-        List<BundleWire> extenderWires = wiring.getRequiredWires(ExtenderNamespace.EXTENDER_NAMESPACE);
-        try 
+        List<BundleWire> extenderWires = wiring.getRequiredWires(
+            ExtenderNamespace.EXTENDER_NAMESPACE);
+        try
         {
-            for (BundleWire wire: extenderWires) 
+            for (BundleWire wire : extenderWires)
             {
-                if (ComponentConstants.COMPONENT_CAPABILITY_NAME.equals(wire.getCapability().getAttributes().get(ExtenderNamespace.EXTENDER_NAMESPACE)))
+                if (ComponentConstants.COMPONENT_CAPABILITY_NAME.equals(
+                    wire.getCapability().getAttributes().get(
+                        ExtenderNamespace.EXTENDER_NAMESPACE)))
                 {
                     if (!m_bundle.adapt(BundleRevision.class).equals(wire.getProvider()))
                     {
-                        log( LogService.LOG_DEBUG, m_bundle, "Bundle {0}/{1} wired to a different extender: {2}",
-                            new Object[] {bundle.getSymbolicName(), bundle.getBundleId(), wire.getProvider().getSymbolicName()}, null );
+                        log(LogService.LOG_DEBUG, m_bundle,
+                            "Bundle {0}/{1} wired to a different extender: {2}",
+                            new Object[] { bundle.getSymbolicName(), bundle.getBundleId(),
+                                    wire.getProvider().getSymbolicName() },
+                            null);
                         return;
                     }
                     break;
                 }
             }
-        } 
-        catch (NoSuchMethodError e) 
+        }
+        catch (NoSuchMethodError e)
         {
-            log( LogService.LOG_DEBUG, m_bundle, "Cannot determine bundle wiring on pre R6 framework",
-                null, null );
+            log(LogService.LOG_DEBUG, m_bundle,
+                "Cannot determine bundle wiring on pre R6 framework", null, null);
         }
 
         // FELIX-1666 method is called for the LAZY_ACTIVATION event and
@@ -346,125 +370,130 @@
         // if LAZY_ACTIVATION and STARTED event are fired at the same time
         final boolean loaded;
         final Long bundleId = bundle.getBundleId();
-        synchronized ( m_componentBundles )
+        synchronized (m_componentBundles)
         {
-            if ( m_componentBundles.containsKey( bundleId ) )
+            if (m_componentBundles.containsKey(bundleId))
             {
                 loaded = true;
             }
             else
             {
-                m_componentBundles.put( bundleId, null );
+                m_componentBundles.put(bundleId, null);
                 loaded = false;
             }
         }
 
         // terminate if already loaded (or currently being loaded)
-        if ( loaded )
+        if (loaded)
         {
-            log( LogService.LOG_DEBUG, m_bundle, "Components for bundle {0}/{1} already loaded. Nothing to do.",
-                new Object[] {bundle.getSymbolicName(), bundle.getBundleId()}, null );
+            log(LogService.LOG_DEBUG, m_bundle,
+                "Components for bundle {0}/{1} already loaded. Nothing to do.",
+                new Object[] { bundle.getSymbolicName(), bundle.getBundleId() }, null);
             return;
         }
 
         try
         {
-            BundleComponentActivator ga = new BundleComponentActivator( m_componentRegistry, m_componentActor, context,
-                m_configuration );
+            BundleComponentActivator ga = new BundleComponentActivator(
+                m_componentRegistry, m_componentActor, context, m_configuration);
             ga.initialEnable();
 
             // replace bundle activator in the map
-            synchronized ( m_componentBundles )
+            synchronized (m_componentBundles)
             {
-                m_componentBundles.put( bundleId, ga );
+                m_componentBundles.put(bundleId, ga);
             }
         }
-        catch ( Exception e )
+        catch (Exception e)
         {
             // remove the bundle id from the bundles map to ensure it is
             // not marked as being loaded
-            synchronized ( m_componentBundles )
+            synchronized (m_componentBundles)
             {
-                m_componentBundles.remove( bundleId );
+                m_componentBundles.remove(bundleId);
             }
 
-            if ( e instanceof IllegalStateException && bundle.getState() != Bundle.ACTIVE )
+            if (e instanceof IllegalStateException && bundle.getState() != Bundle.ACTIVE)
             {
-                log(
-                    LogService.LOG_DEBUG,
-                    m_bundle,
+                log(LogService.LOG_DEBUG, m_bundle,
                     "Bundle {0}/{1} has been stopped while trying to activate its components. Trying again when the bundles gets started again.",
-                new Object[] {bundle.getSymbolicName(), bundle.getBundleId()},
-                    e );
+                    new Object[] { bundle.getSymbolicName(), bundle.getBundleId() }, e);
             }
             else
             {
-                log( LogService.LOG_ERROR, m_bundle, "Error while loading components of bundle {0}/{1}",
-                new Object[] {bundle.getSymbolicName(), bundle.getBundleId()}, e );
+                log(LogService.LOG_ERROR, m_bundle,
+                    "Error while loading components of bundle {0}/{1}",
+                    new Object[] { bundle.getSymbolicName(), bundle.getBundleId() }, e);
             }
         }
     }
 
-
     /**
      * Unloads components of the given bundle. If no components have been loaded
      * for the bundle, this method has no effect.
      */
-    private void disposeComponents( Bundle bundle )
+    private void disposeComponents(Bundle bundle)
     {
         final Object ga;
-        synchronized ( m_componentBundles )
+        synchronized (m_componentBundles)
         {
-            ga = m_componentBundles.remove( bundle.getBundleId() );
+            ga = m_componentBundles.remove(bundle.getBundleId());
         }
 
-        if ( ga != null )
+        if (ga != null)
         {
             try
             {
                 int reason = isStopping()
-                        ? ComponentConstants.DEACTIVATION_REASON_DISPOSED
-                        : ComponentConstants.DEACTIVATION_REASON_BUNDLE_STOPPED;
-                ( ( BundleComponentActivator ) ga ).dispose( reason );
+                    ? ComponentConstants.DEACTIVATION_REASON_DISPOSED
+                    : ComponentConstants.DEACTIVATION_REASON_BUNDLE_STOPPED;
+                ((BundleComponentActivator) ga).dispose(reason);
             }
-            catch ( Exception e )
+            catch (Exception e)
             {
-                log( LogService.LOG_ERROR, m_bundle, "Error while disposing components of bundle {0}/{1}",
-                    new Object[] {bundle.getSymbolicName(), bundle.getBundleId()}, e );
+                log(LogService.LOG_ERROR, m_bundle,
+                    "Error while disposing components of bundle {0}/{1}",
+                    new Object[] { bundle.getSymbolicName(), bundle.getBundleId() }, e);
             }
         }
     }
 
     @Override
-    protected void debug(Bundle bundle, String msg) {
-        final String message = MessageFormat.format( msg + " bundle: {0}/{1}", bundle.getSymbolicName(), bundle.getBundleId() );
-        log( LogService.LOG_DEBUG, bundle, message, null );
-    }
-
-    @Override
-    protected void warn(Bundle bundle, String msg, Throwable t) {
-        final String message = MessageFormat.format( msg + " bundle: {0}/{1}", bundle.getSymbolicName(), bundle.getBundleId() );
-        log( LogService.LOG_WARNING, bundle, message, t );
-    }
-
-    @Override
-    protected void error(String msg, Throwable t) {
-        log( LogService.LOG_DEBUG, m_bundle, msg, t );
-    }
-
-    public static void log( int level, Bundle bundle, String pattern, Object[] arguments, Throwable ex )
+    protected void debug(Bundle bundle, String msg)
     {
-        if ( isLogEnabled( level ) )
+        final String message = MessageFormat.format(msg + " bundle: {0}/{1}",
+            bundle.getSymbolicName(), bundle.getBundleId());
+        log(LogService.LOG_DEBUG, bundle, message, null);
+    }
+
+    @Override
+    protected void warn(Bundle bundle, String msg, Throwable t)
+    {
+        final String message = MessageFormat.format(msg + " bundle: {0}/{1}",
+            bundle.getSymbolicName(), bundle.getBundleId());
+        log(LogService.LOG_WARNING, bundle, message, t);
+    }
+
+    @Override
+    protected void error(String msg, Throwable t)
+    {
+        log(LogService.LOG_DEBUG, m_bundle, msg, t);
+    }
+
+    public static void log(int level, Bundle bundle, String pattern, Object[] arguments,
+        Throwable ex)
+    {
+        if (isLogEnabled(level))
         {
-            final String message = MessageFormat.format( pattern, arguments );
-            log( level, bundle, message, ex );
+            final String message = MessageFormat.format(pattern, arguments);
+            log(level, bundle, message, ex);
         }
     }
 
     /**
      * Returns <code>true</code> if logging for the given level is enabled.
      */
-    public static boolean isLogEnabled( int level )
+    public static boolean isLogEnabled(int level)
     {
         return m_configuration == null || m_configuration.getLogLevel() >= level;
     }
@@ -478,78 +507,79 @@
      * @param message The message to log
      * @param ex An optional <code>Throwable</code> whose stack trace is written,
      *      or <code>null</code> to not log a stack trace.
-     */ 
-    public static void log( int level, Bundle bundle, String message, Throwable ex )
+     */
+    public static void log(int level, Bundle bundle, String message, Throwable ex)
     {
-        if ( isLogEnabled( level ) )
+        if (isLogEnabled(level))
         {
             ServiceTracker<LogService, LogService> t = m_logService;
-            LogService logger = ( t != null ) ? t.getService() : null;
-            if ( logger == null )
+            LogService logger = (t != null) ? t.getService() : null;
+            if (logger == null)
             {
                 // output depending on level
-                PrintStream out = ( level == LogService.LOG_ERROR ) ? System.err : System.out;
+                PrintStream out = (level == LogService.LOG_ERROR) ? System.err
+                    : System.out;
 
                 // level as a string
                 StringBuffer buf = new StringBuffer();
-                switch ( level )
+                switch (level)
                 {
-                    case ( LogService.LOG_DEBUG     ):
-                        buf.append( "DEBUG: " );
+                    case (LogService.LOG_DEBUG):
+                        buf.append("DEBUG: ");
                         break;
-                    case ( LogService.LOG_INFO     ):
-                        buf.append( "INFO : " );
+                    case (LogService.LOG_INFO):
+                        buf.append("INFO : ");
                         break;
-                    case ( LogService.LOG_WARNING     ):
-                        buf.append( "WARN : " );
+                    case (LogService.LOG_WARNING):
+                        buf.append("WARN : ");
                         break;
-                    case ( LogService.LOG_ERROR     ):
-                        buf.append( "ERROR: " );
+                    case (LogService.LOG_ERROR):
+                        buf.append("ERROR: ");
                         break;
                     default:
-                        buf.append( "UNK  : " );
+                        buf.append("UNK  : ");
                         break;
                 }
 
                 // bundle information
-                if ( bundle != null )
+                if (bundle != null)
                 {
-                    buf.append( bundle.getSymbolicName() );
-                    buf.append( " (" );
-                    buf.append( bundle.getBundleId() );
-                    buf.append( "): " );
+                    buf.append(bundle.getSymbolicName());
+                    buf.append(" (");
+                    buf.append(bundle.getBundleId());
+                    buf.append("): ");
                 }
 
                 // the message
-                buf.append( message );
+                buf.append(message);
 
                 // keep the message and the stacktrace together
-                synchronized ( out)
+                synchronized (out)
                 {
-                    out.println( buf );
-                    if ( ex != null )
+                    out.println(buf);
+                    if (ex != null)
                     {
-                        ex.printStackTrace( out );
+                        ex.printStackTrace(out);
                     }
                 }
             }
             else
             {
-                logger.log( level, message, ex );
+                logger.log(level, message, ex);
             }
         }
     }
 
-
     public static Object getPackageAdmin()
     {
-        if ( m_packageAdmin == null )
+        if (m_packageAdmin == null)
         {
-            synchronized ( Activator.class )
+            synchronized (Activator.class)
             {
-                if ( m_packageAdmin == null )
+                if (m_packageAdmin == null)
                 {
-                    m_packageAdmin = new ServiceTracker( m_context, PACKAGEADMIN_CLASS, null );
+                    m_packageAdmin = new ServiceTracker(m_context, PACKAGEADMIN_CLASS,
+                        null);
                     m_packageAdmin.open();
                 }
             }
