diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/integration/api/AdapterWithModifiedInstanceBoundDependencyTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/integration/api/AdapterWithModifiedInstanceBoundDependencyTest.java
new file mode 100644
index 0000000..450badc
--- /dev/null
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/integration/api/AdapterWithModifiedInstanceBoundDependencyTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.dm.test.integration.api;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.test.components.Ensure;
+import org.apache.felix.dm.test.integration.common.TestBase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+
+/**
+ * Test for FELIX-4334 issue.
+ * 
+ * Three components: A, B and C
+ * 
+ * - A provided with property foo=bar
+ * - B adapts A, B has no filters on A, and B.init() method adds an instance bound required dependency to C.
+ * - C depends on A(foo=bar)
+ * - Now someone modifies the service properties of A: foo=bar2
+ * - As a result of that, C becomes unavailable and is unbound from B.
+ * - Since B has an instance bound required dependency to C: B should not be destroyed: it should be called in B.stop(), B.remove(C), B.change(A, "foo=bar2))
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@RunWith(PaxExam.class)
+public class AdapterWithModifiedInstanceBoundDependencyTest extends TestBase {
+    public static interface A {
+    }
+    
+    static class AImpl implements A {
+        final Ensure m_e;
+        AImpl(Ensure e) {
+            m_e = e;
+        }        
+    }
+    
+    public static interface C {
+    }
+
+    static class CImpl implements C {
+        volatile A m_a;
+    }
+    
+    public static interface B {
+    }
+    
+    static class BImpl implements B {
+        final Ensure m_e;
+        volatile A m_a;
+        volatile C m_c;
+        
+        BImpl(Ensure e) {
+            m_e = e;
+        }
+        
+        public void add(A a) {
+            m_e.step(1);
+        }
+
+        void init(Component c) {
+            m_e.step(2);
+            DependencyManager dm = c.getDependencyManager();
+            c.add(dm.createServiceDependency().setService(C.class).setRequired(true).setInstanceBound(true).setCallbacks("add", "remove"));
+        }      
+        
+        public void add(C c) {
+            m_e.step(3);
+        }
+        
+        public void start() {
+            m_e.step(4);            
+        }
+        
+        public void stop() { // C becomes unsatisfied when A properties are changed to foo=bar2
+            m_e.step(5);
+        }
+
+        public void remove(C c) {
+            m_e.step(6);
+        }
+
+        public void change(Map properties, A a) {
+            Assert.assertEquals("bar2", properties.get("foo"));
+            m_e.step(7);
+        }
+        
+        public void destroy() {
+            m_e.step(8);
+        }
+
+        public void remove(A a) {   
+            m_e.step(9);
+        }                    
+    }
+    
+    @Test
+    public void testAdapterWithChangedInstanceBoundDependency() {
+        DependencyManager m = new DependencyManager(context);
+        Ensure e = new Ensure();
+
+        Dictionary props = new Hashtable();
+        props.put("foo", "bar");
+        Component a = m.createComponent()
+                .setImplementation(new AImpl(e))
+                .setInterface(A.class.getName(), props);
+        
+        Component b = m.createAdapterService(A.class, null, "add", "change", "remove")
+                .setInterface(B.class.getName(), null)
+                .setImplementation(new BImpl(e));                
+        
+        Component c = m.createComponent()
+                .setImplementation(new CImpl())
+                .setInterface(C.class.getName(), null)
+                .add(m.createServiceDependency().setService(A.class, "(foo=bar)").setRequired(true));                     
+              
+        m.add(a);
+        m.add(c);
+        m.add(b);
+        
+        e.waitForStep(4, 5000);
+        
+        System.out.println("changing A props ...");
+        props = new Hashtable();
+        props.put("foo", "bar2");
+        a.setServiceProperties(props);
+        
+        e.waitForStep(7, 5000);                
+        
+        m.remove(c);
+        m.remove(a);
+        m.remove(b);
+        
+        e.waitForStep(9, 5000);                
+    }
+}
diff --git a/dependencymanager/test/src/test/java/org/apache/felix/dm/test/integration/api/ModifiedBundleDependencyTest.java b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/integration/api/ModifiedBundleDependencyTest.java
new file mode 100644
index 0000000..2edd8d8
--- /dev/null
+++ b/dependencymanager/test/src/test/java/org/apache/felix/dm/test/integration/api/ModifiedBundleDependencyTest.java
@@ -0,0 +1,145 @@
+/*
+ * 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.dm.test.integration.api;
+
+import junit.framework.Assert;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.test.components.Ensure;
+import org.apache.felix.dm.test.integration.common.TestBase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleException;
+
+/**
+ * Test for FELIX-4334 issue.
+ * 
+ * Two components: A, B
+ * 
+ * - A provided.
+ * - B has a bundle dependency on the dependency manager shell bundle, which is currently stopped.
+ * - B has an instance bound dependency on A.
+ * - Now unregister A.
+ * - As a result of that, B becomes unavailable and is unbound from A. But B is not destroyed, because A dependency 
+ *   is "instance bound". So B is still bound to the bundle dependency.
+ * - Now, someone starts the dependency manager shell bundle: B then shall be called in its "changed" callback.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@RunWith(PaxExam.class)
+public class ModifiedBundleDependencyTest extends TestBase {
+    public static interface A {
+    }
+    
+    static class AImpl implements A {
+    }
+        
+    public static interface B {
+    }
+    
+    static class BImpl implements B {
+        final Ensure m_e;
+        
+        BImpl(Ensure e) {
+            m_e = e;
+        }
+        
+        public void add(Bundle dmTest) {
+            m_e.step(1);
+        }
+
+        void init(Component c) {
+            m_e.step(2);
+            DependencyManager dm = c.getDependencyManager();
+            c.add(dm.createServiceDependency().setService(A.class).setRequired(true).setInstanceBound(true).setCallbacks("add", "remove"));
+        }      
+        
+        public void add(A a) {
+            m_e.step(3);
+        }
+        
+        public void start() {
+            m_e.step(4);            
+        }
+        
+        public void stop() {
+            m_e.step(5);
+        }
+
+        public void remove(A a) {
+            m_e.step(6);
+        }
+
+        public void change(Bundle dmTest) { // called two times: one for STARTING, one for STARTED
+            m_e.step(); 
+        }
+        
+        public void destroy() {
+            m_e.step(9);
+        }
+
+        public void remove(Bundle dmTest) {   
+            m_e.step(10);
+        }                    
+    }
+    
+    @Test
+    public void testAdapterWithChangedInstanceBoundDependency() {
+        DependencyManager m = new DependencyManager(context);
+        Ensure e = new Ensure();
+
+        Component a = m.createComponent()
+                .setImplementation(new AImpl())
+                .setInterface(A.class.getName(), null);
+        
+        Component b = m.createComponent()
+                .setInterface(B.class.getName(), null)
+                .setImplementation(new BImpl(e))
+                .add(m.createBundleDependency()
+                        .setFilter("(Bundle-SymbolicName=org.apache.felix.dependencymanager.shell)")
+                        .setStateMask(Bundle.INSTALLED|Bundle.ACTIVE|Bundle.RESOLVED|Bundle.STARTING)
+                        .setRequired(true)
+                        .setCallbacks("add", "change", "remove"));
+                    
+        Bundle dmtest = getBundle("org.apache.felix.dependencymanager.shell");
+        try {
+            dmtest.stop();
+        } catch (BundleException e1) {
+            Assert.fail("couold not find dependencymanager shell bundle");
+        }
+        
+        m.add(a);
+        m.add(b);
+        
+        e.waitForStep(4, 5000);        
+        m.remove(a); // B will loose A and will enter into "waiting for required (instantiated)" state.
+        System.out.println("Starting dependency manager shell ...");        
+        try {
+            dmtest.start();
+        } catch (BundleException e1) {
+            Assert.fail("could not start dependencymanager shell bundle");
+        }
+        e.waitForStep(7, 5000);     
+        m.remove(b);        
+        e.waitForStep(10, 5000);                
+    }
+}
