felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From uiter...@apache.org
Subject svn commit: r1487106 [1/2] - in /felix/sandbox/uiterlix/MTDMTest: ./ .settings/ src/ src/nl/ src/nl/uiterlinden/ src/nl/uiterlinden/mtdmtest/ src/nl/uiterlinden/mtdmtest/a/ src/nl/uiterlinden/mtdmtest/aspect/ src/nl/uiterlinden/mtdmtest/b/ src/nl/uiter...
Date Tue, 28 May 2013 20:38:14 GMT
Author: uiterlix
Date: Tue May 28 20:38:13 2013
New Revision: 1487106

URL: http://svn.apache.org/r1487106
Log:
Initial import of dependency manager multithreading test project.

Added:
    felix/sandbox/uiterlix/MTDMTest/.classpath
    felix/sandbox/uiterlix/MTDMTest/.gitignore
    felix/sandbox/uiterlix/MTDMTest/.project
    felix/sandbox/uiterlix/MTDMTest/.settings/
    felix/sandbox/uiterlix/MTDMTest/.settings/org.eclipse.jdt.core.prefs
    felix/sandbox/uiterlix/MTDMTest/a.bnd
    felix/sandbox/uiterlix/MTDMTest/aspect.bnd
    felix/sandbox/uiterlix/MTDMTest/b.bnd
    felix/sandbox/uiterlix/MTDMTest/base.bnd
    felix/sandbox/uiterlix/MTDMTest/bnd.bnd
    felix/sandbox/uiterlix/MTDMTest/build.xml
    felix/sandbox/uiterlix/MTDMTest/deadlock.bnd
    felix/sandbox/uiterlix/MTDMTest/deadlock.bndrun
    felix/sandbox/uiterlix/MTDMTest/index-debug.bndrun
    felix/sandbox/uiterlix/MTDMTest/index-plain.bndrun
    felix/sandbox/uiterlix/MTDMTest/index.bnd
    felix/sandbox/uiterlix/MTDMTest/index.bndrun
    felix/sandbox/uiterlix/MTDMTest/instance.bnd
    felix/sandbox/uiterlix/MTDMTest/instancebound.bnd
    felix/sandbox/uiterlix/MTDMTest/instancebound.bndrun
    felix/sandbox/uiterlix/MTDMTest/observaties.txt
    felix/sandbox/uiterlix/MTDMTest/run.bnd
    felix/sandbox/uiterlix/MTDMTest/run.bndrun
    felix/sandbox/uiterlix/MTDMTest/simple.bnd
    felix/sandbox/uiterlix/MTDMTest/simple.bndrun
    felix/sandbox/uiterlix/MTDMTest/src/
    felix/sandbox/uiterlix/MTDMTest/src/.gitignore
    felix/sandbox/uiterlix/MTDMTest/src/nl/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/Activator.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/NodeImpl.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/Activator.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/NodeImpl.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/ProducerAspect.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/ProducerWannabeAspect.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/Activator.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/NodeImpl.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/ProducerWannabeAdapterImpl.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/InstanceProvider.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/InstanceProviderImpl.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/Node.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/Producer.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerImpl.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerNoDeps.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerWannabe.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerWannabeImpl.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/packageinfo
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/A.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/Activator.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/B.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Activator.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/AdvancedMultiPropertyFilterIndex.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Filter.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Property.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/instance/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/instance/Activator.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/instance/NodeImpl.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/instancebound/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/instancebound/Activator.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/run/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/run/Activator.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/run/Coordinator.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/run/SideKick.java
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/simple/
    felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/simple/Activator.java
    felix/sandbox/uiterlix/MTDMTest/test/
    felix/sandbox/uiterlix/MTDMTest/test/.gitignore
    felix/sandbox/uiterlix/MTDMTest/test/nl/
    felix/sandbox/uiterlix/MTDMTest/test/nl/uiterlinden/
    felix/sandbox/uiterlix/MTDMTest/test/nl/uiterlinden/mtdmtest/
    felix/sandbox/uiterlix/MTDMTest/test/nl/uiterlinden/mtdmtest/index/
    felix/sandbox/uiterlix/MTDMTest/test/nl/uiterlinden/mtdmtest/index/MultiPropertyFilterIndexTest.java
    felix/sandbox/uiterlix/MTDMTest/test/nl/uiterlinden/mtdmtest/index/ServiceListenerImpl.java
    felix/sandbox/uiterlix/MTDMTest/test/nl/uiterlinden/mtdmtest/index/ServiceReferenceImpl.java

Added: felix/sandbox/uiterlix/MTDMTest/.classpath
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/.classpath?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/.classpath (added)
+++ felix/sandbox/uiterlix/MTDMTest/.classpath Tue May 28 20:38:13 2013
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>

Added: felix/sandbox/uiterlix/MTDMTest/.gitignore
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/.gitignore?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/.gitignore (added)
+++ felix/sandbox/uiterlix/MTDMTest/.gitignore Tue May 28 20:38:13 2013
@@ -0,0 +1,3 @@
+/bin/
+/bin_test/
+/generated/

Added: felix/sandbox/uiterlix/MTDMTest/.project
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/.project?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/.project (added)
+++ felix/sandbox/uiterlix/MTDMTest/.project Tue May 28 20:38:13 2013
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>MTDMTest</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>

Added: felix/sandbox/uiterlix/MTDMTest/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/.settings/org.eclipse.jdt.core.prefs?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/.settings/org.eclipse.jdt.core.prefs (added)
+++ felix/sandbox/uiterlix/MTDMTest/.settings/org.eclipse.jdt.core.prefs Tue May 28 20:38:13 2013
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6

Added: felix/sandbox/uiterlix/MTDMTest/a.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/a.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/a.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/a.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,3 @@
+Private-Package: nl.uiterlinden.mtdmtest.a
+Bundle-Activator: nl.uiterlinden.mtdmtest.a.Activator
+Bundle-Version: 1.0.0
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/aspect.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/aspect.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/aspect.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/aspect.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,3 @@
+Private-Package: nl.uiterlinden.mtdmtest.aspect
+Bundle-Version: 1.0.0
+Bundle-Activator: nl.uiterlinden.mtdmtest.aspect.Activator
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/b.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/b.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/b.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/b.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,3 @@
+Private-Package: nl.uiterlinden.mtdmtest.b
+Bundle-Version: 1.0.0
+Bundle-Activator: nl.uiterlinden.mtdmtest.b.Activator
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/base.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/base.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/base.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/base.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,2 @@
+Export-Package: nl.uiterlinden.mtdmtest.base
+Bundle-Version: 1.0.0
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/bnd.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/bnd.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/bnd.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/bnd.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,3 @@
+-buildpath: osgi.core,\
+	org.apache.felix.dependencymanager;version=latest
+-sub: *.bnd
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/build.xml
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/build.xml?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/build.xml (added)
+++ felix/sandbox/uiterlix/MTDMTest/build.xml Tue May 28 20:38:13 2013
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="project" default="build">
+
+	<!-- -->
+
+	<import file="../cnf/build.xml" />
+</project>

Added: felix/sandbox/uiterlix/MTDMTest/deadlock.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/deadlock.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/deadlock.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/deadlock.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,2 @@
+Private-Package: nl.uiterlinden.mtdmtest.deadlock
+Bundle-Activator: nl.uiterlinden.mtdmtest.deadlock.Activator
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/deadlock.bndrun
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/deadlock.bndrun?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/deadlock.bndrun (added)
+++ felix/sandbox/uiterlix/MTDMTest/deadlock.bndrun Tue May 28 20:38:13 2013
@@ -0,0 +1,10 @@
+-runfw: org.eclipse.osgi;version='[3.7,4)'
+-runee: JavaSE-1.6
+-runvm: -Dosgi.console
+-runrequires: osgi.identity;filter:='(osgi.identity=MTDMTest.deadlock)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.base)'
+-runbundles: MTDMTest.base;version=latest,\
+	MTDMTest.deadlock;version=latest,\
+	org.apache.felix.configadmin;version='[1.4.0,1.4.1)',\
+	org.apache.felix.dependencymanager;version=latest,\
+	org.apache.felix.metatype;version='[1.0.4,1.0.5)'
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/index-debug.bndrun
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/index-debug.bndrun?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/index-debug.bndrun (added)
+++ felix/sandbox/uiterlix/MTDMTest/index-debug.bndrun Tue May 28 20:38:13 2013
@@ -0,0 +1,10 @@
+-runfw: org.eclipse.osgi;version='[3.7,4)'
+-runee: JavaSE-1.6
+-runvm: -agentpath:/Applications/jprofiler7/bin/macos/libjprofilerti.jnilib=port=8849 -Xmx2048M -Dosgi.console -Dorg.apache.felix.dependencymanager.filterindex="*adapter*;*aspect*;objectClass,x,y;objectClass,x,y,!z*"
+-runrequires: osgi.identity;filter:='(osgi.identity=MTDMTest.base)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.index)'
+-runbundles: MTDMTest.base;version=latest,\
+	MTDMTest.index;version=latest,\
+	org.apache.felix.configadmin;version='[1.4.0,1.4.1)',\
+	org.apache.felix.dependencymanager;version=latest,\
+	org.apache.felix.metatype;version='[1.0.4,1.0.5)'

