FELIX-3680: Added a second integration test which concurrently register dependend services
using BundleContext.registerService.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1400611 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
index 072c724..dfaff77 100644
--- a/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
+++ b/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
@@ -127,7 +127,8 @@
                                             "org.apache.felix.scr.integration.components.activatesignature," +
                                             "org.apache.felix.scr.integration.components.circular," +
                                             "org.apache.felix.scr.integration.components.concurrency," +
-                                            "org.apache.felix.scr.integration.components.felix3680");
+                                            "org.apache.felix.scr.integration.components.felix3680," +
+                                            "org.apache.felix.scr.integration.components.felix3680_2");
         builder.setHeader("Import-Package", "org.apache.felix.scr,org.apache.felix.scr.component;mandatory:=\"status\"; status=\"provisional\"");
         builder.setHeader("Bundle-ManifestVersion", "2");
         return builder;
@@ -398,7 +399,8 @@
                         "org.apache.felix.scr.integration.components.activatesignature," +
                         "org.apache.felix.scr.integration.components.circular," +
                         "org.apache.felix.scr.integration.components.concurrency," +
-                        "org.apache.felix.scr.integration.components.felix3680")
+                        "org.apache.felix.scr.integration.components.felix3680," +
+                        "org.apache.felix.scr.integration.components.felix3680_2")
                 .set("Service-Component", "OSGI-INF/components.xml")
             .build(withBnd());
 
@@ -738,7 +740,6 @@
                     }
                     m_out.println( sw.toString() );
                     m_out.flush();
