FELIX-3659 share method objects as much as possible

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1382234 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java b/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
index 06f79da..e0d8378 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java
@@ -504,11 +504,11 @@
             // as soon as the component factory is satisfied
             if ( !activator.getConfiguration().isFactoryEnabled() )
             {
-                holder = new ComponentFactoryImpl(activator, metadata);
+                holder = new ComponentFactoryImpl(activator, metadata );
             }
             else
             {
-                holder = new ConfigurationComponentFactoryImpl(activator, metadata);
+                holder = new ConfigurationComponentFactoryImpl(activator, metadata );
             }
         }
         else
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java b/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
index 98fd2b8..42f0e3e 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/config/ImmediateComponentHolder.java
@@ -26,6 +26,8 @@
 
 import org.apache.felix.scr.Component;
 import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.helper.ComponentMethods;
+import org.apache.felix.scr.impl.helper.SimpleLogger;
 import org.apache.felix.scr.impl.manager.DelayedComponentManager;
 import org.apache.felix.scr.impl.manager.ImmediateComponentManager;
 import org.apache.felix.scr.impl.manager.ServiceFactoryComponentManager;
@@ -55,7 +57,7 @@
  * <code>service.factoryPid</code> equals the component name.</li>
  * </ul>
  */
-public class ImmediateComponentHolder implements ComponentHolder
+public class ImmediateComponentHolder implements ComponentHolder, SimpleLogger
 {
 
     /**
@@ -102,6 +104,7 @@
      * enabled. Otherwise they are not enabled immediately.
      */
     private boolean m_enabled;
+    private final ComponentMethods m_componentMethods;
 
 
     public ImmediateComponentHolder( final BundleComponentActivator activator, final ComponentMetadata metadata )
@@ -109,6 +112,7 @@
         this.m_activator = activator;
         this.m_componentMetadata = metadata;
         this.m_components = new HashMap();
+        this.m_componentMethods = new ComponentMethods();
         this.m_singleComponent = createComponentManager();
         this.m_enabled = false;
     }
@@ -123,17 +127,17 @@
         }
         else if ( m_componentMetadata.isImmediate() )
         {
-            manager = new ImmediateComponentManager( m_activator, this, m_componentMetadata );
+            manager = new ImmediateComponentManager( m_activator, this, m_componentMetadata, m_componentMethods );
         }
         else if ( m_componentMetadata.getServiceMetadata() != null )
         {
             if ( m_componentMetadata.getServiceMetadata().isServiceFactory() )
             {
-                manager = new ServiceFactoryComponentManager( m_activator, this, m_componentMetadata );
+                manager = new ServiceFactoryComponentManager( m_activator, this, m_componentMetadata, m_componentMethods );
             }
             else
             {
-                manager = new DelayedComponentManager( m_activator, this, m_componentMetadata );
+                manager = new DelayedComponentManager( m_activator, this, m_componentMetadata, m_componentMethods );
             }
         }
         else
@@ -560,7 +564,19 @@
         }
     }
 
-    private void log( int level, String message, Throwable ex )
+    public boolean isLogEnabled( int level )
+    {
+        BundleComponentActivator activator = getActivator();
+        if ( activator != null )
+        {
+            return activator.isLogEnabled( level );
+        }
+
+        // bundle activator has already been removed, so no logging
+        return false;
+    }
+
+    public void log( int level, String message, Throwable ex )
     {
         BundleComponentActivator activator = getActivator();
         if ( activator != null )
@@ -569,7 +585,7 @@
         }
     }
 
-    private void log( int level, String message, Object[] arguments, Throwable ex )
+    public void log( int level, String message, Object[] arguments, Throwable ex )
     {
         BundleComponentActivator activator = getActivator();
         if ( activator != null )
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java
index 3589468..981d258 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/ActivateMethod.java
@@ -21,7 +21,7 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import org.apache.felix.scr.impl.manager.AbstractComponentManager;
+
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.log.LogService;
 
@@ -35,10 +35,10 @@
         { COMPONENT_CONTEXT_CLASS };
 
 
-    public ActivateMethod( final AbstractComponentManager componentManager, final String methodName,
-        final boolean methodRequired, final Class componentClass )
+    public ActivateMethod( final SimpleLogger logger, final String methodName,
+        final boolean methodRequired, final Class componentClass, final boolean isDS11, final boolean isDS12Felix )
     {
-        super( componentManager, methodName, methodRequired, componentClass );
+        super( logger, methodName, methodRequired, componentClass, isDS11, isDS12Felix );
     }
 
 
@@ -185,7 +185,7 @@
             }
             catch ( SuitableMethodNotAccessibleException thrown )
             {
-                getComponentManager().log( LogService.LOG_DEBUG, "SuitableMethodNotAccessible", thrown );
+                getLogger().log( LogService.LOG_DEBUG, "SuitableMethodNotAccessible", thrown );
                 ex = thrown;
             }
         }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java
index aded056..021c902 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/BaseMethod.java
@@ -24,7 +24,7 @@
 import java.lang.reflect.Modifier;
 import java.util.Arrays;
 import java.util.Map;
-import org.apache.felix.scr.impl.manager.AbstractComponentManager;
+
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.ComponentContext;
@@ -44,31 +44,35 @@
     protected static final Class MAP_CLASS = Map.class;
     protected static final Class INTEGER_CLASS = Integer.class;
 
-    private final AbstractComponentManager m_componentManager;
+    private final SimpleLogger m_logger;
+    private final boolean isDS11;
+    private final boolean isDS12Felix;
 
     private final String m_methodName;
     private final Class m_componentClass;
 
-    private Method m_method;
+    private volatile Method m_method;
 
     private final boolean m_methodRequired;
 
-    private State m_state;
+    private volatile State m_state;
 
-    protected BaseMethod( final AbstractComponentManager componentManager, final String methodName,
-        final Class componentClass )
+    protected BaseMethod( final SimpleLogger logger, final String methodName,
+            final Class componentClass, final boolean ds11, final boolean ds12Felix )
     {
-        this( componentManager, methodName, methodName != null, componentClass );
+        this( logger, methodName, methodName != null, componentClass, ds11, ds12Felix );
     }
 
 