Added: felix/sandbox/uiterlix/MTDMTest/index-plain.bndrun
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/index-plain.bndrun?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/index-plain.bndrun (added)
+++ felix/sandbox/uiterlix/MTDMTest/index-plain.bndrun Tue May 28 20:38:13 2013
@@ -0,0 +1,10 @@
+-runfw: org.eclipse.osgi;version='[3.7,4)'
+-runee: JavaSE-1.6
+-runvm: -Xmx2048M -Dosgi.console
+-runrequires: osgi.identity;filter:='(osgi.identity=MTDMTest.base)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.index)'
+-runbundles: MTDMTest.base;version=latest,\
+	MTDMTest.index;version=latest,\
+	org.apache.felix.configadmin;version='[1.4.0,1.4.1)',\
+	org.apache.felix.dependencymanager;version=latest,\
+	org.apache.felix.metatype;version='[1.0.4,1.0.5)'
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/index.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/index.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/index.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/index.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,2 @@
+Bundle-Activator: nl.uiterlinden.mtdmtest.index.Activator
+Private-Package: nl.uiterlinden.mtdmtest.index
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/index.bndrun
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/index.bndrun?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/index.bndrun (added)
+++ felix/sandbox/uiterlix/MTDMTest/index.bndrun Tue May 28 20:38:13 2013
@@ -0,0 +1,10 @@
+-runfw: org.eclipse.osgi;version='[3.7,4)'
+-runee: JavaSE-1.6
+-runvm: -Xmx2048M -Dosgi.console -Dorg.apache.felix.dependencymanager.filterindex="*adapter*;*aspect*;objectClass,x,y;objectClass,x,y,!z*"
+-runrequires: osgi.identity;filter:='(osgi.identity=MTDMTest.base)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.index)'
+-runbundles: MTDMTest.base;version=latest,\
+	MTDMTest.index;version=latest,\
+	org.apache.felix.configadmin;version='[1.4.0,1.4.1)',\
+	org.apache.felix.dependencymanager;version=latest,\
+	org.apache.felix.metatype;version='[1.0.4,1.0.5)'