-
                 }
             }
             catch ( InterruptedException e )
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/Felix3680_2Test.java b/scr/src/test/java/org/apache/felix/scr/integration/Felix3680_2Test.java
new file mode 100644
index 0000000..57a5c58
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/Felix3680_2Test.java
@@ -0,0 +1,82 @@
+/*
+ * 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.integration;
+
+
+import java.util.Iterator;
+
+import javax.inject.Inject;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.scr.Component;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.osgi.framework.BundleContext;
+
+
+@RunWith(JUnit4TestRunner.class)
+public class Felix3680_2Test extends ComponentTestBase
+{
+    static
+    {
+        // uncomment to enable debugging of this test class
+        //        paxRunnerVmOption = DEBUG_VM_OPTION;
+        descriptorFile = "/integration_test_FELIX_3880_2.xml";
+        
+        // Comment this for displaying debug messages
+        DS_LOGLEVEL = "debug";
+    }
+
+    @Inject
+    protected BundleContext bundleContext;
+
+
+    protected static void delay( int secs )
+    {
+        try
+        {
+            Thread.sleep( secs * 1000 );
+        }
+        catch ( InterruptedException ie )
+        {
+        }
+    }
+
+
+    @Test
+    public void test_concurrent_injetion_with_bundleContext()
+    {
+        final Component main = findComponentByName( "org.apache.felix.scr.integration.components.felix3680_2.Main" );
+        TestCase.assertNotNull( main );
+        main.enable();
+
+        delay( 30 );
+        for ( Iterator it = log.foundWarnings().iterator(); it.hasNext(); )
+        {
+            String message = ( String ) it.next();
+            if ( message.startsWith( "Performed " ) && message.endsWith( " tests." ) )
+            {
+                continue;
+            }
+            TestCase.fail( "unexpected warning or error logged: " + message );
+        }
+    }
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/A.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/A.java
new file mode 100644
index 0000000..262a801
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/A.java
@@ -0,0 +1,75 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class A {
+        void bindB( B b )
+        {
+        }
+
+
+        void bindC( C c )
+        {
+        }
+
+
+        void bindD( D d )
+        {
+        }
+
+
+        void bindE( E e )
+        {
+        }
+
+
+        void bindF( F f )
+        {
+        }
+
+
+        void bindG( G g )
+        {
+        }
+
+
+        void bindH( H h )
+        {
+        }
+
+
+        void bindI( I i )
+        {
+        }
+
+
+        void bindJ( J j )
+        {
+        }
+
+
+        void bindK( K k )
+        {
+        }
+
+
+        void start()
+        {
+        }
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/B.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/B.java
new file mode 100644
index 0000000..80e6c7f
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/B.java
@@ -0,0 +1,22 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class B {
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/C.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/C.java
new file mode 100644
index 0000000..68cbb87
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/C.java
@@ -0,0 +1,22 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class C {
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/D.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/D.java
new file mode 100644
index 0000000..680c17e
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/D.java
@@ -0,0 +1,22 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class D {
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/E.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/E.java
new file mode 100644
index 0000000..f9ce2af
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/E.java
@@ -0,0 +1,22 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class E {
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/F.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/F.java
new file mode 100644
index 0000000..495346f
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/F.java
@@ -0,0 +1,22 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class F {
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/G.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/G.java
new file mode 100644
index 0000000..7add549
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/G.java
@@ -0,0 +1,22 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class G {
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/H.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/H.java
new file mode 100644
index 0000000..b10695f
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/H.java
@@ -0,0 +1,22 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class H {
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/I.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/I.java
new file mode 100644
index 0000000..79523cb
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/I.java
@@ -0,0 +1,22 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class I {
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/J.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/J.java
new file mode 100644
index 0000000..10ef015
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/J.java
@@ -0,0 +1,22 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class J {
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/K.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/K.java
new file mode 100644
index 0000000..a0406dd
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/K.java
@@ -0,0 +1,22 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+public class K {
+}
diff --git a/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/Main.java b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/Main.java
new file mode 100644
index 0000000..0c2646d
--- /dev/null
+++ b/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/Main.java
@@ -0,0 +1,290 @@
+/*
+ * 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.integration.components.felix3680_2;
+
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.felix.scr.ScrService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.log.LogService;
+
+
+public class Main implements Runnable
+{
+    private volatile ComponentContext m_ctx;
+    private volatile AtomicInteger m_counter = new AtomicInteger();
+    private volatile CountDownLatch m_enabledLatch;
+    private volatile CountDownLatch m_disabledLatch;
+    private volatile LogService m_logService;
+    private ScrService m_scr;
+    private final Executor m_exec = Executors.newFixedThreadPool( 50 );
+    private volatile BundleContext m_bctx;
+    volatile ConcurrentHashMap<Class, ServiceRegistration> m_registrations = new ConcurrentHashMap<Class, ServiceRegistration>();
+    volatile Exception _bindStackTrace;
+
+
+    /**
+     * Helper used to randomly enable or disable a list of components.
+     */
+    class RegistrationHelper
+    {
+        public void registerBCDEFGHIJK( Executor exec )
+        {
+            enableOrDisable( true );
+        }
+
+
+        public void unregisterBCDEFGHIJK( Executor exec )
+        {
+            enableOrDisable( false );
+        }
+
+
+        private void enableOrDisable( final boolean enable )
+        {
+            if ( enable )
+            {
+                register( B.class );
+                register( C.class );
+                register( D.class );
+                register( E.class );
+                register( F.class );
+                register( G.class );
+                register( H.class );
+                register( I.class );
+                register( J.class );
+                register( K.class );
+            }
+            else
+            {
+                unregister( B.class );
+                unregister( C.class );
+                unregister( D.class );
+                unregister( E.class );
+                unregister( F.class );
+                unregister( G.class );
+                unregister( H.class );
+                unregister( I.class );
+                unregister( J.class );
+                unregister( K.class );
+            }
+        }
+
+
+        private void register( final Class clazz )
+        {
+            m_exec.execute( new Runnable()
+            {
+                public void run()
+                {
+                    try
+                    {
+                        Object instance = clazz.newInstance();
+                        m_registrations.put( clazz, m_bctx.registerService( clazz.getName(), instance, null ) );
+                        m_enabledLatch.countDown();
+                    }
+                    catch ( Throwable e )
+                    {
+                        m_logService.log( LogService.LOG_ERROR, "error while enabling " + clazz, e );
+                    }
+                }
+            } );
+        }
+
+
+        private void unregister( final Class clazz )
+        {
+            m_exec.execute( new Runnable()
+            {
+                public void run()
+                {
+                    try
+                    {
+                        ServiceRegistration sr = m_registrations.remove( clazz );
+                        sr.unregister();
+                        m_disabledLatch.countDown();
+                    }
+                    catch ( Throwable e )
+                    {
+                        m_logService.log( LogService.LOG_ERROR, "error while enabling " + clazz, e );
+                    }
+                }
+            } );
+        }
+    }
+
+
+    void bindSCR( ScrService scr )
+    {
+        m_scr = scr;
+    }
+
+
+    void bindLogService( LogService logService )
+    {
+        m_logService = logService;
+    }
+
+
+    void bindA( ServiceReference sr )
+    {
+        Exception trace = new Exception( "bindA (" + Thread.currentThread() + ")" );
+        if ( _bindStackTrace != null )
+        {
+            m_logService.log( LogService.LOG_ERROR, "Already bound A from stacktrace:", _bindStackTrace );
+            m_logService.log( LogService.LOG_ERROR, "Current stacktrace is:", trace );
+            return;
+        }
+
+        _bindStackTrace = trace;
+
+        A a = ( A ) sr.getBundle().getBundleContext().getService( sr );
+        if ( a == null )
+        {
+            throw new IllegalStateException( "bindA: bundleContext.getService returned null" );
+        }
+        if ( m_counter.incrementAndGet() != 1 )
+        {
+            throw new IllegalStateException( "bindA: invalid counter value: " + m_counter );
+        }
+        m_enabledLatch.countDown();
+    }
+
+
+    void unbindA( A a )
+    {
+        if ( m_counter.decrementAndGet() != 0 )
+        {
+            throw new IllegalStateException( "unbindA: invalid counter value: " + m_counter );
+        }
+        _bindStackTrace = null;
+        m_disabledLatch.countDown();
+    }
+
+
+    void start( ComponentContext ctx )
+    {
+        m_logService.log( LogService.LOG_WARNING, "Main.start" );
+        m_ctx = ctx;
+        m_bctx = ctx.getBundleContext();
+        m_ctx.getBundleContext().registerService( Executor.class.getName(), m_exec, null );
+        new Thread( this ).start();
+    }
+
+
+    public void run()
+    {
+        m_logService.log( LogService.LOG_WARNING, "Main.run" );
+        int loop = 0;
+        while ( true )
+        {
+            m_enabledLatch = new CountDownLatch( 11 ); // 10 for registrations of B,C,D,E,F,G,H,I,J,K + 1 for Main.bindA
+            m_disabledLatch = new CountDownLatch( 11 ); // 10 for unregistrations of B,C,D,E,F,G,H,I,J,K + 1 for Main.unbindA
+
+            RegistrationHelper registry = new RegistrationHelper();
+            registry.registerBCDEFGHIJK( m_exec );
+
+            try
+            {
+                if ( !m_enabledLatch.await( 10000, TimeUnit.MILLISECONDS ) )
+                {
+                    System.out.println( "Did not get A injected timely ... see logs.txt" );
+                    m_logService.log( LogService.LOG_ERROR, "enableLatch TIMEOUT" );
+                    dumpA();
+                    System.exit( 1 );
+                }
+            }
+            catch ( InterruptedException e )
+            {
+            }
+
+            registry.unregisterBCDEFGHIJK( m_exec );
+            try
+            {
+                if ( !m_disabledLatch.await( 10000, TimeUnit.MILLISECONDS ) )
+                {
+                    System.out.println( "Could not disable components timely ... see logs.txt" );
+                    m_logService.log( LogService.LOG_ERROR, "disableLatch TIMEOUT" );
+                    dumpA();
+                    System.exit( 1 );
+                }
+            }
+            catch ( InterruptedException e )
+            {
+            }
+
+            ++loop;
+            //            if ( loop % 100 == 0 )
+            //            {
+            m_logService.log( LogService.LOG_WARNING, "Performed " + loop + " tests." );
+            // }
+        }
+    }
+
+
+    private void dumpA()
+    {
+        org.apache.felix.scr.Component c = m_scr
+            .getComponents( "org.apache.felix.scr.integration.components.felix3680_2.A" )[0];
+        m_logService.log( LogService.LOG_WARNING, "State of " + c + ":" + getState( c ) + "\n" );
+    }
+
+
+    private CharSequence getState( org.apache.felix.scr.Component c )
+    {
+        switch ( c.getState() )
+        {
+            case org.apache.felix.scr.Component.STATE_ACTIVATING:
+                return "activating";
+            case org.apache.felix.scr.Component.STATE_ACTIVE:
+                return "active";
+            case org.apache.felix.scr.Component.STATE_DEACTIVATING:
+                return "deactivating";
+            case org.apache.felix.scr.Component.STATE_DISABLED:
+                return "disabled";
+            case org.apache.felix.scr.Component.STATE_DISABLING:
+                return "disabling";
+            case org.apache.felix.scr.Component.STATE_DISPOSED:
+                return "disposed";
+            case org.apache.felix.scr.Component.STATE_DISPOSING:
+                return "disposing";
+            case org.apache.felix.scr.Component.STATE_ENABLED:
+                return "enabled";
+            case org.apache.felix.scr.Component.STATE_ENABLING:
+                return "enabling";
+            case org.apache.felix.scr.Component.STATE_FACTORY:
+                return "factory";
+            case org.apache.felix.scr.Component.STATE_REGISTERED:
+                return "registered";
+            case org.apache.felix.scr.Component.STATE_UNSATISFIED:
+                return "unsatisfied";
+            default:
+                return "?";
+        }
+    }
+}
diff --git a/scr/src/test/resources/integration_test_FELIX_3880_2.xml b/scr/src/test/resources/integration_test_FELIX_3880_2.xml
new file mode 100644
index 0000000..f4e9d5e
--- /dev/null
+++ b/scr/src/test/resources/integration_test_FELIX_3880_2.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 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. -->
+<components xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
+	<scr:component xmlns:scr='http://www.osgi.org/xmlns/scr/v1.1.0'
+		enabled='false' name='org.apache.felix.scr.integration.components.felix3680_2.Main'
+		activate='start'>
+		<implementation
+			class='org.apache.felix.scr.integration.components.felix3680_2.Main' />
+		<reference name='a'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.A'
+			cardinality='0..1' bind='bindA' unbind='unbindA' policy='dynamic' />
+		<reference name='logService' interface='org.osgi.service.log.LogService'
+			bind='bindLogService' />
+		<reference name='sCR' interface='org.apache.felix.scr.ScrService'
+			bind='bindSCR' />
+	</scr:component>
+
+	<scr:component xmlns:scr='http://www.osgi.org/xmlns/scr/v1.1.0'
+		name='org.apache.felix.scr.integration.components.felix3680_2.A' activate='start'>
+		<implementation
+			class='org.apache.felix.scr.integration.components.felix3680_2.A' />
+		<service>
+			<provide interface='org.apache.felix.scr.integration.components.felix3680_2.A' />
+		</service>
+		<reference name='b'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.B'
+			cardinality='0..n' bind='bindB' policy='dynamic' />
+		<reference name='c'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.C'
+			cardinality='0..n' bind='bindC' policy='dynamic' />
+		<reference name='d'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.D'
+			cardinality='0..n' bind='bindD' policy='dynamic' />
+		<reference name='e'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.E'
+			cardinality='0..n' bind='bindE' policy='dynamic' />
+		<reference name='f'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.F'
+			cardinality='0..n' bind='bindF' policy='dynamic' />
+		<reference name='g'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.G'
+			bind='bindG' />
+		<reference name='h'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.H'
+			bind='bindH' />
+		<reference name='i'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.I'
+			bind='bindI' />
+		<reference name='j'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.J'
+			bind='bindJ' />
+		<reference name='k'
+			interface='org.apache.felix.scr.integration.components.felix3680_2.K'
+			bind='bindK' />
+	</scr:component>
+</components>