-    protected BaseMethod( final AbstractComponentManager componentManager, final String methodName,
-        final boolean methodRequired, final Class componentClass )
+    protected BaseMethod( final SimpleLogger logger, final String methodName,
+            final boolean methodRequired, final Class componentClass, final boolean ds11, final boolean ds12Felix )
     {
-        m_componentManager = componentManager;
+        m_logger = logger;
         m_methodName = methodName;
         m_methodRequired = methodRequired;
         m_componentClass = componentClass;
+        isDS11 = ds11;
+        isDS12Felix = ds12Felix;
         if ( m_methodName == null )
         {
             m_state = NotApplicable.INSTANCE;
@@ -80,21 +84,21 @@
     }
 
 
-    protected final AbstractComponentManager getComponentManager()
+    protected final SimpleLogger getLogger()
     {
-        return m_componentManager;
+        return m_logger;
     }
 
 
     protected final boolean isDS11()
     {
-        return getComponentManager().getComponentMetadata().isDS11();
+        return isDS11;
     }
 
 
     protected final boolean isDS12Felix()
     {
-        return getComponentManager().getComponentMetadata().isDS12Felix();
+        return isDS12Felix;
     }
 
 
@@ -121,20 +125,20 @@
         if ( method != null )
         {
             m_state = Resolved.INSTANCE;
-            getComponentManager().log( LogService.LOG_DEBUG, "Found {0} method: {1}", new Object[]
+            getLogger().log( LogService.LOG_DEBUG, "Found {0} method: {1}", new Object[]
                 { getMethodNamePrefix(), method }, null );
         }
         else if ( m_methodRequired )
         {
             m_state = NotFound.INSTANCE;
-            getComponentManager().log(LogService.LOG_ERROR, "{0} method [{1}] not found; Component will fail",
+            getLogger().log(LogService.LOG_ERROR, "{0} method [{1}] not found; Component will fail",
                 new Object[]
                     { getMethodNamePrefix(), getMethodName() }, null);
         }
         else
         {
             // optional method not found, log as DEBUG and ignore
-            getComponentManager().log( LogService.LOG_DEBUG, "{0} method [{1}] not found, ignoring", new Object[]
+            getLogger().log( LogService.LOG_DEBUG, "{0} method [{1}] not found, ignoring", new Object[]
                 { getMethodNamePrefix(), getMethodName() }, null );
             m_state = NotApplicable.INSTANCE;
         }
@@ -170,9 +174,9 @@
         for ( Class theClass = targetClass; theClass != null; )
         {
 
-            if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+            if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
             {
-                getComponentManager().log( LogService.LOG_DEBUG,
+                getLogger().log( LogService.LOG_DEBUG,
                     "Locating method " + getMethodName() + " in class " + theClass.getName(), null );
             }
 
@@ -187,7 +191,7 @@
             catch ( SuitableMethodNotAccessibleException ex )
             {
                 // log and return null
-                getComponentManager().log( LogService.LOG_ERROR,
+                getLogger().log( LogService.LOG_ERROR,
                     "findMethod: Suitable but non-accessible method {0} found in class {1}, subclass of {2}", new Object[]
                         { getMethodName(), theClass.getName(), targetClass.getName() }, null );
                 break;
@@ -232,14 +236,14 @@
             }
             else
             {
-                getComponentManager().log( LogService.LOG_WARNING, "Method {0} cannot be called on null object",
+                getLogger().log( LogService.LOG_WARNING, "Method {0} cannot be called on null object",
                     new Object[]
                         { getMethodName() }, null );
             }
         }
         catch ( IllegalStateException ise )
         {
-            getComponentManager().log( LogService.LOG_DEBUG, ise.getMessage(), null );
+            getLogger().log( LogService.LOG_DEBUG, ise.getMessage(), null );
             return null;
         }
         catch ( IllegalAccessException ex )
@@ -247,7 +251,7 @@
             // 112.3.1 If the method is not is not declared protected or
             // public, SCR must log an error message with the log service,
             // if present, and ignore the method
-            getComponentManager().log( LogService.LOG_DEBUG, "Method {0} cannot be called", new Object[]
+            getLogger().log( LogService.LOG_DEBUG, "Method {0} cannot be called", new Object[]
                 { getMethodName() }, ex );
         }
         catch ( InvocationTargetException ex )
@@ -332,10 +336,10 @@
         {
             // thrown if no method is declared with the given name and
             // parameters
-            if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+            if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
             {
                 String argList = ( parameterTypes != null ) ? Arrays.asList( parameterTypes ).toString() : "";
-                getComponentManager().log( LogService.LOG_DEBUG, "Declared Method {0}.{1}({2}) not found", new Object[]
+                getLogger().log( LogService.LOG_DEBUG, "Declared Method {0}.{1}({2}) not found", new Object[]
                     { clazz.getName(), name, argList }, null );
             }
         }
@@ -344,7 +348,7 @@
             // may be thrown if a method would be found but the signature
             // contains throws declaration for an exception which cannot
             // be loaded
-            if ( getComponentManager().isLogEnabled( LogService.LOG_WARNING ) )
+            if ( getLogger().isLogEnabled( LogService.LOG_WARNING ) )
             {
                 StringBuffer buf = new StringBuffer();
                 buf.append( "Failure loooking up method " ).append( name ).append( '(' );
@@ -357,7 +361,7 @@
                     }
                 }
                 buf.append( ") in class class " ).append( clazz.getName() ).append( ". Assuming no such method." );
-                getComponentManager().log( LogService.LOG_WARNING, buf.toString(), cdfe );
+                getLogger().log( LogService.LOG_WARNING, buf.toString(), cdfe );
             }
         }
         catch ( SuitableMethodNotAccessibleException e)
@@ -489,7 +493,7 @@
         }
         catch ( InvocationTargetException ite )
         {
-            getComponentManager().log( LogService.LOG_ERROR, "The {0} method has thrown an exception", new Object[]
+            getLogger().log( LogService.LOG_ERROR, "The {0} method has thrown an exception", new Object[]
                 { getMethodName() }, ite.getCause() );
         }
 
@@ -537,7 +541,7 @@
 
         private void resolve( final BaseMethod baseMethod )
         {
-            baseMethod.getComponentManager().log( LogService.LOG_DEBUG, "getting {0}: {1}", new Object[]
+            baseMethod.getLogger().log( LogService.LOG_DEBUG, "getting {0}: {1}", new Object[]
                     {baseMethod.getMethodNamePrefix(), baseMethod.getMethodName()}, null );
 
             // resolve the method
@@ -549,7 +553,7 @@
             catch ( InvocationTargetException ex )
             {
                 method = null;
-                baseMethod.getComponentManager().log( LogService.LOG_WARNING, "{0} cannot be found", new Object[]
+                baseMethod.getLogger().log( LogService.LOG_WARNING, "{0} cannot be found", new Object[]
                         {baseMethod.getMethodName()}, ex.getTargetException() );
             }
 
@@ -582,7 +586,7 @@
             // 112.3.1 If the method is not found , SCR must log an error
             // message with the log service, if present, and ignore the
             // method
-            baseMethod.getComponentManager().log( LogService.LOG_ERROR, "{0} method [{1}] not found", new Object[]
+            baseMethod.getLogger().log( LogService.LOG_ERROR, "{0} method [{1}] not found", new Object[]
                 { baseMethod.getMethodNamePrefix(), baseMethod.getMethodName() }, null );
             return null;
         }
@@ -602,7 +606,7 @@
         public MethodResult invoke( final BaseMethod baseMethod, final Object componentInstance, final Object rawParameter )
             throws InvocationTargetException
         {
-            baseMethod.getComponentManager().log( LogService.LOG_DEBUG, "invoking {0}: {1}", new Object[]
+            baseMethod.getLogger().log( LogService.LOG_DEBUG, "invoking {0}: {1}", new Object[]
                 { baseMethod.getMethodNamePrefix(), baseMethod.getMethodName() }, null );
             return baseMethod.invokeMethod( componentInstance, rawParameter );
         }
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java
index bcfeb18..b187014 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethod.java
@@ -21,7 +21,6 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.Map;
 
 import org.apache.felix.scr.impl.Activator;
 import org.apache.felix.scr.impl.manager.AbstractComponentManager;
@@ -49,10 +48,10 @@
     private int m_paramStyle;
 
 
-    public BindMethod( final AbstractComponentManager componentManager, final String methodName,
-            final Class componentClass, final String referenceClassName )
+    public BindMethod( final SimpleLogger logger, final String methodName,
+            final Class componentClass, final String referenceClassName, final boolean isDS11, final boolean isDS12Felix )
     {
-        super( componentManager, methodName, componentClass );
+        super( logger, methodName, componentClass, isDS11, isDS12Felix );
         m_referenceClassName = referenceClassName;
     }
 
@@ -86,9 +85,9 @@
         // flag indicating a suitable but inaccessible method has been found
         boolean suitableMethodNotAccessible = false;
 
-        if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+        if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
         {
-            getComponentManager().log( LogService.LOG_DEBUG,
+            getLogger().log( LogService.LOG_DEBUG,
                 "doFindMethod: Looking for method " + targetClass.getName() + "." + getMethodName(), null );
         }
 
@@ -99,9 +98,9 @@
             method = getServiceReferenceMethod( targetClass, acceptPrivate, acceptPackage );
             if ( method != null )
             {
-                if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+                if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
                 {
-                    getComponentManager().log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
+                    getLogger().log( LogService.LOG_DEBUG, "doFindMethod: Found Method " + method, null );
                 }
                 m_paramStyle = SERVICE_REFERENCE;
                 return method;
@@ -117,9 +116,9 @@
         if ( parameterClass != null )
         {
 
-            if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+            if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
             {
-                getComponentManager().log(
+                getLogger().log(
                     LogService.LOG_DEBUG,
                     "doFindMethod: No method taking ServiceReference found, checking method taking "
                         + parameterClass.getName(), null );
@@ -193,9 +192,9 @@
             }
 
         }
-        else if ( getComponentManager().isLogEnabled( LogService.LOG_WARNING ) )
+        else if ( getLogger().isLogEnabled( LogService.LOG_WARNING ) )
         {
-            getComponentManager().log(
+            getLogger().log(
                 LogService.LOG_WARNING,
                 "doFindMethod: Cannot check for methods taking parameter class " + m_referenceClassName + ": "
                     + targetClass.getName() + " does not see it", null );
@@ -205,7 +204,7 @@
         // the suitable methods are accessible, we have to terminate
         if ( suitableMethodNotAccessible )
         {
-            getComponentManager().log( LogService.LOG_ERROR,
+            getLogger().log( LogService.LOG_ERROR,
                 "doFindMethod: Suitable but non-accessible method found in class {0}", new Object[]
                     { targetClass.getName() }, null );
             throw new SuitableMethodNotAccessibleException();
@@ -231,9 +230,9 @@
      */
     private Class getParameterClass( final Class targetClass )
     {
-        if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+        if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
         {
-            getComponentManager().log(
+            getLogger().log(
                 LogService.LOG_DEBUG,
                 "getParameterClass: Looking for interface class " + m_referenceClassName + "through loader of "
                     + targetClass.getName(), null );
@@ -250,9 +249,9 @@
             }
 
             final Class referenceClass = loader.loadClass( m_referenceClassName );
-            if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+            if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
             {
-                getComponentManager().log( LogService.LOG_DEBUG,
+                getLogger().log( LogService.LOG_DEBUG,
                     "getParameterClass: Found class " + referenceClass.getName(), null );
             }
             return referenceClass;
@@ -263,9 +262,9 @@
             // super class so we try this class next
         }
 
-        if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+        if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
         {
-            getComponentManager().log( LogService.LOG_DEBUG,
+            getLogger().log( LogService.LOG_DEBUG,
                 "getParameterClass: Not found through component class, using PackageAdmin service", null );
         }
 
@@ -282,18 +281,18 @@
                 {
                     try
                     {
-                        if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+                        if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
                         {
-                            getComponentManager().log(
+                            getLogger().log(
                                 LogService.LOG_DEBUG,
                                 "getParameterClass: Checking Bundle " + pkg[i].getExportingBundle().getSymbolicName()
                                     + "/" + pkg[i].getExportingBundle().getBundleId(), null );
                         }
 
                         Class referenceClass = pkg[i].getExportingBundle().loadClass( m_referenceClassName );
-                        if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+                        if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
                         {
-                            getComponentManager().log( LogService.LOG_DEBUG,
+                            getLogger().log( LogService.LOG_DEBUG,
                                 "getParameterClass: Found class " + referenceClass.getName(), null );
                         }
                         return referenceClass;
@@ -304,23 +303,23 @@
                     }
                 }
             }
-            else if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+            else if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
             {
-                getComponentManager().log( LogService.LOG_DEBUG,
+                getLogger().log( LogService.LOG_DEBUG,
                     "getParameterClass: No bundles exporting package " + referenceClassPackage + " found ", null );
             }
         }
-        else if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+        else if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
         {
-            getComponentManager().log( LogService.LOG_DEBUG,
+            getLogger().log( LogService.LOG_DEBUG,
                 "getParameterClass: PackageAdmin service not available, cannot find class", null );
         }
 
         // class cannot be found, neither through the component nor from an
         // export, so we fall back to assuming Object
-        if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+        if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
         {
-            getComponentManager().log( LogService.LOG_DEBUG,
+            getLogger().log( LogService.LOG_DEBUG,
                 "getParameterClass: No class found, falling back to class Object", null );
         }
         return OBJECT_CLASS;
@@ -400,9 +399,9 @@
         Method candidateBindMethods[] = targetClass.getDeclaredMethods();
         boolean suitableNotAccessible = false;
 
-        if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+        if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
         {
-            getComponentManager().log(
+            getLogger().log(
                 LogService.LOG_DEBUG,
                 "getServiceObjectAssignableMethod: Checking " + candidateBindMethods.length
                     + " declared method in class " + targetClass.getName(), null );
@@ -412,9 +411,9 @@
         for ( int i = 0; i < candidateBindMethods.length; i++ )
         {
             Method method = candidateBindMethods[i];
-            if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+            if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
             {
-                getComponentManager().log( LogService.LOG_DEBUG, "getServiceObjectAssignableMethod: Checking " + method, null );
+                getLogger().log( LogService.LOG_DEBUG, "getServiceObjectAssignableMethod: Checking " + method, null );
             }
 
             // Get the parameters for the current method
@@ -426,9 +425,9 @@
             if ( parameters.length == 1 && method.getName().equals( getMethodName() ) )
             {
 
-                if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+                if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
                 {
-                    getComponentManager().log( LogService.LOG_DEBUG, "getServiceObjectAssignableMethod: Considering " + method, null );
+                    getLogger().log( LogService.LOG_DEBUG, "getServiceObjectAssignableMethod: Considering " + method, null );
                 }
 
                 // Get the parameter type
@@ -447,9 +446,9 @@
                     // suitable method is not accessible, flag for exception
                     suitableNotAccessible = true;
                 }
-                else if ( getComponentManager().isLogEnabled( LogService.LOG_DEBUG ) )
+                else if ( getLogger().isLogEnabled( LogService.LOG_DEBUG ) )
                 {
-                    getComponentManager().log(
+                    getLogger().log(
                         LogService.LOG_DEBUG,
                         "getServiceObjectAssignableMethod: Parameter failure: Required " + theParameter + "; actual "
                             + parameterClass.getName(), null );
@@ -563,7 +562,7 @@
                 Object service = context.getService( ref );
                 if ( service == null )
                 {
-                    getComponentManager().log(
+                    getLogger().log(
                          LogService.LOG_WARNING,
                          "Could not get service from ref " + ref, null );
                     return null;
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethods.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethods.java
new file mode 100644
index 0000000..8f547c0
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/BindMethods.java
@@ -0,0 +1,74 @@
+/*
+ * 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.scr.impl.helper;
+
+
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
+
+/**
+ * @version $Rev:$ $Date:$
+ */
+public class BindMethods
+{
+    private final BindMethod m_bind;
+    private final UpdatedMethod m_updated;
+    private final UnbindMethod m_unbind;
+
+    BindMethods( SimpleLogger logger, ReferenceMetadata m_dependencyMetadata, Class instanceClass,
+            final boolean isDS11, final boolean isDS12Felix )
+    {
+        m_bind = new BindMethod( logger,
+                m_dependencyMetadata.getBind(),
+                instanceClass,
+                m_dependencyMetadata.getInterface(),
+                isDS11, isDS12Felix
+        );
+        m_updated = new UpdatedMethod( logger,
+                m_dependencyMetadata.getUpdated(),
+                instanceClass,
+                m_dependencyMetadata.getName(),
+                m_dependencyMetadata.getInterface(),
+                isDS11, isDS12Felix
+        );
+        m_unbind = new UnbindMethod( logger,
+                m_dependencyMetadata.getUnbind(),
+                instanceClass,
+                m_dependencyMetadata.getName(),
+                m_dependencyMetadata.getInterface(),
+                isDS11, isDS12Felix
+        );
+    }
+
+    public BindMethod getBind()
+    {
+        return m_bind;
+    }
+
+    public UnbindMethod getUnbind()
+    {
+        return m_unbind;
+    }
+
+    public UpdatedMethod getUpdated()
+    {
+        return m_updated;
+    }
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentMethods.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentMethods.java
new file mode 100644
index 0000000..3759b7f
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/ComponentMethods.java
@@ -0,0 +1,86 @@
+/*
+ * 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.scr.impl.helper;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.felix.scr.impl.metadata.ComponentMetadata;
+import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
+
+
+/**
+ * @version $Rev:$ $Date:$
+ */
+public class ComponentMethods
+{
+    private ActivateMethod m_activateMethod;
+    private ModifiedMethod m_modifiedMethod;
+    private DeactivateMethod m_deactivateMethod;
+
+    private final Map bindMethodMap = new HashMap();//<String, BindMethods>
+
+    public synchronized void initComponentMethods(SimpleLogger logger, ComponentMetadata componentMetadata, Class implementationObjectClass)
+    {
+        if (m_activateMethod != null)
+        {
+            return;
+        }
+        boolean isDS11 = componentMetadata.isDS11();
+        boolean isDS12Felix = componentMetadata.isDS12Felix();
+        m_activateMethod = new ActivateMethod( logger, componentMetadata.getActivate(), componentMetadata
+                .isActivateDeclared(), implementationObjectClass, isDS11, isDS12Felix );
+        m_deactivateMethod = new DeactivateMethod( logger, componentMetadata.getDeactivate(),
+                componentMetadata.isDeactivateDeclared(), implementationObjectClass, isDS11, isDS12Felix );
+
+        m_modifiedMethod = new ModifiedMethod( logger, componentMetadata.getModified(), implementationObjectClass, isDS11, isDS12Felix );
+
+        for ( Iterator it = componentMetadata.getDependencies().iterator(); it.hasNext(); )
+        {
+            ReferenceMetadata referenceMetadata = ( ReferenceMetadata ) it.next();
+            String refName = referenceMetadata.getName();
+            BindMethods bindMethods = new BindMethods(logger, referenceMetadata, implementationObjectClass, isDS11, isDS12Felix);
+            bindMethodMap.put( refName, bindMethods );
+        }
+    }
+
+    public ActivateMethod getActivateMethod()
+    {
+        return m_activateMethod;
+    }
+
+    public DeactivateMethod getDeactivateMethod()
+    {
+        return m_deactivateMethod;
+    }
+
+    public ModifiedMethod getModifiedMethod()
+    {
+        return m_modifiedMethod;
+    }
+
+    public BindMethods getBindMethods(String refName )
+    {
+        return ( BindMethods ) bindMethodMap.get( refName );
+    }
+
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/DeactivateMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/DeactivateMethod.java
index 211454e..152aa2f 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/DeactivateMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/DeactivateMethod.java
@@ -29,10 +29,10 @@
         { COMPONENT_CONTEXT_CLASS, BUNDLE_CONTEXT_CLASS, MAP_CLASS, Integer.TYPE, INTEGER_CLASS };
 
 
-    public DeactivateMethod( final AbstractComponentManager componentManager, final String methodName,
-        final boolean methodRequired, final Class componentClass )
+    public DeactivateMethod( final SimpleLogger logger, final String methodName,
+        final boolean methodRequired, final Class componentClass, final boolean isDS11, final boolean isDS12Felix )
     {
-        super( componentManager, methodName, methodRequired, componentClass );
+        super( logger, methodName, methodRequired, componentClass, isDS11, isDS12Felix );
     }
 
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/ModifiedMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/ModifiedMethod.java
index 5812c40..c660e56c 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/ModifiedMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/ModifiedMethod.java
@@ -25,10 +25,10 @@
 public class ModifiedMethod extends ActivateMethod
 {
 
-    public ModifiedMethod( final AbstractComponentManager componentManager, final String methodName,
-        final Class componentClass )
+    public ModifiedMethod( final SimpleLogger logger, final String methodName,
+        final Class componentClass, final boolean isDS11, final boolean isDS12Felix )
     {
-        super( componentManager, methodName, methodName != null, componentClass );
+        super( logger, methodName, methodName != null, componentClass, isDS11, isDS12Felix );
     }
 
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/SimpleLogger.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/SimpleLogger.java
new file mode 100644
index 0000000..6c88952
--- /dev/null
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/SimpleLogger.java
@@ -0,0 +1,33 @@
+/*
+ * 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.scr.impl.helper;
+
+/**
+ * @version $Rev:$ $Date:$
+ */
+public interface SimpleLogger
+{
+    void log( int level, String message, Throwable ex );
+
+    void log( int level, String message, Object[] arguments, Throwable ex );
+
+    boolean isLogEnabled( int level );
+}
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/UnbindMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/UnbindMethod.java
index b0db1e4..3b9d677 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/UnbindMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/UnbindMethod.java
@@ -28,10 +28,10 @@
 public class UnbindMethod extends BindMethod
 {
 
-    public UnbindMethod( final AbstractComponentManager componentManager, final String methodName,
-        final Class componentClass, final String referenceName, final String referenceClassName )
+    public UnbindMethod( final SimpleLogger logger, final String methodName,
+        final Class componentClass, final String referenceName, final String referenceClassName, final boolean isDS11, final boolean isDS12Felix )
     {
-        super( componentManager, methodName, componentClass, referenceClassName );
+        super( logger, methodName, componentClass, referenceClassName, isDS11, isDS12Felix );
     }
 
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/helper/UpdatedMethod.java b/scr/src/main/java/org/apache/felix/scr/impl/helper/UpdatedMethod.java
index 2f68714..8d3fe91 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/helper/UpdatedMethod.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/helper/UpdatedMethod.java
@@ -28,10 +28,10 @@
 public class UpdatedMethod extends BindMethod
 {
 
-    public UpdatedMethod( final AbstractComponentManager componentManager, final String methodName,
-        final Class componentClass, final String referenceName, final String referenceClassName )
+    public UpdatedMethod( final SimpleLogger logger, final String methodName,
+        final Class componentClass, final String referenceName, final String referenceClassName, final boolean isDS11, final boolean isDS12Felix )
     {
-        super( componentManager, methodName, componentClass, referenceClassName );
+        super( logger, methodName, componentClass, referenceClassName, isDS11, isDS12Felix );
     }
 
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
index 9ad7321..e11b75c 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
@@ -39,7 +39,9 @@
 import org.apache.felix.scr.Component;
 import org.apache.felix.scr.Reference;
 import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.helper.MethodResult;
+import org.apache.felix.scr.impl.helper.SimpleLogger;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.apache.felix.scr.impl.metadata.ServiceMetadata;
@@ -58,7 +60,7 @@
  * implementation object's lifecycle.
  *
  */
-public abstract class AbstractComponentManager implements Component
+public abstract class AbstractComponentManager implements Component, SimpleLogger
 {
 
     private static final boolean JUC_AVAILABLE;
@@ -88,6 +90,8 @@
     // The metadata
     private final ComponentMetadata m_componentMetadata;
 
+    private final ComponentMethods m_componentMethods;
+
     // The dependency managers that manage every dependency
     private final List m_dependencyManagers;
 
@@ -115,11 +119,13 @@
      *
      * @param activator
      * @param metadata
+     * @param componentMethods
      */
-    protected AbstractComponentManager( BundleComponentActivator activator, ComponentMetadata metadata )
+    protected AbstractComponentManager( BundleComponentActivator activator, ComponentMetadata metadata, ComponentMethods componentMethods )
     {
         m_activator = activator;
         m_componentMetadata = metadata;
+        this.m_componentMethods = componentMethods;
         m_componentId = -1;
 
         m_state = Disabled.getInstance();
@@ -690,6 +696,10 @@
 
     abstract State getActiveState();
 
+    ComponentMethods getComponentMethods()
+    {
+        return m_componentMethods;
+    }
     /**
      * Registers the service on behalf of the component.
      *
@@ -777,11 +787,13 @@
             log( LogService.LOG_ERROR, "Could not load implementation object class", e );
             return false;
         }
+        m_componentMethods.initComponentMethods( this, m_componentMetadata, implementationObjectClass );
+
         for (Iterator it = m_dependencyManagers.iterator(); it.hasNext(); )
         {
             DependencyManager dependencyManager = ( DependencyManager ) it.next();
 
-            dependencyManager.initBindingMethods( implementationObjectClass );
+            dependencyManager.initBindingMethods( m_componentMethods.getBindMethods( dependencyManager.getName() ) );
         }
         m_dependencyManagersInitialized = true;
         return true;
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
index f9c24d7..b4ee9ce 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
@@ -31,6 +31,7 @@
 import org.apache.felix.scr.Component;
 import org.apache.felix.scr.impl.BundleComponentActivator;
 import org.apache.felix.scr.impl.config.ComponentHolder;
+import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.osgi.framework.Constants;
@@ -82,7 +83,7 @@
 
     public ComponentFactoryImpl( BundleComponentActivator activator, ComponentMetadata metadata )
     {
-        super( activator, metadata );
+        super( activator, metadata, new ComponentMethods() );
         m_componentInstances = new IdentityHashMap();
         m_configuration = new Hashtable();
     }
@@ -410,7 +411,7 @@
      */
     private ImmediateComponentManager createComponentManager()
     {
-        return new ComponentFactoryNewInstance( getActivator(), this, getComponentMetadata() );
+        return new ComponentFactoryNewInstance( getActivator(), this, getComponentMetadata(), getComponentMethods() );
     }
 
 
@@ -428,9 +429,9 @@
     static class ComponentFactoryNewInstance extends ImmediateComponentManager {
 
         public ComponentFactoryNewInstance( BundleComponentActivator activator, ComponentHolder componentHolder,
-            ComponentMetadata metadata )
+                ComponentMetadata metadata, ComponentMethods componentMethods )
         {
-            super( activator, componentHolder, metadata );
+            super( activator, componentHolder, metadata, componentMethods );
         }
 
         State getActiveState()
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
index 60d5f8d..5f9125e 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ConfigurationComponentFactoryImpl.java
@@ -28,6 +28,7 @@
 import org.apache.felix.scr.Component;
 import org.apache.felix.scr.impl.BundleComponentActivator;
 import org.apache.felix.scr.impl.config.ComponentHolder;
+import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.osgi.service.log.LogService;
 
@@ -247,15 +248,15 @@
      */
     private ImmediateComponentManager createConfigurationComponentManager()
     {
-        return new ComponentFactoryConfiguredInstance( getActivator(), this, getComponentMetadata() );
+        return new ComponentFactoryConfiguredInstance( getActivator(), this, getComponentMetadata(), getComponentMethods() );
     }
 
     static class ComponentFactoryConfiguredInstance extends ImmediateComponentManager {
 
         public ComponentFactoryConfiguredInstance( BundleComponentActivator activator, ComponentHolder componentHolder,
-            ComponentMetadata metadata )
+                ComponentMetadata metadata, ComponentMethods componentMethods )
         {
-            super( activator, componentHolder, metadata );
+            super( activator, componentHolder, metadata, componentMethods );
         }
 
         public boolean isImmediate()
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java
index 1c94b8e..46aa448 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DelayedComponentManager.java
@@ -21,9 +21,8 @@
 
 import org.apache.felix.scr.impl.BundleComponentActivator;
 import org.apache.felix.scr.impl.config.ComponentHolder;
+import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceRegistration;
 
 
 /**
@@ -35,11 +34,12 @@
     /**
      * @param activator
      * @param metadata
+     * @param componentMethods
      */
     public DelayedComponentManager( BundleComponentActivator activator, ComponentHolder componentHolder,
-        ComponentMetadata metadata )
+            ComponentMetadata metadata, ComponentMethods componentMethods )
     {
-        super( activator, componentHolder, metadata );
+        super( activator, componentHolder, metadata, componentMethods );
     }
 
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
index 6c5e195..ce0326d 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
@@ -30,10 +30,8 @@
 import org.apache.felix.scr.Component;
 import org.apache.felix.scr.Reference;
 import org.apache.felix.scr.impl.BundleComponentActivator;
-import org.apache.felix.scr.impl.helper.BindMethod;
+import org.apache.felix.scr.impl.helper.BindMethods;
 import org.apache.felix.scr.impl.helper.MethodResult;
-import org.apache.felix.scr.impl.helper.UnbindMethod;
-import org.apache.felix.scr.impl.helper.UpdatedMethod;
 import org.apache.felix.scr.impl.metadata.ReferenceMetadata;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
@@ -67,14 +65,7 @@
     // the number of matching services registered in the system
     private volatile int m_size;
 
-    // the bind method
-    private volatile BindMethod m_bind;
-
-    // the updated method
-    private volatile UpdatedMethod m_updated;
-
-    // the unbind method
-    private volatile UnbindMethod m_unbind;
+    private BindMethods m_bindMethods;
 
     // the target service filter string
     private volatile String m_target;
@@ -109,29 +100,9 @@
     /**
      * Initialize binding methods.
      */
-    void initBindingMethods(Class instanceClass)
+    void initBindingMethods(BindMethods bindMethods)
     {
-        if (m_bind != null)
-        {
-            return;
-        }
-        m_bind = new BindMethod( m_componentManager,
-                                 m_dependencyMetadata.getBind(),
-                                 instanceClass,
-                m_dependencyMetadata.getInterface()
-        );
-        m_updated = new UpdatedMethod( m_componentManager,
-                m_dependencyMetadata.getUpdated(),
-                instanceClass,
-                m_dependencyMetadata.getName(),
-                m_dependencyMetadata.getInterface()
-        );
-        m_unbind = new UnbindMethod( m_componentManager,
-            m_dependencyMetadata.getUnbind(),
-            instanceClass,
-            m_dependencyMetadata.getName(),
-            m_dependencyMetadata.getInterface()
-        );
+       m_bindMethods = bindMethods;
     }
 
 
@@ -1029,7 +1000,7 @@
             {
                 for ( int index = 0; index < refs.length; index++ )
                 {
-                    AbstractComponentManager.RefPair refPair = m_bind.getServiceObject( refs[index], m_componentManager.getActivator().getBundleContext() );
+                    AbstractComponentManager.RefPair refPair = m_bindMethods.getBind().getServiceObject( refs[index], m_componentManager.getActivator().getBundleContext() );
                     // success is if we have the minimal required number of services bound
                     if ( refPair != null )
                     {
@@ -1046,7 +1017,7 @@
             ServiceReference ref = getFrameworkServiceReference();
             if ( ref != null )
             {
-                AbstractComponentManager.RefPair refPair = m_bind.getServiceObject( ref, m_componentManager.getActivator().getBundleContext() );
+                AbstractComponentManager.RefPair refPair = m_bindMethods.getBind().getServiceObject( ref, m_componentManager.getActivator().getBundleContext() );
                 // success is if we have the minimal required number of services bound
                 if ( refPair != null )
                 {
@@ -1173,7 +1144,7 @@
             Map dependencyMap = m_componentManager.getDependencyMap();
             if ( dependencyMap != null )
             {
-                if (m_bind == null)
+                if (m_bindMethods == null)
                 {
                     m_componentManager.log( LogService.LOG_ERROR,
                         "For dependency {0}, bind method not set: component state {1}",
@@ -1183,7 +1154,7 @@
                 }
                 Map deps = ( Map ) dependencyMap.get( this );
                 BundleContext bundleContext = m_componentManager.getActivator().getBundleContext();
-                AbstractComponentManager.RefPair refPair = m_bind.getServiceObject( ref, bundleContext );
+                AbstractComponentManager.RefPair refPair = m_bindMethods.getBind().getServiceObject( ref, bundleContext );
                 deps.put( ref, refPair );
                 return invokeBindMethod( componentInstance, refPair );
             }
@@ -1222,9 +1193,9 @@
         // null. This is valid for both immediate and delayed components
         if( componentInstance != null )
         {
-            if ( m_bind != null )
+            if ( m_bindMethods != null )
             {
-                MethodResult result = m_bind.invoke( componentInstance, refPair, MethodResult.VOID );
+                MethodResult result = m_bindMethods.getBind().invoke( componentInstance, refPair, MethodResult.VOID );
                 if ( result == null )
                 {
                     return false;
@@ -1264,7 +1235,7 @@
         if ( componentInstance != null )
         {
             AbstractComponentManager.RefPair refPair = ( AbstractComponentManager.RefPair ) ((Map )m_componentManager.getDependencyMap().get( this )).get( ref );
-            MethodResult methodResult = m_updated.invoke( componentInstance, refPair, MethodResult.VOID );
+            MethodResult methodResult = m_bindMethods.getUpdated().invoke( componentInstance, refPair, MethodResult.VOID );
             if ( methodResult != null)
             {
                 m_componentManager.setServiceProperties( methodResult );
@@ -1298,7 +1269,7 @@
         if ( componentInstance != null )
         {
             AbstractComponentManager.RefPair refPair = ( AbstractComponentManager.RefPair ) ((Map )m_componentManager.getDependencyMap().get( this )).get( ref );
-            MethodResult methodResult = m_unbind.invoke( componentInstance, refPair, MethodResult.VOID );
+            MethodResult methodResult = m_bindMethods.getUnbind().invoke( componentInstance, refPair, MethodResult.VOID );
             if ( methodResult != null )
             {
                 m_componentManager.setServiceProperties( methodResult );
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
index cab784d..9e180a7 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
@@ -29,6 +29,7 @@
 import org.apache.felix.scr.impl.config.ComponentHolder;
 import org.apache.felix.scr.impl.helper.ActivateMethod;
 import org.apache.felix.scr.impl.helper.ActivateMethod.ActivatorParameter;
+import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.helper.DeactivateMethod;
 import org.apache.felix.scr.impl.helper.MethodResult;
 import org.apache.felix.scr.impl.helper.ModifiedMethod;
@@ -63,15 +64,6 @@
     // the component holder responsible for managing this component
     private ComponentHolder m_componentHolder;
 
-    // the activate method
-    private ActivateMethod m_activateMethod;
-
-    // the deactivate method
-    private DeactivateMethod m_deactivateMethod;
-
-    // the modify method
-    private ModifiedMethod m_modifyMethod;
-
     // optional properties provided in the ComponentFactory.newInstance method
     private Dictionary m_factoryProperties;
 
@@ -92,11 +84,12 @@
      *
      * @param activator
      * @param metadata
+     * @param componentMethods
      */
     public ImmediateComponentManager( BundleComponentActivator activator, ComponentHolder componentHolder,
-            ComponentMetadata metadata )
+            ComponentMetadata metadata, ComponentMethods componentMethods )
     {
-        super( activator, metadata );
+        super( activator, metadata, componentMethods );
 
         m_componentHolder = componentHolder;
     }
@@ -233,15 +226,8 @@
             }
         }
 
-        // get the method
-        if ( m_activateMethod == null )
-        {
-            m_activateMethod = new ActivateMethod( this, getComponentMetadata().getActivate(), getComponentMetadata()
-                    .isActivateDeclared(), implementationObjectClass );
-        }
-
         // 4. Call the activate method, if present
-        final MethodResult result = m_activateMethod.invoke( implementationObject, new ActivatorParameter(
+        final MethodResult result = getComponentMethods().getActivateMethod().invoke( implementationObject, new ActivatorParameter(
                 componentContext, 1 ), null );
         if ( result == null )
         {
@@ -269,18 +255,11 @@
             int reason )
     {
 
-        // get the method
-        if ( m_deactivateMethod == null )
-        {
-            m_deactivateMethod = new DeactivateMethod( this, getComponentMetadata().getDeactivate(),
-                    getComponentMetadata().isDeactivateDeclared(), implementationObject.getClass() );
-        }
-
         // 1. Call the deactivate method, if present
         // don't care for the result, the error (acccording to 112.5.12 If the deactivate
         // method throws an exception, SCR must log an error message containing the
         // exception with the Log Service and continue) has already been logged
-        final MethodResult result = m_deactivateMethod.invoke( implementationObject, new ActivatorParameter( componentContext,
+        final MethodResult result = getComponentMethods().getDeactivateMethod().invoke( implementationObject, new ActivatorParameter( componentContext,
                 reason ), null );
         if ( result != null )
         {
@@ -538,10 +517,6 @@
         // invariant: we have a modified method name
 
         // 2. get and check configured method
-        if ( m_modifyMethod == null )
-        {
-            m_modifyMethod = new ModifiedMethod( this, getComponentMetadata().getModified(), getInstance().getClass() );
-        }
         // invariant: modify method is configured and found
 
         // 3. check whether we can dynamically apply the configuration if
@@ -565,7 +540,7 @@
         // 4. call method (nothing to do when failed, since it has already been logged)
         //   (call with non-null default result to continue even if the
         //    modify method call failed)
-        final MethodResult result = m_modifyMethod.invoke( getInstance(),
+        final MethodResult result = getComponentMethods().getModifiedMethod().invoke( getInstance(),
                 new ActivatorParameter( m_componentContext, -1 ), MethodResult.VOID );
         if ( result == null )
         {
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
index 063fd33..2666249 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
@@ -24,6 +24,7 @@
 
 import org.apache.felix.scr.impl.BundleComponentActivator;
 import org.apache.felix.scr.impl.config.ComponentHolder;
+import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
@@ -50,11 +51,12 @@
      * @param activator BundleComponentActivator for this DS implementation
 	 * @param componentHolder ComponentHolder for configuration management
      * @param metadata ComponentMetadata for this component
+     * @param componentMethods
      */
     public ServiceFactoryComponentManager( BundleComponentActivator activator, ComponentHolder componentHolder,
-        ComponentMetadata metadata )
+            ComponentMetadata metadata, ComponentMethods componentMethods )
     {
-        super( activator, componentHolder, metadata );
+        super( activator, componentHolder, metadata, componentMethods );
     }
 
 
diff --git a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
index f74872e..3cea976 100644
--- a/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
+++ b/scr/src/main/java/org/apache/felix/scr/impl/metadata/ComponentMetadata.java
@@ -793,8 +793,7 @@
             // flag duplicates
             if ( !refs.add( refMeta.getName() ) )
             {
-                logger.log( LogService.LOG_WARNING, "Detected duplicate reference name: ''{0}''", new Object[]
-                    { refMeta.getName() }, this, null );
+                throw validationFailure( "Detected duplicate reference name: ''" + refMeta.getName() + "''" );
             }
         }
 
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java b/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java
index 30e6a60..dbc033a 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/config/ConfiguredComponentHolderTest.java
@@ -27,6 +27,7 @@
 import junit.framework.TestCase;
 
 import org.apache.felix.scr.impl.BundleComponentActivator;
+import org.apache.felix.scr.impl.helper.ComponentMethods;
 import org.apache.felix.scr.impl.manager.ImmediateComponentManager;
 import org.apache.felix.scr.impl.metadata.ComponentMetadata;
 import org.apache.felix.scr.impl.metadata.XmlHandler;
@@ -233,7 +234,7 @@
 
         public MockImmediateComponentManager( BundleComponentActivator activator, ComponentHolder componentHolder, ComponentMetadata metadata )
         {
-            super( activator, componentHolder, metadata );
+            super( activator, componentHolder, metadata, new ComponentMethods() );
         }
 
 
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java b/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java
index 1bcd45a..973e5c7 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/helper/ActivateMethodTest.java
@@ -270,8 +270,8 @@
                 return true;
             }
         };
-        ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata );
-        ActivateMethod am = new ActivateMethod( icm, methodName, methodName != null, obj.getClass() );
+        ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata, new ComponentMethods() );
+        ActivateMethod am = new ActivateMethod( icm, methodName, methodName != null, obj.getClass(), true, false );
         am.invoke( obj, new ActivateMethod.ActivatorParameter( m_ctx, -1 ), null );
         Method m = get(am, "m_method");
         assertNotNull( m );
@@ -298,8 +298,8 @@
                 return true;
             }
         };
-        ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata );
-        ActivateMethod am = new ActivateMethod( icm, methodName, methodName != null, obj.getClass() );
+        ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata, new ComponentMethods() );
+        ActivateMethod am = new ActivateMethod( icm, methodName, methodName != null, obj.getClass(), true, false );
         am.invoke( obj, new ActivateMethod.ActivatorParameter( m_ctx, -1 ), null );
         assertNull( get( am, "m_method" ) );
         assertNull( obj.getCalledMethod() );
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java b/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java
index aec7ea4..3b05736 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/helper/BindMethodTest.java
@@ -432,9 +432,9 @@
                 return isDS11;
             }
         };
-        ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata );
+        ImmediateComponentManager icm = new ImmediateComponentManager( null, null, metadata, new ComponentMethods() );
         BindMethod bm = new BindMethod( icm, methodName, component.getClass(),
-                FakeService.class.getName() );
+                FakeService.class.getName(), isDS11, false );
         AbstractComponentManager.RefPair refPair = bm.getServiceObject( m_serviceReference, m_context );
         bm.invoke( component, refPair, null );
         assertEquals( expectCallPerformed, component.callPerformed );
diff --git a/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentMetadataTest.java b/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentMetadataTest.java
index 8912571..f07d2a9 100644
--- a/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentMetadataTest.java
+++ b/scr/src/test/java/org/apache/felix/scr/impl/metadata/ComponentMetadataTest.java
@@ -432,9 +432,15 @@
         final ComponentMetadata cm2 = createComponentMetadata( Boolean.TRUE, null );
         cm2.addDependency( createReferenceMetadata( "name1" ) );
         cm2.addDependency( createReferenceMetadata( "name1" ) );
-        cm2.validate( logger );
-        assertTrue( "Expected warning for duplicate reference name",
-            logger.messageContains( "Detected duplicate reference name" ) );
+        try
+        {
+            cm2.validate( logger );
+            fail( "Expect validation failure for duplicate reference name" );
+        }
+        catch ( ComponentException ee )
+        {
+             //expected
+        }
     }
 
 
diff --git a/scr/src/test/resources/integration_test_simple_components_service_binding.xml b/scr/src/test/resources/integration_test_simple_components_service_binding.xml
index c8804cc..372796f 100644
--- a/scr/src/test/resources/integration_test_simple_components_service_binding.xml
+++ b/scr/src/test/resources/integration_test_simple_components_service_binding.xml
@@ -282,7 +282,7 @@
             unbind="unbindSimpleService"
         />
         <reference
-            name="ref"
+            name="ref2"
             interface="org.apache.felix.scr.integration.components.SimpleService2"
             cardinality="0..n"
             policy="static"
diff --git a/scr/src/test/resources/integration_test_simple_components_service_binding_greedy.xml b/scr/src/test/resources/integration_test_simple_components_service_binding_greedy.xml
index 7b35e5f..39d72e7 100644
--- a/scr/src/test/resources/integration_test_simple_components_service_binding_greedy.xml
+++ b/scr/src/test/resources/integration_test_simple_components_service_binding_greedy.xml
@@ -300,7 +300,7 @@
             unbind="unbindSimpleService"
         />
         <reference
-            name="ref"
+            name="ref2"
             interface="org.apache.felix.scr.integration.components.SimpleService2"
             cardinality="0..n"
             policy="static"