Added: felix/sandbox/uiterlix/MTDMTest/instance.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/instance.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/instance.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/instance.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,2 @@
+Private-Package: nl.uiterlinden.mtdmtest.instance
+Bundle-Activator: nl.uiterlinden.mtdmtest.instance.Activator
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/instancebound.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/instancebound.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/instancebound.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/instancebound.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,2 @@
+Private-Package: nl.uiterlinden.mtdmtest.instancebound
+Bundle-Activator: nl.uiterlinden.mtdmtest.instancebound.Activator
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/instancebound.bndrun
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/instancebound.bndrun?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/instancebound.bndrun (added)
+++ felix/sandbox/uiterlix/MTDMTest/instancebound.bndrun Tue May 28 20:38:13 2013
@@ -0,0 +1,10 @@
+-runfw: org.eclipse.osgi;version='[3.7,4)'
+-runee: JavaSE-1.6
+-runvm: -Dosgi.console
+-runrequires: osgi.identity;filter:='(osgi.identity=MTDMTest.base)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.instancebound)'
+-runbundles: MTDMTest.base;version=latest,\
+	MTDMTest.instancebound;version=latest,\
+	org.apache.felix.configadmin;version='[1.4.0,1.4.1)',\
+	org.apache.felix.dependencymanager;version=latest,\
+	org.apache.felix.metatype;version='[1.0.4,1.0.5)'
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/observaties.txt
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/observaties.txt?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/observaties.txt (added)
+++ felix/sandbox/uiterlix/MTDMTest/observaties.txt Tue May 28 20:38:13 2013
@@ -0,0 +1,24 @@
+observaties
+
+- met adapter nullpointer in handleaspectawareremoved
+- zonder adapter blijft er 1 producer over...
+	- hoe meer threads hoe meer producers er blijven hangen
+	
+	
+	ook
+	
+	Exception in thread "Thread-3" java.lang.NullPointerException
+	at org.apache.felix.dm.DependencyManager.remove(DependencyManager.java:179)
+	at nl.uiterlinden.mtdmtest.a.NodeImpl.unregister(NodeImpl.java:59)
+	at nl.uiterlinden.mtdmtest.run.Coordinator$1.run(Coordinator.java:46)
+	at java.lang.Thread.run(Thread.java:680)
+	
+	
+	serialexecutor omzetten naar java 1.4 variant en implementeren per dependencyservice
+	
+	nu worden de overige lifecyclecallbacks nog te vroeg aangeroepen (namelijk potentieel voordat het veld daadwerkelijk gezet is)
+	ds.dependencyAvailable
+	ds.dependencyUnavailable
+	ds.dependencyChanged
+	
+	
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/run.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/run.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/run.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/run.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,3 @@
+Private-Package: nl.uiterlinden.mtdmtest.run
+Bundle-Version: 1.0.0
+Bundle-Activator: nl.uiterlinden.mtdmtest.run.Activator
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/run.bndrun
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/run.bndrun?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/run.bndrun (added)
+++ felix/sandbox/uiterlix/MTDMTest/run.bndrun Tue May 28 20:38:13 2013
@@ -0,0 +1,20 @@
+-runfw: org.eclipse.osgi;version='[3.7,4)'
+-runee: JavaSE-1.6
+-runvm: -Dosgi.console -Xmx4096M
+-runrequires: osgi.identity;filter:='(osgi.identity=MTDMTest.a)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.aspect)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.b)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.base)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.run)',\
+	osgi.identity;filter:='(osgi.identity=DMShell)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.instance)'
+-runbundles: DMShell;version=latest,\
+	MTDMTest.a;version=latest,\
+	MTDMTest.aspect;version=latest,\
+	MTDMTest.b;version=latest,\
+	MTDMTest.base;version=latest,\
+	MTDMTest.instance;version=latest,\
+	MTDMTest.run;version=latest,\
+	org.apache.felix.configadmin;version='[1.4.0,1.4.1)',\
+	org.apache.felix.dependencymanager;version=latest,\
+	org.apache.felix.metatype;version='[1.0.4,1.0.5)'
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/simple.bnd
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/simple.bnd?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/simple.bnd (added)
+++ felix/sandbox/uiterlix/MTDMTest/simple.bnd Tue May 28 20:38:13 2013
@@ -0,0 +1,2 @@
+Private-Package: nl.uiterlinden.mtdmtest.simple
+Bundle-Activator: nl.uiterlinden.mtdmtest.simple.Activator
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/simple.bndrun
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/simple.bndrun?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/simple.bndrun (added)
+++ felix/sandbox/uiterlix/MTDMTest/simple.bndrun Tue May 28 20:38:13 2013
@@ -0,0 +1,10 @@
+-runfw: org.eclipse.osgi;version='[3.7,4)'
+-runee: JavaSE-1.6
+-runvm: -Dosgi.console
+-runrequires: osgi.identity;filter:='(osgi.identity=MTDMTest.base)',\
+	osgi.identity;filter:='(osgi.identity=MTDMTest.simple)'
+-runbundles: MTDMTest.base;version=latest,\
+	MTDMTest.simple;version=latest,\
+	org.apache.felix.configadmin;version='[1.4.0,1.4.1)',\
+	org.apache.felix.dependencymanager;version=latest,\
+	org.apache.felix.metatype;version='[1.0.4,1.0.5)'
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/src/.gitignore
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/.gitignore?rev=1487106&view=auto
==============================================================================
    (empty)

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/Activator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/Activator.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/Activator.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/Activator.java Tue May 28 20:38:13 2013
@@ -0,0 +1,45 @@
+package nl.uiterlinden.mtdmtest.a;
+
+import nl.uiterlinden.mtdmtest.base.Node;
+
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends DependencyActivatorBase {
+	
+	private static DependencyManager manager;
+
+	@Override
+	public void init(BundleContext context, final DependencyManager manager)
+			throws Exception {
+		
+		Activator.manager = manager;
+		new Thread(new Runnable() {
+
+			@Override
+			public void run() {
+				try {
+					Thread.sleep(1000);
+					manager.add(createComponent().setInterface(Node.class.getName(), null).setImplementation(NodeImpl.class));
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+				
+			}
+			
+		}).start();
+//		manager.add(createComponent().setInterface(Node.class.getName(), null).setImplementation(NodeImpl.class));
+	}
+
+	@Override
+	public void destroy(BundleContext context, DependencyManager manager)
+			throws Exception {
+
+	}
+
+	public static DependencyManager dependencyManager() {
+		return manager;
+	}
+	
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/NodeImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/NodeImpl.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/NodeImpl.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/a/NodeImpl.java Tue May 28 20:38:13 2013
@@ -0,0 +1,138 @@
+package nl.uiterlinden.mtdmtest.a;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import nl.uiterlinden.mtdmtest.base.Node;
+import nl.uiterlinden.mtdmtest.base.Producer;
+import nl.uiterlinden.mtdmtest.base.ProducerImpl;
+import nl.uiterlinden.mtdmtest.base.ProducerWannabe;
+import nl.uiterlinden.mtdmtest.base.ProducerWannabeImpl;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+public class NodeImpl implements Node {
+	
+	private static final int COUNT = 10;
+	List<Component> components = new ArrayList<Component>();
+	private final AtomicInteger count = new AtomicInteger(0);
+	Executor executor = Executors.newFixedThreadPool(Node.THREADCOUNT);
+
+	@Override
+	public void register(final int run) {
+		final DependencyManager manager = Activator.dependencyManager();
+		System.out.println(run + " Register producers " + components.size() + "/" + count.get());
+		for (int i = 0; i < COUNT; i++) {
+			final int number = i;
+			Runnable runnable = new Runnable() {
+				@Override
+				public void run() {
+					try {
+//						Thread.sleep(5);
+						Producer producerImpl = new ProducerImpl("" + number);
+						Properties props = new Properties();
+						props.setProperty("producer.id", "" + number);
+						props.setProperty("test.run", "" + run);
+						Component producer = manager.createComponent().setInterface(Producer.class.getName(), props)
+								.setImplementation(producerImpl);
+						manager.add(producer);
+						synchronized(components) {
+							components.add(producer);
+							count.incrementAndGet();
+						}
+
+						props = new Properties();
+						props.setProperty("producerwannabe.id", "" + number);
+						props.setProperty("test.run", "" + run);
+						Component producerWannabe = manager.createComponent().setInterface(ProducerWannabe.class.getName(), props)
+								.setImplementation(ProducerWannabeImpl.class);
+						manager.add(producerWannabe);
+						synchronized(components) {
+							components.add(producerWannabe);
+							count.incrementAndGet();
+						}
+
+					} catch (Exception e) {
+						e.printStackTrace();
+					}
+				}
+			};
+			if (Node.THREADCOUNT > 1) {
+				executor.execute(runnable);
+			} else {
+				runnable.run();
+			}
+		}
+		// wait for completion
+		while (count.get() < (COUNT*2)) {
+			try {
+				Thread.sleep(10);
+//				System.out.println("waiting for producer launch.. " + count);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		System.out.println(run + " Registered producers " + components.size() + "/" + count.get());
+	}
+
+	@Override
+	public void unregister(int run) {
+		// also multithreaded removal
+		final DependencyManager manager = Activator.dependencyManager();
+		System.out.println(run + " clearing producers... " + components.size() + "/" + count.get());
+		for (Component component : components) {
+			final Component componentToRemove = component;
+			Runnable runnable = new Runnable() {
+
+				@Override
+				public void run() {
+					manager.remove(componentToRemove);
+					count.decrementAndGet();
+				}
+			};
+			if (Node.THREADCOUNT > 1) {
+				executor.execute(runnable);
+			} else {
+				runnable.run();
+			}
+		}
+		int sleep = 0;
+		while (count.get() > 0) {
+			try {
+				Thread.sleep(10);
+				sleep = sleep + 10;
+				if (sleep == 1000) {
+					System.out.println("problem...");
+				}
+//				System.out.println("waiting for producer cleanup.. " + count);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		synchronized (components) {
+			components.clear();
+		}
+		System.out.println(run + " cleared producers... " + components.size() + "/" + count.get());
+	}
+
+	@Override
+	public boolean registered() {
+		return count.get() == (COUNT*2) && components.size() == (COUNT*2);
+	}
+
+	@Override
+	public boolean unregistered() {
+		return count.get() == 0 && components.isEmpty();
+	}
+	
+	@Override
+	public String toString() {
+		return "Producers";
+	}
+
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/Activator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/Activator.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/Activator.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/Activator.java Tue May 28 20:38:13 2013
@@ -0,0 +1,28 @@
+package nl.uiterlinden.mtdmtest.aspect;
+import nl.uiterlinden.mtdmtest.base.Node;
+
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends DependencyActivatorBase {
+
+	private static DependencyManager manager;
+	
+	@Override
+	public void init(BundleContext context, DependencyManager manager)
+			throws Exception {
+		Activator.manager = manager;
+		manager.add(createComponent().setInterface(Node.class.getName(), null).setImplementation(NodeImpl.class));
+	}
+
+	@Override
+	public void destroy(BundleContext context, DependencyManager manager)
+			throws Exception {
+
+	}
+
+	public static DependencyManager dependencyManager() {
+		return manager;
+	}
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/NodeImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/NodeImpl.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/NodeImpl.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/NodeImpl.java Tue May 28 20:38:13 2013
@@ -0,0 +1,118 @@
+package nl.uiterlinden.mtdmtest.aspect;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import nl.uiterlinden.mtdmtest.base.Node;
+import nl.uiterlinden.mtdmtest.base.Producer;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+public class NodeImpl implements Node {
+
+	private static final int ASPECT_COUNT = Node.ASPECT_COUNT;
+	private List<Component> components = new ArrayList<Component>();
+	private AtomicInteger count = new AtomicInteger(0);
+	Executor executor = Executors.newFixedThreadPool(Node.THREADCOUNT);
+	
+	@Override
+	public void register(int run) {
+		// add and remove aspects
+		final DependencyManager manager = Activator.dependencyManager();
+		System.out.println(run + " Register aspects " + components.size() + "/" + count.get());
+		for (int i = 0; i < ASPECT_COUNT; i ++) {
+			final int n = i;
+			final int rank = i + 1000;
+			Runnable runnable = new Runnable() {
+				@Override
+				public void run() {
+					Component producerAspect = manager.createAspectService(Producer.class, null, rank).setImplementation(ProducerAspect.class)
+							.setCallbacks("init", "start", "stop", "destroy")
+							.add(manager.createServiceDependency().setService(Node.class).setRequired(true));
+					System.out.println("adding aspect: " + n);
+					manager.add(producerAspect);
+					synchronized(components) {
+						components.add(producerAspect);
+						count.incrementAndGet();
+					}
+//					Component producerWannabeAspect = manager.createAspectService(ProducerWannabe.class, null, rank).setImplementation(ProducerWannabeAspect.class);
+//					manager.add(producerWannabeAspect);
+//					components.add(producerWannabeAspect);
+//					if (components.size() % 5 == 0) {
+//						System.out.println("PA: " + components.size());
+//					}				
+				}
+			};
+			if (Node.THREADCOUNT > 1) {
+				executor.execute(runnable);
+			} else {
+				runnable.run();
+			}
+		}
+		while (count.get() < ASPECT_COUNT) {
+			try {
+				Thread.sleep(10);
+//				System.out.println("waiting for aspect launch.." + count.get());
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		System.out.println(run + " Registered aspects " + components.size() + "/" + count.get());
+	}
+
+	@Override
+	public void unregister(int run) {
+		// also multithreaded removal
+		final DependencyManager manager = Activator.dependencyManager();
+		System.out.println(run + " clearing aspects... " + components.size() + "/" + count.get());
+		
+		for (Component component : components) {
+			final Component componentToRemove = component;
+			Runnable runnable = new Runnable() {
+
+				@Override
+				public void run() {
+					manager.remove(componentToRemove);
+					count.decrementAndGet();
+				}
+			};
+			if (Node.THREADCOUNT > 1) {
+				executor.execute(runnable);
+			} else {
+				runnable.run();
+			}
+		}
+		while (count.get() > 0) {
+			try {
+				Thread.sleep(10);
+//				System.out.println("waiting for aspect cleanup.. " + count.get());
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		synchronized (components) {
+			components.clear();
+		}
+		System.out.println(run + " cleared aspects... " + components.size() + "/" + count.get());
+	}
+	
+	@Override
+	public boolean registered() {
+		return count.get() == ASPECT_COUNT && components.size() == ASPECT_COUNT;
+	}
+
+	@Override
+	public boolean unregistered() {
+		return count.get() == 0 && components.isEmpty();
+	}
+	
+	@Override
+	public String toString() {
+		return "Aspects";
+	}
+
+}
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/ProducerAspect.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/ProducerAspect.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/ProducerAspect.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/ProducerAspect.java Tue May 28 20:38:13 2013
@@ -0,0 +1,50 @@
+package nl.uiterlinden.mtdmtest.aspect;
+
+import nl.uiterlinden.mtdmtest.base.Node;
+import nl.uiterlinden.mtdmtest.base.Producer;
+
+public class ProducerAspect implements Producer {
+
+	private volatile Producer producer;
+	
+	private volatile Node node;
+	
+	boolean inited = false;
+	
+	@Override
+	public String getId() {
+		return producer.getId();
+	}
+	
+	private void init() {
+		inited = true;
+	}
+	
+	private void start() {
+		if (producer == null) {
+			System.err.println("Invalid start");
+			System.exit(0);
+		}
+		if (!inited) {
+			System.err.println("Invalid start, not inited");
+			System.exit(0);
+		}
+	}
+	
+	private void stop() {
+		if (producer == null) {
+			System.err.println("Invalid start");
+			System.exit(0);
+		}
+	}
+	
+	private void destroy() {
+		inited = false;
+	}
+
+	@Override
+	public void setVerbose(boolean verbose) {
+		// TODO Auto-generated method stub
+		
+	}
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/ProducerWannabeAspect.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/ProducerWannabeAspect.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/ProducerWannabeAspect.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/aspect/ProducerWannabeAspect.java Tue May 28 20:38:13 2013
@@ -0,0 +1,7 @@
+package nl.uiterlinden.mtdmtest.aspect;
+
+import nl.uiterlinden.mtdmtest.base.ProducerWannabe;
+
+public class ProducerWannabeAspect implements ProducerWannabe {
+
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/Activator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/Activator.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/Activator.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/Activator.java Tue May 28 20:38:13 2013
@@ -0,0 +1,28 @@
+package nl.uiterlinden.mtdmtest.b;
+import nl.uiterlinden.mtdmtest.base.Node;
+
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends DependencyActivatorBase {
+
+	private static DependencyManager manager;
+	
+	@Override
+	public void init(BundleContext context, DependencyManager manager)
+			throws Exception {
+		Activator.manager = manager;
+		manager.add(createComponent().setInterface(Node.class.getName(), null).setImplementation(NodeImpl.class));
+	}
+
+	@Override
+	public void destroy(BundleContext context, DependencyManager manager)
+			throws Exception {
+
+	}
+
+	public static DependencyManager dependencyManager() {
+		return manager;
+	}
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/NodeImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/NodeImpl.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/NodeImpl.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/NodeImpl.java Tue May 28 20:38:13 2013
@@ -0,0 +1,117 @@
+package nl.uiterlinden.mtdmtest.b;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import nl.uiterlinden.mtdmtest.base.Node;
+import nl.uiterlinden.mtdmtest.base.Producer;
+import nl.uiterlinden.mtdmtest.base.ProducerWannabe;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+public class NodeImpl implements Node {
+
+	private static final int ADAPTER_COUNT = 1;
+	private List<Component> components = new ArrayList<Component>();
+	private AtomicInteger count = new AtomicInteger(0);
+	Executor executor = Executors.newFixedThreadPool(Node.THREADCOUNT);
+	
+	@Override
+	public void register(int run) {
+		// add and remove aspects
+		final DependencyManager manager = Activator.dependencyManager();
+		System.out.println(run + " Registered adapters " + components.size() + "/" + count.get());
+		for (int i = 0; i < ADAPTER_COUNT; i ++) {
+			Runnable runnable = new Runnable() {
+				@Override
+				public void run() {
+					try {
+						Component adapter = manager.createAdapterService(ProducerWannabe.class, null)
+								.setInterface(Producer.class.getName(), null)
+								.setImplementation(ProducerWannabeAdapterImpl.class);
+						manager.add(adapter);
+						synchronized (components) {
+							components.add(adapter);
+						}
+						count.incrementAndGet();		
+					} catch (Exception e) {
+						e.printStackTrace();
+					}
+				}
+			};
+			if (Node.THREADCOUNT > 1) {
+				executor.execute(runnable);
+			} else {
+				runnable.run();
+			}
+		}
+		while (count.get() < ADAPTER_COUNT) {
+			try {
+				Thread.sleep(10);
+//				System.out.println("waiting for adapter launch.." + count.get());
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}	
+		System.out.println(run + " Registered adapters " + components.size() + "/" + count.get());
+	}
+
+	@Override
+	public void unregister(int run) {
+		// also multithreaded removal
+		final DependencyManager manager = Activator.dependencyManager();
+		System.out.println(run + " clearing adapters... " + components.size() + "/" + count.get());
+		int cnt = 0;
+		System.out.println("start unregister: " + components.size());
+		for (Component component : components) {
+			final Component componentToRemove = component;
+			final int pos = cnt ++;
+			Runnable runnable = new Runnable() {
+
+				@Override
+				public void run() {
+					try {
+						manager.remove(componentToRemove);
+						count.decrementAndGet();
+					} catch (Exception e) {
+						e.printStackTrace();
+					}
+				}
+			};
+			if (Node.THREADCOUNT > 1) {
+				executor.execute(runnable);
+			} else {
+				runnable.run();
+			}
+		}
+		while (count.get() > 0) {
+			try {
+				Thread.sleep(10);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+		}
+		synchronized (components) {
+			components.clear();
+		}
+		System.out.println(run + " cleared adapters... " + components.size() + "/" + count.get());
+	}
+	
+	@Override
+	public boolean registered() {
+		return count.get() == ADAPTER_COUNT && components.size() == ADAPTER_COUNT;
+	}
+
+	@Override
+	public boolean unregistered() {
+		return count.get() == 0 && components.isEmpty();
+	}
+	
+	@Override
+	public String toString() {
+		return "Adapters";
+	}
+}
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/ProducerWannabeAdapterImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/ProducerWannabeAdapterImpl.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/ProducerWannabeAdapterImpl.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/b/ProducerWannabeAdapterImpl.java Tue May 28 20:38:13 2013
@@ -0,0 +1,43 @@
+package nl.uiterlinden.mtdmtest.b;
+
+import nl.uiterlinden.mtdmtest.base.Producer;
+import nl.uiterlinden.mtdmtest.base.ProducerWannabe;
+
+public class ProducerWannabeAdapterImpl implements Producer {
+
+	ProducerWannabe producerWannabe;
+	boolean inited = false;
+
+	@Override
+	public String getId() {
+		return null;
+	}
+	
+	void init() {
+		if (producerWannabe == null) {
+			System.err.println("invalid start");
+			System.exit(0);
+		}
+		inited = true;
+	}
+	
+	void start() {
+		if (producerWannabe == null) {
+			System.err.println("invalid start");
+			System.exit(0);
+		}
+		if (!inited) {
+			System.out.println("ProducerWannabe not inited.");
+			System.exit(13);
+		}
+	}
+	
+	void destroy() {
+		inited = false;
+	}
+
+	@Override
+	public void setVerbose(boolean verbose) {
+		
+	}
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/InstanceProvider.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/InstanceProvider.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/InstanceProvider.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/InstanceProvider.java Tue May 28 20:38:13 2013
@@ -0,0 +1,6 @@
+package nl.uiterlinden.mtdmtest.base;
+
+public interface InstanceProvider {
+
+	boolean isValid();
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/InstanceProviderImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/InstanceProviderImpl.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/InstanceProviderImpl.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/InstanceProviderImpl.java Tue May 28 20:38:13 2013
@@ -0,0 +1,84 @@
+package nl.uiterlinden.mtdmtest.base;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.apache.felix.dm.ServiceDependency;
+
+public class InstanceProviderImpl implements InstanceProvider {
+
+	private final String id;
+	private ProducerWannabe wb;
+	private volatile DependencyManager manager;
+	private boolean started;
+	private boolean everSet = false;
+
+	public InstanceProviderImpl(String id) {
+		this.id = id;
+	}
+	
+	private void init(Component component) {
+		ServiceDependency dep = manager.createServiceDependency()
+				.setService(ProducerWannabe.class, "(producerwannabe.id=" + id + ")")
+				.setCallbacks("add", null, "remove", "swap")
+				.setRequired(true)
+				.setInstanceBound(true);
+//		dep.enableDebug("IP");
+		component.add(dep);
+	}
+
+	private void start() {
+		synchronized (this) {
+			if (wb == null) {
+				System.err.println("EARLY START");
+				System.exit(13);
+			}
+			started = true;
+		}
+	}
+
+	private void stop() {
+//		synchronized (this) {
+		System.out.println("instanceprovider stop " + Thread.currentThread().getId());
+//		Thread.dumpStack();
+			if (wb == null) {
+				System.err.println("EARLY STOP (instanceproviderimpl)");
+				System.exit(13);
+			}
+			started = false;
+//		}
+	}
+	
+	private void destroy() {
+		synchronized (this) {
+			System.out.println("destroy instanceproviderimpl");
+		}
+	}
+	
+	void add(ProducerWannabe wb) {
+		synchronized (this) {
+			everSet = true;
+			this.wb = wb;
+		}
+	}
+	
+	void swap(ProducerWannabe owb, ProducerWannabe nwb) {
+		synchronized (this) {
+			this.wb = nwb;
+		}
+	}
+	
+	void remove(ProducerWannabe wb) {
+		System.out.println("instanceprovider remove wb " + Thread.currentThread().getId());
+		synchronized (this) {
+			if (started) {
+				System.err.println("oops...");
+//				Thread.dumpStack();
+			}
+			this.wb = null;
+		}
+	}
+	
+	public boolean isValid() {
+		return (this.wb != null);
+	}
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/Node.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/Node.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/Node.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/Node.java Tue May 28 20:38:13 2013
@@ -0,0 +1,18 @@
+package nl.uiterlinden.mtdmtest.base;
+
+public interface Node {
+	
+	public final int THREADCOUNT = 40; //30;
+	
+	public final int PRODUCER_COUNT = 10;
+	
+	public final int ASPECT_COUNT = 3;
+
+	public void register(int run);
+	
+	public void unregister(int run);
+	
+	boolean registered();
+	
+	boolean unregistered();
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/Producer.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/Producer.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/Producer.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/Producer.java Tue May 28 20:38:13 2013
@@ -0,0 +1,8 @@
+package nl.uiterlinden.mtdmtest.base;
+
+public interface Producer {
+
+	String getId();
+	
+	void setVerbose(boolean verbose);
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerImpl.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerImpl.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerImpl.java Tue May 28 20:38:13 2013
@@ -0,0 +1,90 @@
+package nl.uiterlinden.mtdmtest.base;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+
+public class ProducerImpl implements Producer {
+
+	private final String id;
+	private volatile InstanceProvider instanceProvider;
+	private volatile DependencyManager manager;
+	private boolean verbose = false;
+	private boolean inited = false;
+
+	public ProducerImpl(String id) {
+		this.id = id;
+	}
+	
+	@Override
+	public String getId() {
+		return id;
+	}
+	
+	@Override
+	public String toString() {
+		return "producer " + id;
+	}
+	
+	void init(Component component) {
+		component.add(manager.createServiceDependency()
+				.setService(InstanceProvider.class, "(instanceprovider.id=" + id + ")")
+				.setRequired(true)
+				.setInstanceBound(true)
+				.setCallbacks("addIP", "removeIP"));
+		inited = true;
+	}
+	
+	void addIP(InstanceProvider ip) {
+		this.instanceProvider = ip;
+	}
+	
+	void removeIP(InstanceProvider ip) {
+		System.err.println("remove: " + Thread.currentThread().getId());
+		this.instanceProvider = null;
+	}
+	
+	void start() {
+		if (instanceProvider == null) {
+			System.err.println("Invalid start of ProducerImpl");
+			System.exit(13);
+		}
+//		if (!instanceProvider.isValid()) {
+//			System.err.println("Invalid instanceprovider PRODUCERIMPL (start)");
+//			System.exit(13);
+//		}
+		if (!inited) {
+			System.err.println("[start] Init has never been called in ProducerImpl");
+			System.exit(13);
+		}
+		if (verbose) {
+			System.out.println("producerImpl start " + id);
+		}
+	}
+	
+	void stop() {
+		System.err.println("stop: " + Thread.currentThread().getId());
+//		Thread.dumpStack();
+		if (instanceProvider == null) {
+			System.err.println("Invalid stop");
+			System.exit(13);
+		}
+//		if (!instanceProvider.isValid()) {
+//			System.err.println("Invalid instanceprovider in PRODUCERIMPL (stop)");
+//			System.exit(13);
+//		}
+		if (verbose) {
+			System.out.println("producer stop " + id);
+		}
+	}
+	
+	void destroy() {
+		System.out.println("producer destroy " + 1);
+		inited = false;
+	}
+	
+	public void setVerbose(boolean verbose) {
+		this.verbose = verbose;
+		
+	}
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerNoDeps.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerNoDeps.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerNoDeps.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerNoDeps.java Tue May 28 20:38:13 2013
@@ -0,0 +1,50 @@
+package nl.uiterlinden.mtdmtest.base;
+
+import org.apache.felix.dm.DependencyManager;
+
+
+public class ProducerNoDeps implements Producer {
+
+	private final String id;
+	private InstanceProvider instanceProvider;
+	private volatile DependencyManager manager;
+	private boolean verbose;
+	private boolean inited;
+
+	public ProducerNoDeps(String id) {
+		this.id = id;
+	}
+	
+	@Override
+	public String getId() {
+		return id;
+	}
+	
+	@Override
+	public String toString() {
+		return "producer " + id;
+	}
+
+	@Override
+	public void setVerbose(boolean verbose) {
+		this.verbose = verbose;
+	}
+
+	void init() {
+		System.out.println("init " + id);
+		inited = true;
+	}
+	
+	void start() {
+		System.out.println("start " + id);
+		if (!inited) {
+			System.err.println("Init has never been called");
+			System.exit(13);
+		}
+	}
+	
+	void destroy() {
+		System.out.println("destroy " + id);
+		inited = false;
+	}
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerWannabe.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerWannabe.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerWannabe.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerWannabe.java Tue May 28 20:38:13 2013
@@ -0,0 +1,5 @@
+package nl.uiterlinden.mtdmtest.base;
+
+public interface ProducerWannabe {
+
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerWannabeImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerWannabeImpl.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerWannabeImpl.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/ProducerWannabeImpl.java Tue May 28 20:38:13 2013
@@ -0,0 +1,6 @@
+package nl.uiterlinden.mtdmtest.base;
+
+
+public class ProducerWannabeImpl implements ProducerWannabe {
+
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/packageinfo
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/packageinfo?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/packageinfo (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/base/packageinfo Tue May 28 20:38:13 2013
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/A.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/A.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/A.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/A.java Tue May 28 20:38:13 2013
@@ -0,0 +1,45 @@
+package nl.uiterlinden.mtdmtest.deadlock;
+
+import java.util.Properties;
+
+import nl.uiterlinden.mtdmtest.base.Producer;
+import nl.uiterlinden.mtdmtest.base.ProducerImpl;
+import nl.uiterlinden.mtdmtest.base.ProducerNoDeps;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+public class A {
+	
+	private volatile Component component;
+	private volatile DependencyManager manager;
+
+	void init() {
+		System.out.println("init a");
+		// launch producer 2
+		Producer p2 = new ProducerNoDeps("2");
+		Properties props = new Properties();
+		props.setProperty("producer.id", p2.getId());
+		Component c = manager.createComponent().setImplementation(p2).setInterface(Producer.class.getName(), props);
+		manager.add(c);
+	}
+
+	void start() {
+		System.out.println("start a");
+	}
+	
+	void addProducer(Producer p) {
+		System.out.println(Thread.currentThread().getId() + " A add producer " + p + " lock on adep");
+		
+		// launch producer 3
+		if ("1".equals(p.getId())) {
+			System.out.println("launch p4");
+			Producer p4 = new ProducerNoDeps("4");
+			Properties props = new Properties();
+			props.setProperty("producer.id", p4.getId());
+			Component c = manager.createComponent().setImplementation(p4).setInterface(Producer.class.getName(), props);
+			manager.add(c);
+		}
+	}
+
+}
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/Activator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/Activator.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/Activator.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/Activator.java Tue May 28 20:38:13 2013
@@ -0,0 +1,123 @@
+package nl.uiterlinden.mtdmtest.deadlock;
+
+import java.util.Properties;
+
+import nl.uiterlinden.mtdmtest.base.Producer;
+import nl.uiterlinden.mtdmtest.base.ProducerNoDeps;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends DependencyActivatorBase {
+
+	@Override
+	public void init(BundleContext context, final DependencyManager manager)
+			throws Exception {
+		System.out.println("Activate");
+		Producer p = new ProducerNoDeps("1");
+		Properties props = new Properties();
+		props.setProperty("producer.id", p.getId());
+		Component c = createComponent().setImplementation(p).setInterface(Producer.class.getName(), props);
+		manager.add(c);
+		
+		Runnable ar = new Runnable() {
+
+			@Override
+			public void run() {
+				System.out.println("adding a");
+				Component a = manager.createComponent().setImplementation(A.class);
+				Dependency adep = createServiceDependency().setService(Producer.class, "(|(producer.id=1)(producer.id=3))").setCallbacks("addProducer", null, "removeProducer", "swapProducer");
+				a.add(adep);
+				manager.add(a);
+			}
+		};
+		
+		Runnable br = new Runnable() {
+
+			@Override
+			public void run() {
+				System.out.println("adding b");
+				Component b = manager.createComponent().setImplementation(B.class);
+				Dependency bdep = createServiceDependency().setService(Producer.class, "(|(producer.id=2)(producer.id=4))").setCallbacks("addProducer", null, "removeProducer", "swapProducer");
+				b.add(bdep);
+				manager.add(b);				
+			}
+		};
+		
+		new Thread(ar).start();
+		new Thread(br).start();
+		System.out.println("done");
+		
+		
+		// late injection test
+//		Component t = createComponent().setImplementation(this)
+//				.add(createServiceDependency().setService(Producer.class)
+//						.setCallbacks("addProducer", null, "removeProducer", "swapProducer")
+//						.setRequired(true));
+//		manager.add(t);
+//		System.out.println("Added component");
+//		final Producer p4 = new ProducerImpl("4");
+//		Properties p4props = new Properties();
+//		p4props.setProperty("producer.id", p4.getId());
+//		final Component cp4 = manager.createComponent().setImplementation(p4).setInterface(Producer.class.getName(), p4props);
+//		Runnable pStart = new Runnable() {
+//			@Override
+//			public void run() {
+//				System.out.println("add p4");
+//				manager.add(cp4);
+//			}
+//		};
+//		Runnable pStop = new Runnable() {
+//			@Override
+//			public void run() {
+//				try {
+//					Thread.sleep(1500);
+//				} catch (InterruptedException e) {
+//					e.printStackTrace();
+//				}
+//				System.out.println("remove p4");
+//				manager.remove(cp4);
+//			}
+//		};
+//		new Thread(pStart).start();
+//		new Thread(pStop).start();
+		
+	}
+
+	@Override
+	public void destroy(BundleContext context, DependencyManager manager)
+			throws Exception {
+
+	}
+	
+	Producer producer;
+	
+	void init() {
+		System.out.println("init: " + producer);
+	}
+	
+	void start() {
+		System.out.println("start");
+	}
+	
+	void stop() {
+		System.out.println("stop");
+	}
+	
+	void addProducer(Producer p) {
+		System.out.println("adding " + p);
+		this.producer = p;
+	}
+	
+	void swapProducer(Producer po, Producer pn) {
+		
+	}
+
+	void removeProducer(Producer p) {
+		System.out.println("removing " + p);
+		this.producer = null;
+	}
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/B.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/B.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/B.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/deadlock/B.java Tue May 28 20:38:13 2013
@@ -0,0 +1,38 @@
+package nl.uiterlinden.mtdmtest.deadlock;
+
+import java.util.Properties;
+
+import nl.uiterlinden.mtdmtest.base.Producer;
+import nl.uiterlinden.mtdmtest.base.ProducerNoDeps;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+
+public class B {
+
+	private volatile Component component;
+	private volatile DependencyManager manager;
+
+	void init() {
+		System.out.println("init b");
+	}
+
+	void start() {
+		System.out.println("start b");
+	}
+	
+	void addProducer(Producer p) {
+		System.out.println(Thread.currentThread().getId() + " B add producer " + p + " lock on bdep");
+		
+		// launch producer 3
+		if ("2".equals(p.getId())) {
+			System.out.println("launch p3");
+			Producer p3 = new ProducerNoDeps("3");
+			Properties props = new Properties();
+			props.setProperty("producer.id", p3.getId());
+			Component c = manager.createComponent().setImplementation(p3).setInterface(Producer.class.getName(), props);
+			manager.add(c);
+		}
+	}
+
+}
\ No newline at end of file

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Activator.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Activator.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Activator.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Activator.java Tue May 28 20:38:13 2013
@@ -0,0 +1,123 @@
+package nl.uiterlinden.mtdmtest.index;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import nl.uiterlinden.mtdmtest.base.Producer;
+import nl.uiterlinden.mtdmtest.base.ProducerImpl;
+
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.Dependency;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+
+public class Activator extends DependencyActivatorBase {
+
+	private static final int IRRELEVANT_COUNT = 2; // 00000;
+	private static final int PRODUCER_COUNT = 1; //00000;
+	
+	private int count;
+	
+	@Override
+	public void init(BundleContext context, DependencyManager manager)
+			throws Exception {
+		
+		List<Component> components = new ArrayList<Component>();
+		long start = System.currentTimeMillis();
+		// *adapter*;*aspect*;objectClass,x,y;objectClass,x,!z*
+		System.out.println("Using index config: " + System.getProperty("org.apache.felix.dependencymanager.filterindex"));
+		
+		// Launch lots of other irrelevant services
+		for (int i = 0; i < IRRELEVANT_COUNT; i++) {
+			Producer p = new ProducerImpl("" + i);
+			Properties props = new Properties();
+			props.setProperty("producer.id", p.getId());
+			props.setProperty("x", "aap & tijger");
+			props.setProperty("y", "mies");
+			Component component = createComponent().setInterface(Producer.class.getName(), props).setImplementation(p);
+			manager.add(component);
+			components.add(component);
+			
+			if ((i+1) % 100000 == 0) {
+				System.out.println("Added " + (i + 1) + " irrelevant producers.");
+			}
+		}
+		
+		// Launch lots of producers
+		for (int i = 0; i < PRODUCER_COUNT; i++) {
+			Producer p = new ProducerImpl("" + i);
+			Properties props = new Properties();
+			props.setProperty("producer.id", p.getId());
+			props.setProperty("x", "aap & tijger");
+			props.setProperty("y", "noot");
+			if (i % 10 == 0) {
+				props.setProperty("z", "mies");
+			}
+			Component component = createComponent().setInterface(Producer.class.getName(), props).setImplementation(p); 
+			manager.add(component);
+			components.add(component);
+			
+			if ((i+1) % 10000 == 0) {
+				System.out.println("Added " + (i + 1) + " producers.");
+			}
+		}
+		
+		// create a service dependency
+		Component component = createComponent().setImplementation(this);
+		Dependency dep = createServiceDependency().setService(Producer.class, "(&(x=aap & tijger)(y=noot))")
+				.setCallbacks("add", "remove").setRequired(true);
+		component.add(dep);
+		components.add(component);
+		
+		// create a service dependency 
+		Dependency dep2 = createServiceDependency().setService(Producer.class, "(&(x=aap & tijger)(y=noot)(!(z=*)))")
+				.setCallbacks("add", "remove").setRequired(true);
+		manager.add(component);
+		component.add(dep2);
+		
+		System.out.println("Removing components");
+		for (Component c : components) {
+			manager.remove(c);
+		}
+		
+		manager.clear();
+		
+		long duration = System.currentTimeMillis() - start;
+		System.out.println("Done in " + duration + "ms.");
+	}
+
+	@Override
+	public void destroy(BundleContext context, DependencyManager manager)
+			throws Exception {
+
+	}
+	
+	private void add() {
+		count ++;
+//		if (count % 10000 == 0) {
+			System.out.println("Injected " + count + " producers.");
+//		}
+	}
+
+	private void remove() {
+		count --;
+	}
+	
+	private void init() {
+		System.out.println("init..");
+	}
+	
+	private void start() {
+		System.out.println("start..");
+	}
+	
+	private void stop() {
+		System.out.println("stop..");
+	}
+	
+	private void destroy() {
+		System.out.println("destroy..");
+	}
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/AdvancedMultiPropertyFilterIndex.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/AdvancedMultiPropertyFilterIndex.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/AdvancedMultiPropertyFilterIndex.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/AdvancedMultiPropertyFilterIndex.java Tue May 28 20:38:13 2013
@@ -0,0 +1,457 @@
+package nl.uiterlinden.mtdmtest.index;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.felix.dm.FilterIndex;
+import org.apache.felix.dm.tracker.ServiceTracker;
+import org.apache.felix.dm.tracker.ServiceTrackerCustomizer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+public class AdvancedMultiPropertyFilterIndex implements FilterIndex, ServiceTrackerCustomizer {
+
+    private final Object m_lock = new Object();
+    private ServiceTracker m_tracker;
+    private BundleContext m_context;
+	private Map /* <String, Property> */ configProperties = new LinkedHashMap();
+	private List /* <String> */ negatePropertyKeys = new ArrayList();
+    private final Map /* <String, List<ServiceReference>> */ m_keyToServiceReferencesMap = new HashMap();
+    private final Map /* <String, List<ServiceListener>> */ m_keyToListenersMap = new HashMap();
+    private final Map /* <ServiceListener, String> */ m_listenerToFilterMap = new HashMap();
+
+	public AdvancedMultiPropertyFilterIndex(String configString) {
+		parseConfig(configString);
+	}
+	
+	public boolean isApplicable(String clazz, String filterString) {
+		Filter filter = createFilter(clazz, filterString);
+		
+		if (!filter.isValid()) {
+			return false;
+		}
+		// compare property keys to the ones in the configuration
+		Set /* <String> */ filterPropertyKeys = filter.getPropertyKeys();
+		if (configProperties.size() != filterPropertyKeys.size()) {
+			return false;
+		}
+		Iterator filterPropertyKeysIterator = filterPropertyKeys.iterator();
+		while (filterPropertyKeysIterator.hasNext()) {
+			String filterPropertyKey = (String) filterPropertyKeysIterator.next();
+			if (!configProperties.containsKey(filterPropertyKey)) {
+				return false;
+			} else if (((Property)configProperties.get(filterPropertyKey)).isNegate() != filter.getProperty(filterPropertyKey).isNegate()) {
+				// negation should be equal
+				return false;
+			} else if (!filter.getProperty(filterPropertyKey).isNegate() && filter.getProperty(filterPropertyKey).getValue().equals("*")) {
+				// no wildcards without negation allowed
+				return false;
+			}
+		}
+		// our properties match so we're applicable
+		return true;
+	}
+	
+    public boolean isApplicable(ServiceReference ref) {
+    	String[] propertyKeys = ref.getPropertyKeys();
+        TreeSet referenceProperties = new TreeSet(String.CASE_INSENSITIVE_ORDER);
+        for (int i = 0; i < propertyKeys.length; i++) {
+            referenceProperties.add(propertyKeys[i]);
+        }
+        Iterator iterator = configProperties.keySet().iterator();
+        while (iterator.hasNext()) {
+            String item = (String) iterator.next();
+            Property configProperty = (Property) configProperties.get(item);
+            if (!configProperty.isNegate() && !(referenceProperties.contains(item))) {
+                return false;
+            } else if (configProperty.isNegate() && referenceProperties.contains(item)) {
+            	return false;
+            }
+        }
+        return true;
+    }
+	
+	private void parseConfig(String configString) {
+		String[] propertyConfigs = configString.split(",");
+		for (int i = 0; i < propertyConfigs.length; i++) {
+			String propertyConfig = propertyConfigs[i];
+			Property property = new Property();
+			String key;
+			String value = null;
+			if (propertyConfig.startsWith("!")) {
+				property.setNegate(true);
+				key = propertyConfig.substring(1);
+			} else {
+				key = propertyConfig;
+			}
+			if (key.endsWith("*")) {
+				key = key.substring(0, key.indexOf("*"));
+				value = "*";
+			}
+			property.setKey(key.toLowerCase());
+			property.addValue(value);
+			configProperties.put(key.toLowerCase(), property);
+			if (property.isNegate()) {
+				negatePropertyKeys.add(key);
+			}
+		}
+	}
+	
+	protected Collection /* <Property> */ getProperties() {
+		return configProperties.values();
+	}
+	
+    protected String createKeyFromFilter(String clazz, String filterString) {
+    	return createFilter(clazz, filterString).createKey();
+    }
+    
+    private Filter createFilter(String clazz, String filterString) {
+		String filterStringWithObjectClass = filterString;
+		if (clazz != null) {
+			if (filterString != null) {
+				if (!filterStringWithObjectClass.startsWith("(&(objectClass=")) {
+					filterStringWithObjectClass = "(&(objectClass=" + clazz + ")" + filterString + ")";
+				}
+			} else {
+				filterStringWithObjectClass = "(objectClass=" + clazz + ")";
+			}
+		}
+		Filter filter = Filter.parse(filterStringWithObjectClass);
+		return filter;
+    }
+    
+    protected List createKeys(ServiceReference reference) {
+    	List /* <String> */ results = new ArrayList();
+    	List sets = new ArrayList();   	
+    	String[] keys = reference.getPropertyKeys();
+    	Arrays.sort(keys, String.CASE_INSENSITIVE_ORDER);
+    	for (int i = 0; i < keys.length; i++) {
+    		List set = new ArrayList();
+    		String key = keys[i].toLowerCase();
+    		if (configProperties.containsKey(key)) {
+	    		Object valueObject = reference.getProperty(key);
+	    		if (valueObject instanceof String[]) {
+	    			set.addAll(getPermutations(key, (String[]) valueObject));
+	    		} else {
+	    			set.add(toKey(key, valueObject));
+	    		}
+	    		sets.add(set);
+    		}
+    	}
+    	
+    	List reversedSets = new ArrayList();
+    	int size = sets.size();
+    	for (int i = size - 1; i > -1; i--) {
+    		reversedSets.add(sets.get(i));
+    	}
+    	List products = carthesianProduct(0, reversedSets);
+    	// convert sets into strings
+    	for (int i = 0; i < products.size(); i++) {
+    		List set = (List) products.get(i);
+    		StringBuilder b = new StringBuilder();
+    		for (int j = 0; j < set.size(); j++) {
+    			String item = (String) set.get(j);
+    			b.append(item);
+    			if (j < set.size() - 1) {
+    				b.append(";");
+    			}
+    		}
+    		results.add(b.toString());
+    	}
+    	
+    	return results;
+    }
+    
+    private List carthesianProduct(int index, List sets) {
+    	List result = new ArrayList();
+    	if (index == sets.size()) {
+    		result.add(new ArrayList());
+    	} else {
+			List set = (List) sets.get(index);
+			for (int i = 0; i < set.size(); i++) {
+				Object object = set.get(i);
+    			List pSets = carthesianProduct(index + 1, sets);
+    			for (int j = 0; j < pSets.size(); j++) {
+    				List pSet = (List) pSets.get(j);
+    				pSet.add(object);
+    				result.add(pSet);
+    			}
+    		}
+    	}
+    	return result;
+    }
+    
+    List getPermutations(String key, String[] values) {
+    	List results = new ArrayList();
+		Arrays.sort(values, String.CASE_INSENSITIVE_ORDER);
+		for (int v = 0; v < values.length; v++) {
+			String processValue = values[v];
+			List /* <String> */ items = new ArrayList();
+			items.add(processValue);
+			// per value get combinations
+			List /* <String> */ subItems = new ArrayList(items);
+			for (int w = v; w < values.length; w++) {
+				// make a copy of the current list
+				subItems = new ArrayList(subItems);
+				if (w != v) {
+					String value = values[w];
+					subItems.add(value);
+				}
+				results.add(toKey(key, subItems));
+			}
+		}
+		return results;
+    }
+    
+    protected String toKey(String key, List values) {
+    	StringBuilder builder = new StringBuilder();
+    	for (int i = 0; i < values.size(); i++) {
+    		builder.append(toKey(key, (String) values.get(i)));
+    		if (i < values.size() - 1) {
+    			builder.append(";");
+    		}
+    	}
+    	return builder.toString();
+    }
+    
+    protected String toKey(String key, Object value) {
+    	StringBuilder builder = new StringBuilder();
+    	builder.append(key);
+		builder.append("=");
+		builder.append(value.toString());
+		return builder.toString();
+    }
+    
+    public Object addingService(ServiceReference reference) {
+        BundleContext context;
+        synchronized (m_lock) {
+            context = m_context;
+        }
+        if (context != null) {
+            return context.getService(reference);
+        }
+        else {
+            throw new IllegalStateException("No valid bundle context.");
+        }
+    }
+
+    public void addedService(ServiceReference reference, Object service) {
+        if (isApplicable(reference) && shouldBeIndexed(reference)) {
+            handleServiceAdd(reference);
+        }
+    }
+
+    public void modifiedService(ServiceReference reference, Object service) {
+        if (isApplicable(reference)) {
+            handleServicePropertiesChange(reference);
+        }
+    }
+
+    public void removedService(ServiceReference reference, Object service) {
+        if (isApplicable(reference) && shouldBeIndexed(reference)) {
+            handleServiceRemove(reference);
+        }
+    }
+    
+    protected void handleServiceAdd(ServiceReference reference) {
+        List /* <String> */ keys = createKeys(reference);
+        synchronized (m_keyToServiceReferencesMap) {
+            for (int i = 0; i < keys.size(); i++) {
+                List /* <ServiceReference> */ references = (List) m_keyToServiceReferencesMap.get(keys.get(i));
+                if (references == null) {
+                    references = new ArrayList();
+                    m_keyToServiceReferencesMap.put(keys.get(i), references);
+                }
+                references.add(reference);
+            }
+        }
+    }
+
+    protected void handleServicePropertiesChange(ServiceReference reference) {
+        
+        synchronized (m_keyToServiceReferencesMap) {
+            // TODO this is a quite expensive linear scan over the existing collection
+            // because we first need to remove any existing references and they can be
+            // all over the place :)
+            Iterator iterator = m_keyToServiceReferencesMap.values().iterator();
+            while (iterator.hasNext()) {
+                List /* <ServiceReference> */ list = (List) iterator.next();
+                if (list != null) {
+                    Iterator i2 = list.iterator();
+                    while (i2.hasNext()) {
+                        ServiceReference ref = (ServiceReference) i2.next();
+                        if (ref.equals(reference)) {
+                            i2.remove();
+                        }
+                    }
+                }
+            }
+            // only re-add the reference when it is still applicable for this filter index
+            if (shouldBeIndexed(reference)) {
+            	List /* <String> */ keys = createKeys(reference);
+	            for (int i = 0; i < keys.size(); i++) {
+	                List /* <ServiceReference> */ references = (List) m_keyToServiceReferencesMap.get(keys.get(i));
+	                if (references == null) {
+	                    references = new ArrayList();
+	                    m_keyToServiceReferencesMap.put(keys.get(i), references);
+	                }
+	                references.add(reference);
+	            }
+            }
+        }
+    }
+
+    protected void handleServiceRemove(ServiceReference reference) {
+        List /* <String> */ keys = createKeys(reference);
+        synchronized (m_keyToServiceReferencesMap) {
+            for (int i = 0; i < keys.size(); i++) {
+                List /* <ServiceReference> */ references = (List) m_keyToServiceReferencesMap.get(keys.get(i));
+                if (references != null) {
+                    references.remove(reference);
+                    if (references.isEmpty()) {
+                    	m_keyToServiceReferencesMap.remove(keys.get(i));
+                    }
+                }
+            }
+        }
+    }
+    
+    protected boolean shouldBeIndexed(ServiceReference reference) {
+    	// is already applicable, so we should only check whether there's a negate field in the filter which has a value in the reference
+    	Iterator negatePropertyKeyIterator = negatePropertyKeys.iterator();
+    	while (negatePropertyKeyIterator.hasNext()) {
+    		String negatePropertyKey = (String) negatePropertyKeyIterator.next();
+    		if (reference.getProperty(negatePropertyKey) != null) {
+    			return false;
+    		}
+    	}
+    	return true;
+    }
+
+    public void open(BundleContext context) {
+        synchronized (m_lock) {
+            if (m_context != null) {
+                throw new IllegalStateException("Filter already open.");
+            }
+            try {
+                m_tracker = new ServiceTracker(context, context.createFilter("(" + Constants.OBJECTCLASS + "=*)"), this);
+            }
+            catch (InvalidSyntaxException e) {
+                throw new Error();
+            }
+            m_context = context;
+        }
+        m_tracker.open(true, true);
+    }
+
+	public void close() {
+        ServiceTracker tracker;
+        synchronized (m_lock) {
+            if (m_context == null) {
+                throw new IllegalStateException("Filter already closed.");
+            }
+            tracker = m_tracker;
+            m_tracker = null;
+            m_context = null;
+        }
+        tracker.close();
+	}
+
+    public List /* <ServiceReference> */ getAllServiceReferences(String clazz, String filter) {
+        List /* <ServiceReference> */ result = new ArrayList();
+        String key = createKeyFromFilter(clazz, filter);
+        ServiceReference reference;
+        synchronized (m_keyToServiceReferencesMap) {
+            List references = (List) m_keyToServiceReferencesMap.get(key);
+            if (references != null) {
+                result.addAll(references);
+            }
+        }
+        return result;
+    }
+
+    public void serviceChanged(ServiceEvent event) {
+        if (isApplicable(event.getServiceReference())) {
+            List /* <String> */ keys = createKeys(event.getServiceReference());
+            List list = new ArrayList();
+            synchronized (m_keyToListenersMap) {
+                for (int i = 0; i < keys.size(); i++) {
+                    String key = (String) keys.get(i);
+                    List listeners = (List) m_keyToListenersMap.get(key);
+                    if (listeners != null) {
+                        list.addAll(listeners);
+                    }
+                }
+            }
+            if (list != null) {
+                Iterator iterator = list.iterator();
+                while (iterator.hasNext()) {
+                    ServiceListener listener = (ServiceListener) iterator.next();
+                    listener.serviceChanged(event);
+                }
+            }
+        }
+    }
+
+    public void addServiceListener(ServiceListener listener, String filter) {
+        String key = createKeyFromFilter(null, filter);
+        synchronized (m_keyToListenersMap) {
+            List /* <ServiceListener> */ listeners = (List) m_keyToListenersMap.get(key);
+            if (listeners == null) {
+                listeners = new CopyOnWriteArrayList();
+                m_keyToListenersMap.put(key, listeners);
+            }
+            listeners.add(listener);
+            m_listenerToFilterMap.put(listener, filter);
+        }
+    }
+
+    public void removeServiceListener(ServiceListener listener) {
+        synchronized (m_keyToListenersMap) {
+            String filter = (String) m_listenerToFilterMap.remove(listener);
+            if (filter != null) {
+            	// the listener does exist
+        		String key = createKeyFromFilter(null, filter);
+        		
+        		boolean result = filter != null;
+        		if (result) {
+        			List /* <ServiceListener> */ listeners = (List) m_keyToListenersMap.get(key);
+        			if (listeners != null) {
+        				listeners.remove(listener);
+        				if (listeners.isEmpty()) {
+        					m_keyToListenersMap.remove(key);
+        				}
+        			}
+        			// TODO actually, if listeners == null that would be strange....
+        		}
+            }
+        }
+    }
+    
+    protected Collection getServiceListeners() {
+    	return m_listenerToFilterMap.keySet();
+    }
+    
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("MultiPropertyExactFilter[");
+        sb.append("K2L: " + m_keyToListenersMap.size());
+        sb.append(", K2SR: " + m_keyToServiceReferencesMap.size());
+        sb.append(", L2F: " + m_listenerToFilterMap.size());
+        sb.append("]");
+        return sb.toString();
+    }
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Filter.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Filter.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Filter.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Filter.java Tue May 28 20:38:13 2013
@@ -0,0 +1,116 @@
+package nl.uiterlinden.mtdmtest.index;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+public class Filter {
+	
+	private boolean valid = true;
+	private Map /* <String, Property> */ properties = new HashMap();
+	private Set /* <String> */ propertyKeys = new TreeSet(String.CASE_INSENSITIVE_ORDER);
+	
+	private Filter() {
+		
+	}
+	
+	// (&(objectClass=OBJECTCLASS)(&(model=MODEL)(concept=CONCEPT)(role=ROLE)(!(context=*))))
+	public static Filter parse(String filterString) {
+		Filter filter = new Filter();
+		StringTokenizer tokenizer = new StringTokenizer(filterString, "(&|=)", true);
+		
+		String token = null;
+		String prevToken = null;
+		String key = null;
+		StringBuilder valueBuilder = new StringBuilder();
+		boolean negate = false;
+
+		while (tokenizer.hasMoreTokens()) {
+			prevToken = token;
+			token = tokenizer.nextToken();
+			if (token.equals("|")) {
+				// we're not into OR's
+				filter.valid = false;
+				break;
+			}
+			if (token.equals("!")) {
+				negate = true;
+			} else if (token.equals("=")) {
+				key = prevToken.toLowerCase();
+			} else if (key != null) {
+				if (!token.equals(")")) {
+					valueBuilder.append(token); // might be superseded by a &
+				}
+				if (token.equals(")")) {
+					// set complete
+					if (filter.properties.containsKey(key)) {
+						// set current property to multivalue
+						Property property = (Property) filter.properties.get(key);
+						property.addValue(valueBuilder.toString());
+					} else {
+						Property property = new Property(negate, key, valueBuilder.toString());
+						filter.properties.put(key, property);
+						filter.propertyKeys.add(key);
+					}
+					negate = false;
+					key = null;
+					valueBuilder = new StringBuilder();
+				}
+			} 
+		}
+		return filter;
+	}
+	
+	public boolean containsProperty(String propertyKey) {
+		return properties.containsKey(propertyKey);
+	}
+	
+	public Set /* <String> */ getPropertyKeys() {
+		return properties.keySet();
+	}
+	
+	public Property getProperty(String key) {
+		return (Property) properties.get(key);
+	}
+	
+	public boolean isValid() {
+		return valid;
+	}
+	
+	public static void main(String args[]) {
+		Filter parser = Filter.parse("(&(objectClass=OBJECTCLASS)(&(a=x)(a=n)(a=y)(b=y)(c=z)))");
+		System.out.println("key: " + parser.createKey());
+	}
+
+	protected String createKey() {
+		StringBuilder builder = new StringBuilder();
+		Iterator keys = propertyKeys.iterator();
+		
+		while (keys.hasNext()) {
+			String key = (String) keys.next();
+			Property prop = (Property) properties.get(key);
+			if (!prop.isWildcard()) {
+				Iterator values = prop.getValues().iterator();
+				while (values.hasNext()) {
+					String value = (String) values.next();
+					builder.append(key);
+					builder.append("=");
+					builder.append(value);
+					if (keys.hasNext() || values.hasNext()) {
+						builder.append(";");
+					}
+				}
+			}
+		}
+		// strip the final ';' in case the last key was a wildcard property
+		if (builder.charAt(builder.length() - 1) == ';') {
+			return builder.toString().substring(0, builder.length() - 1);
+		} else {
+			return builder.toString();
+		}
+	}
+	
+}

Added: felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Property.java
URL: http://svn.apache.org/viewvc/felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Property.java?rev=1487106&view=auto
==============================================================================
--- felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Property.java (added)
+++ felix/sandbox/uiterlix/MTDMTest/src/nl/uiterlinden/mtdmtest/index/Property.java Tue May 28 20:38:13 2013
@@ -0,0 +1,66 @@
+package nl.uiterlinden.mtdmtest.index;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+class Property {
+	boolean negate;
+	String key;
+	String value;
+	Set values = new TreeSet(String.CASE_INSENSITIVE_ORDER);
+	
+	public Property() {
+	}
+	
+	public Property(boolean negate, String key, String value) {
+		super();
+		this.negate = negate;
+		this.key = key.toLowerCase();
+		this.values.add(value);
+		this.value = value;
+	}
+
+	public void setNegate(boolean negate) {
+		this.negate = negate;
+	}
+	
+	public void setKey(String key) {
+		this.key = key.toLowerCase();
+	}
+	
+	public void addValue(String value) {
+		if (this.value == null) {
+			this.value = value;
+		}
+		values.add(value);
+	}
+	
+	public boolean isNegate() {
+		return negate;
+	}
+	
+	public String getKey() {
+		return key;
+	}
+	
+	public String getValue() {
+		return value;
+	}
+	
+	public Set getValues() {
+		return values;
+	}
+	
+	public boolean isWildcard() {
+		return "*".equals(value);
+	}
+	
+	public boolean isMultiValue() {
+		return values.size() > 1;
+	}
+
+	public String toString() {
+		return "Property [negate=" + negate + ", key=" + key + ", values="
+				+ values + "]";
+	}
+}
\ No newline at end of file



Mime
View raw message