[maven-release-plugin]  copy for tag org.apache.aries.blueprint.noosgi-1.0.0

git-svn-id: https://svn.apache.org/repos/asf/aries/tags/org.apache.aries.blueprint.noosgi-1.0.0@1463436 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 6b0b127..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,203 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
-
diff --git a/NOTICE b/NOTICE
deleted file mode 100644
index 424644d..0000000
--- a/NOTICE
+++ /dev/null
@@ -1,8 +0,0 @@
-
-Apache Aries
-Copyright 2009-2011 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-
diff --git a/pom.xml b/pom.xml
index 33ac633..a6364ca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,35 +26,25 @@
     </parent>
 
     <groupId>org.apache.aries.blueprint</groupId>
-    <artifactId>org.apache.aries.blueprint.cm</artifactId>
-    <packaging>bundle</packaging>
-    <version>1.0.2-SNAPSHOT</version>
-    <name>Apache Aries Blueprint CM</name>
+    <artifactId>org.apache.aries.blueprint.noosgi</artifactId>
+    <packaging>jar</packaging>
+    <version>1.0.0</version>
+    <name>Apache Aries Blueprint no-OSGI</name>
     <description>
-        This bundle contains the ConfigAdmin namespace for blueprint.
+        This jar contains everything needed to run Blueprint outside OSGi.
     </description>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/aries/trunk/blueprint/blueprint-cm</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/aries/trunk/blueprint/blueprint-cm</developerConnection>
-        <url>http://svn.apache.org/viewvc/aries/trunk/blueprint/blueprint-cm</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/aries/tags/org.apache.aries.blueprint.noosgi-1.0.0</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/aries/tags/org.apache.aries.blueprint.noosgi-1.0.0</developerConnection>
+        <url>http://svn.apache.org/viewvc/aries/tags/org.apache.aries.blueprint.noosgi-1.0.0</url>
     </scm>
 
     <properties>
-        <!-- Export package versions are maintained in packageinfo files -->
-        <aries.osgi.export.pkg />
-        <aries.osgi.import.pkg>
-           org.apache.aries.blueprint;provide:=true;version="[1.0,1.2)",
-           org.apache.aries.blueprint.ext;provide:=true;version="[1.0,1.2)",
-           *
-        </aries.osgi.import.pkg>
-        <aries.osgi.private.pkg>
-            org.apache.aries.blueprint.compendium.cm
-        </aries.osgi.private.pkg>
-
         <blueprint.api.version>1.0.0</blueprint.api.version>
         <blueprint.core.version>1.0.0</blueprint.core.version>
         <blueprint.parser.version>1.0.0</blueprint.parser.version>
+        <proxy.impl.version>1.0.0</proxy.impl.version>
     </properties>
 
     <profiles>
@@ -66,6 +56,12 @@
                 <blueprint.parser.version>1.0.1-SNAPSHOT</blueprint.parser.version>
             </properties>
         </profile>
+        <profile>
+            <id>apache-release</id>
+            <properties>
+                <createSourcesJar>true</createSourcesJar>
+            </properties>
+        </profile>
     </profiles>
 
     <dependencies>
@@ -84,36 +80,30 @@
             <groupId>org.apache.aries.blueprint</groupId>
             <artifactId>org.apache.aries.blueprint.core</artifactId>
             <version>${blueprint.core.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.aries.quiesce</groupId>
+                    <artifactId>org.apache.aries.quiesce.api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.aries</groupId>
+                    <artifactId>org.apache.aries.util</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
+        <!--
         <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-            <scope>provided</scope>
+            <groupId>org.apache.aries.proxy</groupId>
+            <artifactId>org.apache.aries.proxy.impl</artifactId>
+            <version>${proxy.impl.version}</version>
         </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.compendium</artifactId>
-            <scope>provided</scope>
-            <version>4.1.0</version>
-        </dependency>
+        -->
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>com.googlecode.pojosr</groupId>
-            <artifactId>de.kalpatec.pojosr.framework</artifactId>
-            <version>0.1.6</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.ops4j.pax.swissbox</groupId>
-            <artifactId>pax-swissbox-tinybundles</artifactId>
-            <version>1.3.1</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <version>4.7</version>
@@ -131,34 +121,66 @@
             <version>1.5.11</version>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.aries.proxy</groupId>
-            <artifactId>org.apache.aries.proxy.impl</artifactId>
-            <version>1.0.0</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.felix</groupId>
-            <artifactId>org.apache.felix.configadmin</artifactId>
-            <version>1.2.8</version>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
     <build>
         <plugins>
             <plugin>
-                <groupId>org.apache.aries.versioning</groupId>
-                <artifactId>org.apache.aries.versioning.plugin</artifactId>
-                <version>0.1.0</version>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
                 <executions>
                     <execution>
-                        <id>default-verify</id>
-                        <phase>verify</phase>
+                        <phase>package</phase>
                         <goals>
-                            <goal>version-check</goal>
+                            <goal>shade</goal>
                         </goals>
                         <configuration>
-                            <oldArtifact>org.apache.aries.blueprint:org.apache.aries.blueprint.cm:1.0.1</oldArtifact>
+                            <filters>
+                                <filter>
+                                    <artifact>org.apache.aries.blueprint:org.apache.aries.blueprint.core</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/aries/blueprint/container/AbstractServiceReferenceRecipe*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/BlueprintContainerImpl*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/BlueprintEventDispatcher*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/BlueprintExtender*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/BlueprintQuiesceParticipant*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/BlueprintThreadFactory*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/GenericType*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/NamespaceHandlerRegistry*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/ParserServiceImpl*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/QuiesceInterceptor*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/ReferenceListRecipe*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/ReferenceRecipe*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/SatisfiableRecipe*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/container/ServiceRecipe*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder$LateBindingValueMetadata.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.class</exclude>
+                                        <!--
+                                        <exclude>org/apache/aries/blueprint/mutable/MutableReference*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/mutable/MutableRegistrationListener.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/mutable/MutableService*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/reflect/Reference*.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/reflect/Service*.class</exclude>
+                                        -->
+                                        <exclude>org/apache/aries/blueprint/services/ExtendedBlueprintContainer.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/namespace/**</exclude>
+                                        <!--
+                                          - Check if we can exclude proxy
+                                        <exclude>org/apache/aries/blueprint/proxy/**</exclude>
+                                        -->
+                                        <exclude>org/apache/aries/blueprint/utils/ServiceListener.class</exclude>
+                                        <exclude>org/apache/aries/blueprint/utils/threading/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.aries.proxy:org.apache.aries.proxy.api</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/aries/proxy/weavinghook/**</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
+                            <createSourcesJar>${createSourcesJar}</createSourcesJar>
+                            <promoteTransitiveDependencies>true</promoteTransitiveDependencies>
+                            <createDependencyReducedPom>true</createDependencyReducedPom>
                         </configuration>
                     </execution>
                 </executions>
diff --git a/src/main/appended-resources/META-INF/NOTICE.vm b/src/main/appended-resources/META-INF/NOTICE.vm
deleted file mode 100644
index 3e5ad36..0000000
--- a/src/main/appended-resources/META-INF/NOTICE.vm
+++ /dev/null
@@ -1,2 +0,0 @@
-This product includes software developed at
-the OSGi Alliance (http://www.osgi.org/).
\ No newline at end of file
diff --git a/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java b/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java
deleted file mode 100644
index 9393349..0000000
--- a/src/main/java/org/apache/aries/blueprint/compendium/cm/BaseManagedServiceFactory.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.util.Dictionary;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import org.apache.aries.blueprint.utils.JavaUtils;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedServiceFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class BaseManagedServiceFactory<T> implements ManagedServiceFactory {
-
-    public static final long DEFAULT_TIMEOUT_BEFORE_INTERRUPT = 30000;
-
-    public static final int CONFIGURATION_ADMIN_OBJECT_DELETED = 1;
-
-    public static final int BUNDLE_STOPPING = 2;
-
-    public static final int INTERNAL_ERROR = 4;
-
-    protected final Logger LOGGER = LoggerFactory.getLogger(getClass());
-
-    private final BundleContext context;
-    private final String name;
-    private final long timeoutBeforeInterrupt;
-    private final AtomicBoolean destroyed;
-    private final ExecutorService executor;
-    private final Map<String, Pair<T, ServiceRegistration>> services;
-    private final Map<ServiceRegistration, T> registrations;
-
-    public BaseManagedServiceFactory(BundleContext context, String name) {
-        this(context, name, DEFAULT_TIMEOUT_BEFORE_INTERRUPT);
-    }
-
-    public BaseManagedServiceFactory(BundleContext context, String name, long timeoutBeforeInterrupt) {
-        this.context = context;
-        this.name = name;
-        this.timeoutBeforeInterrupt = timeoutBeforeInterrupt;
-        this.destroyed = new AtomicBoolean(false);
-        this.executor = Executors.newSingleThreadExecutor();
-        this.services = new ConcurrentHashMap<String, Pair<T, ServiceRegistration>>();
-        this.registrations = new ConcurrentHashMap<ServiceRegistration, T>();
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public Map<ServiceRegistration, T> getServices() {
-        return registrations;
-    }
-
-    public void updated(final String pid, final Dictionary properties) throws ConfigurationException {
-        if (destroyed.get()) {
-            return;
-        }
-        checkConfiguration(pid, properties);
-        executor.submit(new Runnable() {
-            public void run() {
-                try {
-                    internalUpdate(pid, properties);
-                } catch (Throwable t) {
-                    LOGGER.warn("Error destroying service for ManagedServiceFactory " + getName(), t);
-                }
-            }
-        });
-    }
-
-    public void deleted(final String pid) {
-        if (destroyed.get()) {
-            return;
-        }
-        executor.submit(new Runnable() {
-            public void run() {
-                try {
-                    internalDelete(pid, CONFIGURATION_ADMIN_OBJECT_DELETED);
-                } catch (Throwable throwable) {
-                    LOGGER.warn("Error destroying service for ManagedServiceFactory " + getName(), throwable);
-                }
-            }
-        });
-    }
-
-    protected void checkConfiguration(String pid, Dictionary properties) throws ConfigurationException {
-        // Do nothing
-    }
-
-    protected abstract T doCreate(Dictionary properties) throws Exception;
-
-    protected abstract T doUpdate(T t, Dictionary properties) throws Exception;
-
-    protected abstract void doDestroy(T t, Dictionary properties, int code) throws Exception;
-
-    protected abstract String[] getExposedClasses(T t);
-
-    private void internalUpdate(String pid, Dictionary properties) {
-        Pair<T, ServiceRegistration> pair = services.get(pid);
-        if (pair != null) {
-            try {
-                T t = doUpdate(pair.getFirst(), properties);
-                pair.setFirst(t);
-                pair.getSecond().setProperties(properties);
-            } catch (Throwable throwable) {
-                internalDelete(pid, INTERNAL_ERROR);
-                LOGGER.warn("Error updating service for ManagedServiceFactory " + getName(), throwable);
-            }
-        } else {
-            if (destroyed.get()) {
-                return;
-            }
-            try {
-                T t = doCreate(properties);
-                try {
-                    if (destroyed.get()) {
-                        throw new IllegalStateException("ManagedServiceFactory has been destroyed");
-                    }
-                    ServiceRegistration registration = context.registerService(getExposedClasses(t), t, properties);
-                    services.put(pid, new Pair<T, ServiceRegistration>(t, registration));
-                    registrations.put(registration,  t);
-                    postRegister(t, properties, registration);
-                } catch (Throwable throwable1) {
-                    try {
-                        doDestroy(t, properties, INTERNAL_ERROR);
-                    } catch (Throwable throwable2) {
-                        // Ignore
-                    }
-                    throw throwable1;
-                }
-            } catch (Throwable throwable) {
-                LOGGER.warn("Error creating service for ManagedServiceFactory " + getName(), throwable);
-            }
-        }
-    }
-
-    protected void postRegister(T t, Dictionary properties, ServiceRegistration registration) {
-        // Place holder
-    }
-
-    protected void preUnregister(T t, Dictionary properties, ServiceRegistration registration) {
-        // Place holder
-    }
-
-    private void internalDelete(String pid, int code) {
-        Pair<T, ServiceRegistration> pair = services.remove(pid);
-        if (pair != null) {
-            registrations.remove(pair.getSecond());
-            Dictionary properties = JavaUtils.getProperties(pair.getSecond().getReference());
-            try {
-                preUnregister(pair.getFirst(), properties, pair.getSecond());
-                pair.getSecond().unregister();
-            } catch (Throwable t) {
-                LOGGER.info("Error unregistering service", t);
-            }
-            try {
-                doDestroy(pair.getFirst(), properties, code);
-            } catch (Throwable t) {
-                LOGGER.info("Error destroying service", t);
-            }
-        }
-    }
-
-    public void destroy() {
-        if (destroyed.compareAndSet(false, true)) {
-            executor.shutdown();
-            try {
-                executor.awaitTermination(timeoutBeforeInterrupt, TimeUnit.MILLISECONDS);
-            } catch (InterruptedException e) {
-                throw new RuntimeException("Shutdown interrupted");
-            }
-            if (!executor.isTerminated()) {
-                executor.shutdownNow();
-                try {
-                    executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
-                } catch (InterruptedException e) {
-                    throw new RuntimeException("Shutdown interrupted");
-                }
-            }
-
-            while (!services.isEmpty()) {
-                String pid = services.keySet().iterator().next();
-                internalDelete(pid, BUNDLE_STOPPING);
-            }
-        }
-    }
-
-    static class Pair<U,V> {
-        private U first;
-        private V second;
-        public Pair(U first, V second) {
-            this.first = first;
-            this.second = second;
-        }
-        public U getFirst() {
-            return first;
-        }
-        public V getSecond() {
-            return second;
-        }
-        public void setFirst(U first) {
-            this.first = first;
-        }
-        public void setSecond(V second) {
-            this.second = second;
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedProperties.java b/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedProperties.java
deleted file mode 100644
index 1622689..0000000
--- a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedProperties.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.apache.aries.blueprint.BeanProcessor;
-import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
-import org.apache.aries.blueprint.utils.ReflectionUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.service.blueprint.container.ReifiedType;
-import org.osgi.service.blueprint.reflect.BeanMetadata;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * TODO
- *
- * @version $Rev$, $Date$
- */
-public class CmManagedProperties implements ManagedObject, BeanProcessor {
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(CmManagedProperties.class);
-
-    private ExtendedBlueprintContainer blueprintContainer;
-    private ConfigurationAdmin configAdmin;
-    private ManagedObjectManager managedObjectManager;
-    private String persistentId;
-    private String updateStrategy;
-    private String updateMethod;
-    private String beanName;
-
-    private final Object lock = new Object();
-    private final Set<Object> beans = new HashSet<Object>();
-    private Dictionary<String,Object> properties;
-
-    public ExtendedBlueprintContainer getBlueprintContainer() {
-        return blueprintContainer;
-    }
-
-    public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
-        this.blueprintContainer = blueprintContainer;
-    }
-
-    public ConfigurationAdmin getConfigAdmin() {
-        return configAdmin;
-    }
-
-    public void setConfigAdmin(ConfigurationAdmin configAdmin) {
-        this.configAdmin = configAdmin;
-    }
-
-    public void setManagedObjectManager(ManagedObjectManager managedObjectManager) {
-        this.managedObjectManager = managedObjectManager;
-    }
-    
-    public ManagedObjectManager getManagedObjectManager() {
-        return managedObjectManager;
-    }
-    
-    public Bundle getBundle() {
-        return blueprintContainer.getBundleContext().getBundle();
-    }
-    
-    public String getPersistentId() {
-        return persistentId;
-    }
-
-    public void setPersistentId(String persistentId) {
-        this.persistentId = persistentId;
-    }
-
-    public String getUpdateStrategy() {
-        return updateStrategy;
-    }
-
-    public void setUpdateStrategy(String updateStrategy) {
-        this.updateStrategy = updateStrategy;
-    }
-
-    public String getUpdateMethod() {
-        return updateMethod;
-    }
-
-    public void setUpdateMethod(String updateMethod) {
-        this.updateMethod = updateMethod;
-    }
-
-    public String getBeanName() {
-        return beanName;
-    }
-
-    public void setBeanName(String beanName) {
-        this.beanName = beanName;
-    }
-    
-    public void init() throws Exception {
-        LOGGER.debug("Initializing CmManagedProperties for bean={} / pid={}", beanName, persistentId);
-        
-        Properties props = new Properties();
-        props.put(Constants.SERVICE_PID, persistentId);
-        Bundle bundle = blueprintContainer.getBundleContext().getBundle();
-        props.put(Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
-        props.put(Constants.BUNDLE_VERSION, bundle.getHeaders().get(Constants.BUNDLE_VERSION));
-                
-        synchronized (lock) {
-            managedObjectManager.register(this, props);
-            Configuration config = CmUtils.getConfiguration(configAdmin, persistentId);
-            if (config != null) {
-                properties = config.getProperties();
-            }
-        }
-    }
-
-    public void destroy() {
-        managedObjectManager.unregister(this);
-    }
-
-    public void updated(final Dictionary props) {
-        LOGGER.debug("Configuration updated for bean={} / pid={}", beanName, persistentId);
-        synchronized (lock) {
-            properties = props;
-            for (Object bean : beans) {
-                inject(bean, false);
-            }
-        }
-    }
-
-    public Object beforeInit(Object bean, String beanName, BeanCreator beanCreator, BeanMetadata beanData) {
-        if (beanName != null && beanName.equals(this.beanName)) {
-            LOGGER.debug("Adding bean for bean={} / pid={}", beanName, persistentId);
-            synchronized (lock) {
-                beans.add(bean);
-                inject(bean, true);
-            }
-        }
-        return bean;
-    }
-
-    public Object afterInit(Object bean, String beanName, BeanCreator beanCreator, BeanMetadata beanData) {
-        return bean;
-    }
-
-    public void beforeDestroy(Object bean, String beanName) {
-        if (beanName.equals(this.beanName)) {
-            LOGGER.debug("Removing bean for bean={} / pid={}", beanName, persistentId);
-            synchronized (lock) {
-                beans.remove(bean);
-            }
-        }
-    }
-
-    public void afterDestroy(Object bean, String beanName) {
-    }
-
-    private void inject(Object bean, boolean initial) {
-        LOGGER.debug("Injecting bean for bean={} / pid={}", beanName, persistentId);
-        LOGGER.debug("Configuration: {}", properties);
-        if (initial || "container-managed".equals(updateStrategy)) {
-            if (properties != null) {
-                for (Enumeration<String> e = properties.keys(); e.hasMoreElements();) {
-                    String key = e.nextElement();
-                    Object val = properties.get(key);
-                    String setterName = "set" + Character.toUpperCase(key.charAt(0));
-                    if (key.length() > 0) {
-                        setterName += key.substring(1);
-                    }
-                    Set<Method> validSetters = new LinkedHashSet<Method>();
-                    List<Method> methods = new ArrayList<Method>(Arrays.asList(bean.getClass().getMethods()));
-                    methods.addAll(Arrays.asList(bean.getClass().getDeclaredMethods()));
-                    for (Method method : methods) {
-                        if (method.getName().equals(setterName)) {
-                            if (method.getParameterTypes().length == 0) {
-                                LOGGER.debug("Setter takes no parameters: {}", method);
-                                continue;
-                            }
-                            if (method.getParameterTypes().length > 1) {
-                                LOGGER.debug("Setter takes more than one parameter: {}", method);
-                                continue;
-                            }
-                            if (method.getReturnType() != Void.TYPE) {
-                                LOGGER.debug("Setter returns a value: {}", method);
-                                continue;
-                            }
-                            if (Modifier.isAbstract(method.getModifiers())) {
-                                LOGGER.debug("Setter is abstract: {}", method);
-                                continue;
-                            }
-                            if (!Modifier.isPublic(method.getModifiers())) {
-                                LOGGER.debug("Setter is not public: {}", method);
-                                continue;
-                            }
-                            if (Modifier.isStatic(method.getModifiers())) {
-                                LOGGER.debug("Setter is static: {}", method);
-                                continue;
-                            }
-                            Class methodParameterType = method.getParameterTypes()[0];
-                            Object propertyValue;
-                            try {
-                                propertyValue = blueprintContainer.getConverter().convert(val, new ReifiedType(methodParameterType));
-                            } catch (Throwable t) {
-                                LOGGER.debug("Unable to convert value for setter: " + method, t);
-                                continue;
-                            }
-                            if (methodParameterType.isPrimitive() && propertyValue == null) {
-                                LOGGER.debug("Null can not be assigned to {}: {}", methodParameterType.getName(), method);
-                                continue;
-                            }
-                            if (validSetters.add(method)) {
-                                try {
-                                    method.invoke(bean, propertyValue);
-                                } catch (Exception t) {
-                                    LOGGER.debug("Setter can not be invoked: " + method, getRealCause(t));
-                                }
-                            }
-                        }
-                    }
-                    if (validSetters.isEmpty()) {
-                        LOGGER.debug("Unable to find a valid setter method for property {} and value {}", key, val);
-                    }
-                }
-            }
-        } else if ("component-managed".equals(updateStrategy) && updateMethod != null) {
-            List<Method> methods = ReflectionUtils.findCompatibleMethods(bean.getClass(), updateMethod, new Class[] { Map.class });
-            Map map = null;
-            if (properties != null) {
-                map = new HashMap();
-                for (Enumeration<String> e = properties.keys(); e.hasMoreElements();) {
-                    String key = e.nextElement();
-                    Object val = properties.get(key);
-                    map.put(key, val);
-                }
-            }
-            for (Method method : methods) {
-                try {
-                    method.invoke(bean, map);
-                } catch (Throwable t) {
-                    LOGGER.warn("Unable to call method " + method + " on bean " + beanName, getRealCause(t));
-                }
-            }
-        }
-    }
-
-    private static Throwable getRealCause(Throwable t) {
-        if (t instanceof InvocationTargetException && t.getCause() != null) {
-            return t.getCause();
-        }
-        return t;
-    }
-
-}
diff --git a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java b/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java
deleted file mode 100644
index 9600eca..0000000
--- a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmManagedServiceFactory.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.apache.aries.blueprint.BeanProcessor;
-import org.apache.aries.blueprint.ServiceProcessor;
-import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
-import org.apache.aries.blueprint.utils.JavaUtils;
-import org.apache.aries.blueprint.utils.ReflectionUtils;
-import org.apache.aries.blueprint.utils.ServiceListener;
-import org.apache.aries.util.AriesFrameworkUtil;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.blueprint.reflect.ServiceMetadata;
-import org.osgi.service.cm.ManagedServiceFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * TODO: if we need to make those exported services tied to their references as for other <service/> elements
- * TODO: it becomes a problem as currently we would have to create a specific recipe or something like that
- *
- * @version $Rev$, $Date$
- */
-public class CmManagedServiceFactory extends BaseManagedServiceFactory<Object> {
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(CmManagedServiceFactory.class);
-
-    private ExtendedBlueprintContainer blueprintContainer;
-    private String id;
-    private String factoryPid;
-    private List<String> interfaces;
-    private int autoExport;
-    private int ranking;
-    private Map<Object,Object> serviceProperties;
-    private String managedComponentName;
-    private String componentDestroyMethod;
-    private List<ServiceListener> listeners;
-
-    private ServiceRegistration registration;
-
-    public CmManagedServiceFactory(ExtendedBlueprintContainer blueprintContainer) {
-        super(blueprintContainer.getBundleContext(), null);
-        this.blueprintContainer = blueprintContainer;
-    }
-
-    public void init() throws Exception {
-        LOGGER.debug("Initializing CmManagedServiceFactory for factoryPid={}", factoryPid);
-        Properties props = new Properties();
-        props.put(Constants.SERVICE_PID, factoryPid);
-        Bundle bundle = blueprintContainer.getBundleContext().getBundle();
-        props.put(Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
-        props.put(Constants.BUNDLE_VERSION, bundle.getHeaders().get(Constants.BUNDLE_VERSION));
-
-        registration = blueprintContainer.getBundleContext().registerService(ManagedServiceFactory.class.getName(), this, props);
-    }
-
-    public void destroy() {
-        AriesFrameworkUtil.safeUnregisterService(registration);
-        super.destroy();
-    }
-
-    public Map<ServiceRegistration, Object> getServiceMap() {
-        return Collections.unmodifiableMap(getServices());
-    }
-
-    public void setListeners(List<ServiceListener> listeners) {
-        this.listeners = listeners;
-    }
-
-    public void setId(String id) {
-        this.id = id;
-    }
-
-    public void setFactoryPid(String factoryPid) {
-        this.factoryPid = factoryPid;
-    }
-
-    public void setInterfaces(List<String> interfaces) {
-        this.interfaces = interfaces;
-    }
-
-    public void setAutoExport(int autoExport) {
-        this.autoExport = autoExport;
-    }
-
-    public void setRanking(int ranking) {
-        this.ranking = ranking;
-    }
-
-    public void setServiceProperties(Map serviceProperties) {
-        this.serviceProperties = serviceProperties;
-    }
-
-    public void setManagedComponentName(String managedComponentName) {
-        this.managedComponentName = managedComponentName;
-    }
-
-    public void setComponentDestroyMethod(String componentDestroyMethod) {
-        this.componentDestroyMethod = componentDestroyMethod;
-    }
-
-    private void getRegistrationProperties(Dictionary properties, boolean update) {
-        String pid = (String) properties.get(Constants.SERVICE_PID);
-        CmProperties cm = findServiceProcessor();
-        if (cm == null) {
-            while (!properties.isEmpty()) {
-                properties.remove(properties.keys().nextElement());
-            }
-        } else  {
-            if (!cm.getUpdate()) {
-                if (update) {
-                    while (!properties.isEmpty()) {
-                        properties.remove(properties.keys().nextElement());
-                    }
-                    for (Map.Entry entry : cm.getProperties().entrySet()) {
-                        properties.put(entry.getKey(), entry.getValue());
-                    }
-                } else {
-                    cm.updated(properties);
-                }
-            }
-        }
-        if (serviceProperties != null) {
-            for (Map.Entry entry : serviceProperties.entrySet()) {
-                properties.put(entry.getKey(), entry.getValue());
-            }
-        }
-        properties.put(Constants.SERVICE_RANKING, ranking);
-        properties.put(Constants.SERVICE_PID, pid);
-    }
-
-    private void updateComponentProperties(Dictionary props) {
-        CmManagedProperties cm = findBeanProcessor();
-        if (cm != null) {
-            cm.updated(props);
-        }
-    }
-
-    private CmManagedProperties findBeanProcessor() {
-        for (BeanProcessor beanProcessor : blueprintContainer.getProcessors(BeanProcessor.class)) {
-            if (beanProcessor instanceof CmManagedProperties) {
-                CmManagedProperties cm = (CmManagedProperties) beanProcessor;
-                if (managedComponentName.equals(cm.getBeanName()) && "".equals(cm.getPersistentId())) {
-                    return cm;
-                }
-            }
-        }
-        return null;
-    }
-
-    private CmProperties findServiceProcessor() {
-        for (ServiceProcessor processor : blueprintContainer.getProcessors(ServiceProcessor.class)) {
-            if (processor instanceof CmProperties) {
-                CmProperties cm = (CmProperties) processor;
-                if (id.equals(cm.getServiceId())) {
-                    return cm;
-                }
-            }
-        }
-        return null;
-    }
-
-    private Method findDestroyMethod(Class clazz) {
-        Method method = null;
-        if (componentDestroyMethod != null && componentDestroyMethod.length() > 0) {
-            List<Method> methods = ReflectionUtils.findCompatibleMethods(clazz, componentDestroyMethod, new Class [] { int.class });
-            if (methods != null && !methods.isEmpty()) {
-                method = methods.get(0);
-            }
-        }
-        return method;
-    }
-
-    protected Object doCreate(Dictionary properties) throws Exception {
-        updateComponentProperties(copy(properties));
-        Object component = blueprintContainer.getComponentInstance(managedComponentName);
-        getRegistrationProperties(properties, false);
-        return component;
-    }
-
-    protected Object doUpdate(Object service, Dictionary properties) throws Exception {
-        updateComponentProperties(copy(properties));
-        getRegistrationProperties(properties, true);
-        return service;
-    }
-
-    protected void doDestroy(Object service, Dictionary properties, int code) throws Exception {
-        Method method = findDestroyMethod(service.getClass());
-        if (method != null) {
-            try {
-                method.invoke(service, new Object [] { code });
-            } catch (Exception e) {
-                LOGGER.info("Error destroying component", e);
-            }
-        }
-    }
-
-    protected void postRegister(Object service, Dictionary properties, ServiceRegistration registration) {
-        if (listeners != null && !listeners.isEmpty()) {
-            Hashtable props = new Hashtable();
-            JavaUtils.copy(properties, props);
-            for (ServiceListener listener : listeners) {
-                listener.register(service, props);
-            }
-        }
-    }
-
-    protected void preUnregister(Object service, Dictionary properties, ServiceRegistration registration) {
-        if (listeners != null && !listeners.isEmpty()) {
-            Hashtable props = new Hashtable();
-            JavaUtils.copy(properties, props);
-            for (ServiceListener listener : listeners) {
-                listener.unregister(service, props);
-            }
-        }
-    }
-
-    protected String[] getExposedClasses(Object service) {
-        Class serviceClass = service.getClass();
-        Set<String> classes;
-        switch (autoExport) {
-            case ServiceMetadata.AUTO_EXPORT_INTERFACES:
-                classes = ReflectionUtils.getImplementedInterfaces(new HashSet<String>(), serviceClass);
-                break;
-            case ServiceMetadata.AUTO_EXPORT_CLASS_HIERARCHY:
-                classes = ReflectionUtils.getSuperClasses(new HashSet<String>(), serviceClass);
-                break;
-            case ServiceMetadata.AUTO_EXPORT_ALL_CLASSES:
-                classes = ReflectionUtils.getSuperClasses(new HashSet<String>(), serviceClass);
-                classes = ReflectionUtils.getImplementedInterfaces(classes, serviceClass);
-                break;
-            default:
-                classes = new HashSet<String>(interfaces);
-                break;
-        }
-        return classes.toArray(new String[classes.size()]);
-    }
-
-    private Hashtable copy(Dictionary source) {
-        Hashtable ht = new Hashtable();
-        JavaUtils.copy(ht, source);
-        return ht;
-    }
-
-}
diff --git a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java b/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
deleted file mode 100644
index 34e2909..0000000
--- a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmNamespaceHandler.java
+++ /dev/null
@@ -1,645 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-
-import org.apache.aries.blueprint.ComponentDefinitionRegistry;
-import org.apache.aries.blueprint.NamespaceHandler;
-import org.apache.aries.blueprint.ParserContext;
-import org.apache.aries.blueprint.ext.PlaceholdersUtils;
-import org.apache.aries.blueprint.mutable.MutableBeanMetadata;
-import org.apache.aries.blueprint.mutable.MutableCollectionMetadata;
-import org.apache.aries.blueprint.mutable.MutableComponentMetadata;
-import org.apache.aries.blueprint.mutable.MutableIdRefMetadata;
-import org.apache.aries.blueprint.mutable.MutableMapMetadata;
-import org.apache.aries.blueprint.mutable.MutableRefMetadata;
-import org.apache.aries.blueprint.mutable.MutableReferenceMetadata;
-import org.apache.aries.blueprint.mutable.MutableValueMetadata;
-import org.apache.aries.blueprint.utils.ServiceListener;
-import org.osgi.service.blueprint.container.ComponentDefinitionException;
-import org.osgi.service.blueprint.reflect.BeanMetadata;
-import org.osgi.service.blueprint.reflect.BeanProperty;
-import org.osgi.service.blueprint.reflect.CollectionMetadata;
-import org.osgi.service.blueprint.reflect.ComponentMetadata;
-import org.osgi.service.blueprint.reflect.IdRefMetadata;
-import org.osgi.service.blueprint.reflect.MapMetadata;
-import org.osgi.service.blueprint.reflect.Metadata;
-import org.osgi.service.blueprint.reflect.RefMetadata;
-import org.osgi.service.blueprint.reflect.ReferenceMetadata;
-import org.osgi.service.blueprint.reflect.RegistrationListener;
-import org.osgi.service.blueprint.reflect.ServiceMetadata;
-import org.osgi.service.blueprint.reflect.ValueMetadata;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.CharacterData;
-import org.w3c.dom.Comment;
-import org.w3c.dom.Element;
-import org.w3c.dom.EntityReference;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-/**
- * Namespace handler for the Config Admin service.
- * This handler will parse the various elements defined and populate / modify the registry
- * accordingly.
- *
- * @see CmManagedProperties
- * @see CmManagedServiceFactory
- * @see CmProperties
- * @see CmPropertyPlaceholder
- *
- * @version $Rev$, $Date$
- */
-public class CmNamespaceHandler implements NamespaceHandler {
-
-    public static final String BLUEPRINT_NAMESPACE = "http://www.osgi.org/xmlns/blueprint/v1.0.0";
-    public static final String BLUEPRINT_CM_NAMESPACE_1_0 = "http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0";
-    public static final String BLUEPRINT_CM_NAMESPACE_1_1 = "http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0";
-    public static final String BLUEPRINT_CM_NAMESPACE_1_2 = "http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0";
-    public static final String BLUEPRINT_EXT_NAMESPACE_V1_0 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0";
-    public static final String BLUEPRINT_EXT_NAMESPACE_V1_1 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.1.0";
-    public static final String BLUEPRINT_EXT_NAMESPACE_V1_2 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0";
-    
-    public static final String PROPERTY_PLACEHOLDER_ELEMENT = "property-placeholder";
-    public static final String MANAGED_PROPERTIES_ELEMENT = "managed-properties";
-    public static final String MANAGED_SERVICE_FACTORY_ELEMENT = "managed-service-factory";
-    public static final String CM_PROPERTIES_ELEMENT = "cm-properties";
-    public static final String DEFAULT_PROPERTIES_ELEMENT = "default-properties";
-    public static final String PROPERTY_ELEMENT = "property";
-    public static final String INTERFACES_ELEMENT = "interfaces";
-    public static final String VALUE_ELEMENT = "value";
-    public static final String MANAGED_COMPONENT_ELEMENT = "managed-component";
-    public static final String LOCATION_ELEMENT = "location";
-    public static final String SERVICE_PROPERTIES_ELEMENT = "service-properties";
-    public static final String REGISTRATION_LISTENER_ELEMENT = "registration-listener";
-
-    public static final String ID_ATTRIBUTE = "id";
-    public static final String SYSTEM_PROPERTIES_NEVER = "never";
-    public static final String PERSISTENT_ID_ATTRIBUTE = "persistent-id";
-    public static final String PLACEHOLDER_PREFIX_ATTRIBUTE = "placeholder-prefix";
-    public static final String PLACEHOLDER_SUFFIX_ATTRIBUTE = "placeholder-suffix";
-    public static final String DEFAULTS_REF_ATTRIBUTE = "defaults-ref";
-    public static final String UPDATE_STRATEGY_ATTRIBUTE = "update-strategy";
-    public static final String UPDATE_METHOD_ATTRIBUTE = "update-method";
-    public static final String FACTORY_PID_ATTRIBUTE = "factory-pid";
-    public static final String AUTO_EXPORT_ATTRIBUTE = "auto-export";
-    public static final String RANKING_ATTRIBUTE = "ranking";
-    public static final String INTERFACE_ATTRIBUTE = "interface";
-    public static final String UPDATE_ATTRIBUTE = "update";
-    public static final String SYSTEM_PROPERTIES_ATTRIBUTE = "system-properties";
-    public static final String IGNORE_MISSING_LOCATIONS_ATTRIBUTE = "ignore-missing-locations";
-
-    public static final String AUTO_EXPORT_DISABLED = "disabled";
-    public static final String AUTO_EXPORT_INTERFACES = "interfaces";
-    public static final String AUTO_EXPORT_CLASS_HIERARCHY = "class-hierarchy";
-    public static final String AUTO_EXPORT_ALL = "all-classes";
-    public static final String AUTO_EXPORT_DEFAULT = AUTO_EXPORT_DISABLED;
-    public static final String RANKING_DEFAULT = "0";
-
-    private static final String MANAGED_OBJECT_MANAGER_NAME = "org.apache.aries.managedObjectManager";
-    
-    private static final Logger LOGGER = LoggerFactory.getLogger(CmNamespaceHandler.class);
-
-    // This property is static but it should be ok since there will be only a single instance
-    // of this class for the bundle
-    private static ConfigurationAdmin configAdmin;
-
-    private int idCounter;
-
-    public int getIdCounter() {
-        return idCounter;
-    }
-
-    public void setIdCounter(int idCounter) {
-        this.idCounter = idCounter;
-    }
-
-    public static ConfigurationAdmin getConfigAdmin() {
-        return configAdmin;
-    }
-
-    public void setConfigAdmin(ConfigurationAdmin configAdmin) {
-        this.configAdmin = configAdmin;
-    }
-
-    public URL getSchemaLocation(String namespace) {
-        if (BLUEPRINT_CM_NAMESPACE_1_2.equals(namespace)) {
-            return getClass().getResource("blueprint-cm-1.2.0.xsd");
-        } else if (BLUEPRINT_CM_NAMESPACE_1_1.equals(namespace)) {
-            return getClass().getResource("blueprint-cm-1.1.0.xsd");
-        } else if (BLUEPRINT_CM_NAMESPACE_1_0.equals(namespace)) {
-            return getClass().getResource("blueprint-cm-1.0.0.xsd");
-        } else {
-            return null;
-        }
-    }
-
-    public Set<Class> getManagedClasses() {
-        return new HashSet<Class>(Arrays.asList(
-                CmPropertyPlaceholder.class,
-                CmManagedServiceFactory.class,
-                CmManagedProperties.class,
-                CmProperties.class
-        ));
-    }
-
-    public Metadata parse(Element element, ParserContext context) {
-        LOGGER.debug("Parsing element {{}}{}", element.getNamespaceURI(), element.getLocalName());
-        ComponentDefinitionRegistry registry = context.getComponentDefinitionRegistry();
-        registerManagedObjectManager(context, registry);
-        if (nodeNameEquals(element, PROPERTY_PLACEHOLDER_ELEMENT)) {
-            return parsePropertyPlaceholder(context, element);
-        } else if (nodeNameEquals(element, MANAGED_SERVICE_FACTORY_ELEMENT)) {
-            return parseManagedServiceFactory(context, element);
-        } else if (nodeNameEquals(element, CM_PROPERTIES_ELEMENT)) {
-            return parseCmProperties(context, element);
-        } else {
-            throw new ComponentDefinitionException("Unsupported element: " + element.getNodeName());
-        }
-    }
-
-    public ComponentMetadata decorate(Node node, ComponentMetadata component, ParserContext context) {
-        LOGGER.debug("Decorating node {{}}{}", node.getNamespaceURI(), node.getLocalName());
-        ComponentDefinitionRegistry registry = context.getComponentDefinitionRegistry();
-        registerManagedObjectManager(context, registry);
-        if (node instanceof Element) {
-            if (nodeNameEquals(node, MANAGED_PROPERTIES_ELEMENT)) {
-                return decorateManagedProperties(context, (Element) node, component);
-            } else if (nodeNameEquals(node, CM_PROPERTIES_ELEMENT)) {
-                return decorateCmProperties(context, (Element) node, component);
-            } else {
-                throw new ComponentDefinitionException("Unsupported element: " + node.getNodeName());
-            }
-        } else {
-            throw new ComponentDefinitionException("Illegal use of blueprint cm namespace");
-        }
-    }
-
-    private ComponentMetadata parseCmProperties(ParserContext context, Element element) {
-        String id = getId(context, element);
-
-        MutableBeanMetadata factoryMetadata = context.createMetadata(MutableBeanMetadata.class);
-        generateIdIfNeeded(context, factoryMetadata);
-        factoryMetadata.setScope(BeanMetadata.SCOPE_SINGLETON);
-        factoryMetadata.setRuntimeClass(CmProperties.class);
-        factoryMetadata.setInitMethod("init");
-        factoryMetadata.setDestroyMethod("destroy");
-        factoryMetadata.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
-        factoryMetadata.addProperty("configAdmin", createConfigurationAdminRef(context));
-        factoryMetadata.addProperty("managedObjectManager", createRef(context, MANAGED_OBJECT_MANAGER_NAME));
-        String persistentId = element.getAttribute(PERSISTENT_ID_ATTRIBUTE);
-        factoryMetadata.addProperty("persistentId", createValue(context, persistentId));
-        context.getComponentDefinitionRegistry().registerComponentDefinition(factoryMetadata);
-
-        MutableBeanMetadata propertiesMetadata = context.createMetadata(MutableBeanMetadata.class);
-        propertiesMetadata.setId(id);
-        propertiesMetadata.setScope(BeanMetadata.SCOPE_SINGLETON);
-        propertiesMetadata.setRuntimeClass(Properties.class);
-        propertiesMetadata.setFactoryComponent(createRef(context, factoryMetadata.getId()));
-        propertiesMetadata.setFactoryComponent(factoryMetadata);
-        propertiesMetadata.setFactoryMethod("getProperties");
-        // Work around ARIES-877
-        propertiesMetadata.setDependsOn(Arrays.asList(factoryMetadata.getId()));
-
-        return propertiesMetadata;
-    }
-
-    private ComponentMetadata parsePropertyPlaceholder(ParserContext context, Element element) {
-        MutableBeanMetadata metadata = context.createMetadata(MutableBeanMetadata.class);
-        metadata.setProcessor(true);
-        metadata.setId(getId(context, element));
-        metadata.setScope(BeanMetadata.SCOPE_SINGLETON);
-        metadata.setRuntimeClass(CmPropertyPlaceholder.class);
-        metadata.setInitMethod("init");
-        metadata.setDestroyMethod("destroy");
-        metadata.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
-        metadata.addProperty("configAdmin", createConfigurationAdminRef(context));
-        metadata.addProperty("persistentId", createValue(context, element.getAttribute(PERSISTENT_ID_ATTRIBUTE)));
-        String prefix = element.hasAttribute(PLACEHOLDER_PREFIX_ATTRIBUTE)
-                                    ? element.getAttribute(PLACEHOLDER_PREFIX_ATTRIBUTE)
-                                    : "${";
-        metadata.addProperty("placeholderPrefix", createValue(context, prefix));
-        String suffix = element.hasAttribute(PLACEHOLDER_SUFFIX_ATTRIBUTE)
-                                    ? element.getAttribute(PLACEHOLDER_SUFFIX_ATTRIBUTE)
-                                    : "}";
-        metadata.addProperty("placeholderSuffix", createValue(context, suffix));
-        String defaultsRef = element.hasAttribute(DEFAULTS_REF_ATTRIBUTE) ? element.getAttribute(DEFAULTS_REF_ATTRIBUTE) : null;
-        if (defaultsRef != null) {
-            metadata.addProperty("defaultProperties", createRef(context, defaultsRef));
-        }
-        String ignoreMissingLocations = extractIgnoreMissingLocations(element);
-        if (ignoreMissingLocations != null) {
-            metadata.addProperty("ignoreMissingLocations", createValue(context, ignoreMissingLocations));
-        }
-        String systemProperties = extractSystemPropertiesAttribute(element);
-        if (systemProperties == null) {
-            systemProperties = SYSTEM_PROPERTIES_NEVER;
-        }
-        metadata.addProperty("systemProperties", createValue(context, systemProperties));
-        String updateStrategy = element.getAttribute(UPDATE_STRATEGY_ATTRIBUTE);
-        if (updateStrategy != null) {
-            metadata.addProperty("updateStrategy", createValue(context, updateStrategy));
-        }
-        metadata.addProperty("managedObjectManager", createRef(context, MANAGED_OBJECT_MANAGER_NAME));
-        // Parse elements
-        List<String> locations = new ArrayList<String>();
-        NodeList nl = element.getChildNodes();
-        for (int i = 0; i < nl.getLength(); i++) {
-            Node node = nl.item(i);
-            if (node instanceof Element) {
-                Element e = (Element) node;
-                if (isCmNamespace(e.getNamespaceURI())) {
-                    if (nodeNameEquals(e, DEFAULT_PROPERTIES_ELEMENT)) {
-                        if (defaultsRef != null) {
-                            throw new ComponentDefinitionException("Only one of " + DEFAULTS_REF_ATTRIBUTE + " attribute or " + DEFAULT_PROPERTIES_ELEMENT + " element is allowed");
-                        }
-                        Metadata props = parseDefaultProperties(context, metadata, e);
-                        metadata.addProperty("defaultProperties", props);
-                    }
-                } else if (isExtNamespace(e.getNamespaceURI())) {
-                    if (nodeNameEquals(e, LOCATION_ELEMENT)) {
-                        locations.add(getTextValue(e));
-                    }
-                } 
-            }
-        }
-        if (!locations.isEmpty()) {
-            metadata.addProperty("locations", createList(context, locations));
-        }
-
-        PlaceholdersUtils.validatePlaceholder(metadata, context.getComponentDefinitionRegistry());
-        
-        return metadata;
-    }
-
-    private String extractSystemPropertiesAttribute(Element element) {
-      String systemProperties = null;
-      
-      if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_0, SYSTEM_PROPERTIES_ATTRIBUTE)) {
-        systemProperties =  element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_0, SYSTEM_PROPERTIES_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_1, SYSTEM_PROPERTIES_ATTRIBUTE)) {
-        systemProperties =  element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_1, SYSTEM_PROPERTIES_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_2, SYSTEM_PROPERTIES_ATTRIBUTE)) {
-        systemProperties =  element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_2, SYSTEM_PROPERTIES_ATTRIBUTE);
-      }
-      return systemProperties;
-    }
-
-    private String extractIgnoreMissingLocations(Element element) {
-      String ignoreMissingLocations = null;
-      if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_0, IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
-        ignoreMissingLocations = element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_0, IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_1, IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
-        ignoreMissingLocations = element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_1, IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
-      } else if (element.hasAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_2, IGNORE_MISSING_LOCATIONS_ATTRIBUTE)) {
-        ignoreMissingLocations = element.getAttributeNS(BLUEPRINT_EXT_NAMESPACE_V1_1, IGNORE_MISSING_LOCATIONS_ATTRIBUTE);
-      }
-      return ignoreMissingLocations;
-    }
-
-    private Metadata parseDefaultProperties(ParserContext context, MutableBeanMetadata enclosingComponent, Element element) {
-        MutableMapMetadata props = context.createMetadata(MutableMapMetadata.class);
-        NodeList nl = element.getChildNodes();
-        for (int i = 0; i < nl.getLength(); i++) {
-            Node node = nl.item(i);
-            if (node instanceof Element) {
-                Element e = (Element) node;
-                if (isCmNamespace(e.getNamespaceURI())) {
-                    if (nodeNameEquals(e, PROPERTY_ELEMENT)) {
-                        BeanProperty prop = context.parseElement(BeanProperty.class, enclosingComponent, e);
-                        props.addEntry(createValue(context, prop.getName(), String.class.getName()), prop.getValue());
-                    }
-                }
-            }
-        }
-        return props;
-    }
-
-    private ComponentMetadata parseManagedServiceFactory(ParserContext context, Element element) {
-        String id = getId(context, element);
-
-        MutableBeanMetadata factoryMetadata = context.createMetadata(MutableBeanMetadata.class);
-        generateIdIfNeeded(context, factoryMetadata);
-        factoryMetadata.addProperty("id", createValue(context, factoryMetadata.getId()));
-        factoryMetadata.setScope(BeanMetadata.SCOPE_SINGLETON);
-        factoryMetadata.setRuntimeClass(CmManagedServiceFactory.class);
-        factoryMetadata.setInitMethod("init");
-        factoryMetadata.setDestroyMethod("destroy");
-        factoryMetadata.addArgument(createRef(context, "blueprintContainer"), null, 0);
-        factoryMetadata.addProperty("factoryPid", createValue(context, element.getAttribute(FACTORY_PID_ATTRIBUTE)));
-        String autoExport = element.hasAttribute(AUTO_EXPORT_ATTRIBUTE) ? element.getAttribute(AUTO_EXPORT_ATTRIBUTE) : AUTO_EXPORT_DEFAULT;
-        if (AUTO_EXPORT_DISABLED.equals(autoExport)) {
-            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_DISABLED);
-        } else if (AUTO_EXPORT_INTERFACES.equals(autoExport)) {
-            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_INTERFACES);
-        } else if (AUTO_EXPORT_CLASS_HIERARCHY.equals(autoExport)) {
-            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_CLASS_HIERARCHY);
-        } else if (AUTO_EXPORT_ALL.equals(autoExport)) {
-            autoExport = Integer.toString(ServiceMetadata.AUTO_EXPORT_ALL_CLASSES);
-        } else {
-            throw new ComponentDefinitionException("Illegal value (" + autoExport + ") for " + AUTO_EXPORT_ATTRIBUTE + " attribute");
-        }
-        factoryMetadata.addProperty("autoExport", createValue(context, autoExport));
-        String ranking = element.hasAttribute(RANKING_ATTRIBUTE) ? element.getAttribute(RANKING_ATTRIBUTE) : RANKING_DEFAULT;
-        factoryMetadata.addProperty("ranking", createValue(context, ranking));
-
-        List<String> interfaces = null;
-        if (element.hasAttribute(INTERFACE_ATTRIBUTE)) {
-            interfaces = Collections.singletonList(element.getAttribute(INTERFACE_ATTRIBUTE));
-            factoryMetadata.addProperty("interfaces", createList(context, interfaces));
-        }
-       
-        // Parse elements
-        List<RegistrationListener> listeners = new ArrayList<RegistrationListener>();
-        NodeList nl = element.getChildNodes();
-        for (int i = 0; i < nl.getLength(); i++) {
-            Node node = nl.item(i);
-            if (node instanceof Element) {
-                Element e = (Element) node;
-                if (isBlueprintNamespace(e.getNamespaceURI())) {
-                    if (nodeNameEquals(e, INTERFACES_ELEMENT)) {
-                        if (interfaces != null) {
-                            throw new ComponentDefinitionException("Only one of " + INTERFACE_ATTRIBUTE + " attribute or " + INTERFACES_ELEMENT + " element must be used");
-                        }
-                        interfaces = parseInterfaceNames(e);
-                        factoryMetadata.addProperty("interfaces", createList(context, interfaces));                    
-                    } else if (nodeNameEquals(e, SERVICE_PROPERTIES_ELEMENT)) { 
-                        MapMetadata map = context.parseElement(MapMetadata.class,
-                            factoryMetadata, e);
-                        factoryMetadata.addProperty("serviceProperties", map);
-                        NodeList enl = e.getChildNodes();
-                        for (int j = 0; j < enl.getLength(); j++) {
-                            Node enode = enl.item(j);
-                            if (enode instanceof Element) {
-                                if (isCmNamespace(enode.getNamespaceURI()) && nodeNameEquals(enode, CM_PROPERTIES_ELEMENT)) {
-                                    decorateCmProperties(context, (Element) enode, factoryMetadata);
-                                }
-                            }
-                        }
-                    } else if (nodeNameEquals(e, REGISTRATION_LISTENER_ELEMENT)) {
-                        listeners.add(context.parseElement(RegistrationListener.class,
-                            factoryMetadata, e));
-                    }
-                } else if (isCmNamespace(e.getNamespaceURI())) {
-                    if (nodeNameEquals(e, MANAGED_COMPONENT_ELEMENT)) {
-                        MutableBeanMetadata managedComponent = context.parseElement(MutableBeanMetadata.class, null, e);
-                        generateIdIfNeeded(context, managedComponent);
-                        managedComponent.setScope(BeanMetadata.SCOPE_PROTOTYPE);
-                        // destroy-method on managed-component has different signature than on regular beans
-                        // so we'll handle it differently
-                        String destroyMethod = managedComponent.getDestroyMethod();
-                        if (destroyMethod != null) {
-                            factoryMetadata.addProperty("componentDestroyMethod", createValue(context, destroyMethod));
-                            managedComponent.setDestroyMethod(null);
-                        }
-                        context.getComponentDefinitionRegistry().registerComponentDefinition(managedComponent);
-                        factoryMetadata.addProperty("managedComponentName", createIdRef(context, managedComponent.getId()));
-                    }
-                }
-            }
-        }
-
-        MutableCollectionMetadata listenerCollection = context.createMetadata(MutableCollectionMetadata.class);
-        listenerCollection.setCollectionClass(List.class);
-        for (RegistrationListener listener : listeners) {
-            MutableBeanMetadata bean = context.createMetadata(MutableBeanMetadata.class);
-            bean.setRuntimeClass(ServiceListener.class);
-            bean.addProperty("listener", listener.getListenerComponent());
-            bean.addProperty("registerMethod", createValue(context, listener.getRegistrationMethod()));
-            bean.addProperty("unregisterMethod", createValue(context, listener.getUnregistrationMethod()));
-            listenerCollection.addValue(bean);
-        }
-        factoryMetadata.addProperty("listeners", listenerCollection);
-        
-        context.getComponentDefinitionRegistry().registerComponentDefinition(factoryMetadata);
-        
-        MutableBeanMetadata mapMetadata = context.createMetadata(MutableBeanMetadata.class);
-        mapMetadata.setScope(BeanMetadata.SCOPE_SINGLETON);
-        mapMetadata.setId(id);
-        mapMetadata.setFactoryComponent(createRef(context, factoryMetadata.getId()));
-        mapMetadata.setFactoryMethod("getServiceMap");
-        return mapMetadata;
-    }
-
-    private ComponentMetadata decorateCmProperties(ParserContext context, Element element, ComponentMetadata component) {
-        generateIdIfNeeded(context, ((MutableComponentMetadata) component));
-        MutableBeanMetadata metadata = context.createMetadata(MutableBeanMetadata.class);
-        metadata.setProcessor(true);
-        metadata.setId(getId(context, element));
-        metadata.setRuntimeClass(CmProperties.class);
-        String persistentId = element.getAttribute(PERSISTENT_ID_ATTRIBUTE);
-        // if persistentId is "" the cm-properties element in nested in managed-service-factory
-        // and the configuration object will come from the factory. So we only really need to register
-        // ManagedService if the persistentId is not an empty string.
-        if (persistentId.length() > 0) {
-            metadata.setInitMethod("init");
-            metadata.setDestroyMethod("destroy");
-        }
-        metadata.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
-        metadata.addProperty("configAdmin", createConfigurationAdminRef(context));
-        metadata.addProperty("managedObjectManager", createRef(context, MANAGED_OBJECT_MANAGER_NAME));
-        metadata.addProperty("persistentId", createValue(context, persistentId));
-        if (element.hasAttribute(UPDATE_ATTRIBUTE)) {
-            metadata.addProperty("update", createValue(context, element.getAttribute(UPDATE_ATTRIBUTE)));
-        }
-        metadata.addProperty("serviceId", createIdRef(context, component.getId()));
-        context.getComponentDefinitionRegistry().registerComponentDefinition(metadata);
-        return component;
-    }
-
-    private ComponentMetadata decorateManagedProperties(ParserContext context, Element element, ComponentMetadata component) {
-        if (!(component instanceof MutableBeanMetadata)) {
-            throw new ComponentDefinitionException("Element " + MANAGED_PROPERTIES_ELEMENT + " must be used inside a <bp:bean> element");
-        }
-        generateIdIfNeeded(context, ((MutableBeanMetadata) component));
-        MutableBeanMetadata metadata = context.createMetadata(MutableBeanMetadata.class);
-        metadata.setProcessor(true);
-        metadata.setId(getId(context, element));
-        metadata.setRuntimeClass(CmManagedProperties.class);
-        String persistentId = element.getAttribute(PERSISTENT_ID_ATTRIBUTE);
-        // if persistentId is "" the managed properties element in nested in managed-service-factory
-        // and the configuration object will come from the factory. So we only really need to register
-        // ManagedService if the persistentId is not an empty string.
-        if (persistentId.length() > 0) {
-            metadata.setInitMethod("init");
-            metadata.setDestroyMethod("destroy");
-        }
-        metadata.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
-        metadata.addProperty("configAdmin", createConfigurationAdminRef(context));
-        metadata.addProperty("managedObjectManager", createRef(context, MANAGED_OBJECT_MANAGER_NAME));
-        metadata.addProperty("persistentId", createValue(context, persistentId));
-        String updateStrategy = element.getAttribute(UPDATE_STRATEGY_ATTRIBUTE);
-        if (updateStrategy != null) {
-            metadata.addProperty("updateStrategy", createValue(context, updateStrategy));
-        }
-        if (element.hasAttribute(UPDATE_METHOD_ATTRIBUTE)) {
-            metadata.addProperty("updateMethod", createValue(context, element.getAttribute(UPDATE_METHOD_ATTRIBUTE)));
-        } else if ("component-managed".equals(updateStrategy)) {
-            throw new ComponentDefinitionException(UPDATE_METHOD_ATTRIBUTE + " attribute must be set when " + UPDATE_STRATEGY_ATTRIBUTE + " is set to 'component-managed'");
-        }
-        metadata.addProperty("beanName", createIdRef(context, component.getId()));
-        context.getComponentDefinitionRegistry().registerComponentDefinition(metadata);
-        return component;
-    }
-
-    private void registerManagedObjectManager(ParserContext context, ComponentDefinitionRegistry registry) {
-        if (registry.getComponentDefinition(MANAGED_OBJECT_MANAGER_NAME) == null) {
-            MutableBeanMetadata beanMetadata = context.createMetadata(MutableBeanMetadata.class);
-            beanMetadata.setScope(BeanMetadata.SCOPE_SINGLETON);
-            beanMetadata.setId(MANAGED_OBJECT_MANAGER_NAME);
-            beanMetadata.setRuntimeClass(ManagedObjectManager.class);            
-            registry.registerComponentDefinition(beanMetadata);
-        }
-    }
-    
-    private MutableReferenceMetadata createConfigurationAdminRef(ParserContext context) {
-        return createServiceRef(context, ConfigurationAdmin.class, null);
-    }
-    
-    private static ValueMetadata createValue(ParserContext context, String value) {
-        return createValue(context, value, null);
-    }
-
-    private static ValueMetadata createValue(ParserContext context, String value, String type) {
-        MutableValueMetadata m = context.createMetadata(MutableValueMetadata.class);
-        m.setStringValue(value);
-        m.setType(type);
-        return m;
-    }
-
-    private static RefMetadata createRef(ParserContext context, String value) {
-        MutableRefMetadata m = context.createMetadata(MutableRefMetadata.class);
-        m.setComponentId(value);
-        return m;
-    }
-    
-    private MutableReferenceMetadata createServiceRef(ParserContext context, Class<?> cls, String filter) {
-        MutableReferenceMetadata m = context.createMetadata(MutableReferenceMetadata.class);
-        m.setRuntimeInterface(cls);
-        m.setInterface(cls.getName());
-        m.setActivation(ReferenceMetadata.ACTIVATION_EAGER);
-        m.setAvailability(ReferenceMetadata.AVAILABILITY_MANDATORY);
-        
-        if (filter != null) {
-            m.setFilter(filter);
-        }
-        
-        return m;
-    }
-
-    private static IdRefMetadata createIdRef(ParserContext context, String value) {
-        MutableIdRefMetadata m = context.createMetadata(MutableIdRefMetadata.class);
-        m.setComponentId(value);
-        return m;
-    }
-
-    private static CollectionMetadata createList(ParserContext context, List<String> list) {
-        MutableCollectionMetadata m = context.createMetadata(MutableCollectionMetadata.class);
-        m.setCollectionClass(List.class);
-        m.setValueType(String.class.getName());
-        for (String v : list) {
-            m.addValue(createValue(context, v, String.class.getName()));
-        }
-        return m;
-    }
-
-    private static String getTextValue(Element element) {
-        StringBuffer value = new StringBuffer();
-        NodeList nl = element.getChildNodes();
-        for (int i = 0; i < nl.getLength(); i++) {
-            Node item = nl.item(i);
-            if ((item instanceof CharacterData && !(item instanceof Comment)) || item instanceof EntityReference) {
-                value.append(item.getNodeValue());
-            }
-        }
-        return value.toString();
-    }
-
-    private static boolean nodeNameEquals(Node node, String name) {
-        return (name.equals(node.getNodeName()) || name.equals(node.getLocalName()));
-    }
-
-    public static boolean isBlueprintNamespace(String ns) {
-        return BLUEPRINT_NAMESPACE.equals(ns);
-    }
-
-    public static boolean isCmNamespace(String uri) {
-        return BLUEPRINT_CM_NAMESPACE_1_0.equals(uri)
-                || BLUEPRINT_CM_NAMESPACE_1_1.equals(uri)
-                || BLUEPRINT_CM_NAMESPACE_1_2.equals(uri);
-    }
-
-    public static boolean isExtNamespace(String uri) {
-        return BLUEPRINT_EXT_NAMESPACE_V1_0.equals(uri)
-                || BLUEPRINT_EXT_NAMESPACE_V1_1.equals(uri)
-                || BLUEPRINT_EXT_NAMESPACE_V1_2.equals(uri);
-    }
-
-    public String getId(ParserContext context, Element element) {
-        if (element.hasAttribute(ID_ATTRIBUTE)) {
-            return element.getAttribute(ID_ATTRIBUTE);
-        } else {
-            return generateId(context);
-        }
-    }
-
-    public void generateIdIfNeeded(ParserContext context, MutableComponentMetadata metadata) {
-        if (metadata.getId() == null) {
-            metadata.setId(generateId(context));
-        }
-    }
-
-    private String generateId(ParserContext context) {
-        String id;
-        do {
-            id = ".cm-" + ++idCounter;
-        } while (context.getComponentDefinitionRegistry().containsComponentDefinition(id));
-        return id;
-    }
-    
-    public List<String> parseInterfaceNames(Element element) {
-        List<String> interfaceNames = new ArrayList<String>();
-        NodeList nl = element.getChildNodes();
-        for (int i = 0; i < nl.getLength(); i++) {
-            Node node = nl.item(i);
-            if (node instanceof Element) {
-                Element e = (Element) node;
-                if (nodeNameEquals(e, VALUE_ELEMENT)) {
-                    String v = getTextValue(e).trim();
-                    if (interfaceNames.contains(v)) {
-                        throw new ComponentDefinitionException("The element " + INTERFACES_ELEMENT + " should not contain the same interface twice");
-                    }
-                    interfaceNames.add(getTextValue(e));
-                } else {
-                    throw new ComponentDefinitionException("Unsupported element " + e.getNodeName() + " inside an " + INTERFACES_ELEMENT + " element");
-                }
-            }
-        }
-        return interfaceNames;
-    }
-}
diff --git a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java b/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java
deleted file mode 100644
index eb8b881..0000000
--- a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmProperties.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.util.Dictionary;
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-
-import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
-import org.apache.aries.blueprint.ServiceProcessor;
-import org.apache.aries.blueprint.utils.JavaUtils;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * @version $Rev$, $Date$
- */
-public class CmProperties implements ManagedObject, ServiceProcessor {
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(CmProperties.class);
-
-    private ExtendedBlueprintContainer blueprintContainer;
-    private ConfigurationAdmin configAdmin;
-    private ManagedObjectManager managedObjectManager;
-    private String persistentId;
-    private boolean update;
-    private String serviceId;
-
-    private final Object lock = new Object();
-    private final Set<ServicePropertiesUpdater> services = new HashSet<ServicePropertiesUpdater>();
-    private final Properties properties = new Properties();
-
-    public ExtendedBlueprintContainer getBlueprintContainer() {
-        return blueprintContainer;
-    }
-
-    public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
-        this.blueprintContainer = blueprintContainer;
-    }
-
-    public ConfigurationAdmin getConfigAdmin() {
-        return configAdmin;
-    }
-
-    public void setConfigAdmin(ConfigurationAdmin configAdmin) {
-        this.configAdmin = configAdmin;
-    }
-
-    public void setManagedObjectManager(ManagedObjectManager managedObjectManager) {
-        this.managedObjectManager = managedObjectManager;
-    }
-    
-    public ManagedObjectManager getManagedObjectManager() {
-        return managedObjectManager;
-    }
-    
-    public Bundle getBundle() {
-        return blueprintContainer.getBundleContext().getBundle();
-    }
-    
-    public String getPersistentId() {
-        return persistentId;
-    }
-
-    public void setPersistentId(String persistentId) {
-        this.persistentId = persistentId;
-    }
-
-    public boolean getUpdate() {
-        return update;
-    }
-
-    public void setUpdate(boolean update) {
-        this.update = update;
-    }
-
-    public String getServiceId() {
-        return serviceId;
-    }
-
-    public void setServiceId(String serviceId) {
-        this.serviceId = serviceId;
-    }
-    
-    public void init() throws Exception {
-        if (serviceId != null) {
-            LOGGER.debug("Initializing CmProperties for service={} / pid={}", serviceId, persistentId);
-        } else {
-            LOGGER.debug("Initializing CmProperties for pid={}", persistentId);
-        }
-        
-        Properties props = new Properties();
-        props.put(Constants.SERVICE_PID, persistentId);
-        Bundle bundle = blueprintContainer.getBundleContext().getBundle();
-        props.put(Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
-        props.put(Constants.BUNDLE_VERSION, bundle.getHeaders().get(Constants.BUNDLE_VERSION));
-                
-        synchronized (lock) {
-            managedObjectManager.register(this, props);
-            Configuration config = CmUtils.getConfiguration(configAdmin, persistentId);
-            if (config != null) {
-                properties.clear();
-                JavaUtils.copy(properties, config.getProperties());
-            }
-        }
-    }
-
-    public void destroy() {
-        managedObjectManager.unregister(this);
-    }
-
-    public Properties getProperties() {
-        return properties;
-    }
-
-    public void updated(Dictionary props) {
-        if (serviceId != null) {
-            LOGGER.debug("Service properties updated for service={} / pid={}, {}", new Object[] {serviceId, persistentId, props});
-        } else {
-            LOGGER.debug("Service properties updated for pid={}, {}", new Object[] {persistentId, props});
-        }
-        
-        synchronized (lock) {
-            properties.clear();
-            if (props != null) {
-                JavaUtils.copy(properties, props);
-            }
-            if (update) {
-                for (ServicePropertiesUpdater service : services) {
-                    service.updateProperties(props);
-                }
-            }
-        }
-    }
-
-    public void updateProperties(ServicePropertiesUpdater service, Dictionary props) {
-        if (this.serviceId == null || !this.serviceId.equals(service.getId())) {
-            return;
-        }
-                
-        LOGGER.debug("Service properties initialized for service={} / pid={}, {}", new Object[] {serviceId, persistentId, props});
-        
-        synchronized (lock) {
-            services.add(service);
-            if (properties != null) {
-                JavaUtils.copy(props, properties);
-            }
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java b/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java
deleted file mode 100644
index 7abb98e..0000000
--- a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmPropertyPlaceholder.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.Properties;
-
-import org.apache.aries.blueprint.ext.PropertyPlaceholder;
-import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.Constants;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * TODO: javadoc
- *
- * @version $Rev$, $Date$
- */
-public class CmPropertyPlaceholder extends PropertyPlaceholder implements ManagedObject {
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(CmPropertyPlaceholder.class);
-
-    private ExtendedBlueprintContainer blueprintContainer;
-    private ConfigurationAdmin configAdmin; 
-    private String persistentId;
-    private String updateStrategy;
-    private ManagedObjectManager managedObjectManager;
-    private Dictionary<String,Object> properties;
-
-    public ExtendedBlueprintContainer getBlueprintContainer() {
-        return blueprintContainer;
-    }
-
-    public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
-        this.blueprintContainer = blueprintContainer;
-    }
-
-    public ConfigurationAdmin getConfigAdmin() {
-        return configAdmin;
-    }
-
-    public void setConfigAdmin(ConfigurationAdmin configAdmin) {
-        this.configAdmin = configAdmin;
-    }
-
-    public String getPersistentId() {
-        return persistentId;
-    }
-
-    public void setPersistentId(String persistentId) {
-        this.persistentId = persistentId;
-    }
-
-    public String getUpdateStrategy() {
-        return updateStrategy;
-    }
-
-    public void setUpdateStrategy(String updateStrategy) {
-        this.updateStrategy = updateStrategy;
-    }
-
-    public ManagedObjectManager getManagedObjectManager() {
-        return managedObjectManager;
-    }
-
-    public void setManagedObjectManager(ManagedObjectManager managedObjectManager) {
-        this.managedObjectManager = managedObjectManager;
-    }
-
-    public void init() throws Exception {
-        LOGGER.debug("Initializing CmPropertyPlaceholder");
-        Configuration config = CmUtils.getConfiguration(configAdmin, persistentId);
-        if (config != null) {
-            properties = config.getProperties();
-        }
-        Properties props = new Properties();
-        props.put(Constants.SERVICE_PID, persistentId);
-        Bundle bundle = blueprintContainer.getBundleContext().getBundle();
-        props.put(Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
-        props.put(Constants.BUNDLE_VERSION, bundle.getHeaders().get(Constants.BUNDLE_VERSION));
-        managedObjectManager.register(this, props);
-    }
-
-    public void destroy() {
-        LOGGER.debug("Destroying CmPropertyPlaceholder");
-        managedObjectManager.unregister(this);
-    }
-
-    protected String getProperty(String val) {
-        LOGGER.debug("Retrieving property value {} from configuration with pid {}", val, persistentId);
-        Object v = null;
-        if (properties != null) {
-            v = properties.get(val);
-            if (v != null) {
-                LOGGER.debug("Found property value {}", v);
-            } else {
-                LOGGER.debug("Property not found in configuration");
-            }
-        }
-        if (v == null) {
-            v = super.getProperty(val);
-        }
-        return v != null ? v.toString() : null;
-    }
-
-    public Bundle getBundle() {
-        return blueprintContainer.getBundleContext().getBundle();
-    }
-
-    public void updated(Dictionary props) {
-        if ("reload".equalsIgnoreCase(updateStrategy) && !equals(properties, props)) {
-            LOGGER.debug("Configuration updated for pid={}", persistentId);
-            // Run in a separate thread to avoid re-entrance
-            new Thread() {
-                public void run() {
-                    blueprintContainer.reload();
-                }
-            }.start();
-        }
-    }
-
-    private <T,U> boolean equals(Dictionary<T,U> d1, Dictionary<T,U> d2) {
-        if (d1 == null || d1.isEmpty()) {
-            return d2 == null || d2.isEmpty();
-        } else if (d2 == null || d1.size() != d2.size()) {
-            return false;
-        } else {
-            for (Enumeration<T> e = d1.keys(); e.hasMoreElements();) {
-                T k = e.nextElement();
-                U v1 = d1.get(k);
-                U v2 = d2.get(k);
-                if (v1 == null) {
-                    if (v2 != null) {
-                        return false;
-                    }
-                } else {
-                    if (!v1.equals(v2)) {
-                        return false;
-                    }
-                }
-            }
-            return true;
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java b/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java
deleted file mode 100644
index aa407f8..0000000
--- a/src/main/java/org/apache/aries/blueprint/compendium/cm/CmUtils.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.io.IOException;
-
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-public class CmUtils  {
-
-    private CmUtils() {        
-    }
-    
-    public static Configuration getConfiguration(ConfigurationAdmin configAdmin, String persistentId) throws IOException {
-        String filter = '(' + Constants.SERVICE_PID + '=' + persistentId + ')';
-        Configuration[] configs;
-        try {
-            configs = configAdmin.listConfigurations(filter);
-        } catch (InvalidSyntaxException e) {
-            // this should not happen
-            throw new RuntimeException("Invalid filter: " + filter);
-        }
-        if (configs != null && configs.length > 0) {
-            return configs[0];
-        } else {
-            // TODO: what should we do?
-            // throw new RuntimeException("No configuration object for pid=" + persistentId);
-            return null;
-        }
-    }
-  
-}
diff --git a/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObject.java b/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObject.java
deleted file mode 100644
index 8005dc5..0000000
--- a/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObject.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.util.Dictionary;
-
-import org.osgi.framework.Bundle;
-
-public interface ManagedObject {
-
-    Bundle getBundle();
-    String getPersistentId();
-    
-    void updated(Dictionary props);
-          
-}
diff --git a/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java b/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java
deleted file mode 100644
index 90bc7f4..0000000
--- a/src/main/java/org/apache/aries/blueprint/compendium/cm/ManagedObjectManager.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.apache.aries.util.AriesFrameworkUtil;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.cm.ConfigurationException;
-import org.osgi.service.cm.ManagedService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Since persistence id can only be associated with one ManagedService in a bundle
- * this class ensures only one ManagedService is registered per persistence id.
- */
-public class ManagedObjectManager {
-
-    private static final Logger LOGGER = LoggerFactory.getLogger(ManagedObjectManager.class);
-
-    private HashMap<String, ConfigurationWatcher> map = new HashMap<String, ConfigurationWatcher>();
-               
-    public synchronized void register(ManagedObject cm, Properties props) {
-        String key = cm.getPersistentId();
-        ConfigurationWatcher reg = map.get(key);
-        if (reg == null) {
-            reg = new ConfigurationWatcher(); 
-            ServiceRegistration registration = cm.getBundle().getBundleContext().registerService(ManagedService.class.getName(), reg, props);
-            reg.setRegistration(registration);            
-            map.put(key, reg);
-        }
-        reg.add(cm);
-    }
-
-    public synchronized void unregister(ManagedObject cm) {
-        String key = cm.getPersistentId();
-        ConfigurationWatcher reg = map.get(key);
-        if (reg != null) {
-            reg.remove(cm);
-            if (reg.isEmpty()) {
-                map.remove(key);
-                AriesFrameworkUtil.safeUnregisterService(reg.getRegistration());
-            }
-        }
-    }
-            
-    private static class ConfigurationWatcher implements ManagedService {
-
-        private ServiceRegistration registration;
-        private List<ManagedObject> list = new CopyOnWriteArrayList<ManagedObject>();
-        
-        public ConfigurationWatcher() {
-        }
-        
-        public void updated(final Dictionary props) throws ConfigurationException {
-            // Run in a separate thread to avoid re-entrance
-            new Thread() {
-                public void run() {
-                    for (ManagedObject cm : list) {
-                        cm.updated(props);
-                    }
-                }
-            }.start();
-        }
-        
-        private void setRegistration(ServiceRegistration registration) {
-            this.registration = registration;
-        }
-        
-        private ServiceRegistration getRegistration() {
-            return registration;
-        }
-        
-        private void add(ManagedObject cm) {
-            list.add(cm);
-        }
-        
-        private void remove(ManagedObject cm) {
-            list.remove(cm);
-        }
-        
-        private boolean isEmpty() {
-            return list.isEmpty();
-        }
-    }
-        
-}
diff --git a/src/main/java/org/apache/aries/blueprint/compendium/cm/packageinfo b/src/main/java/org/apache/aries/blueprint/compendium/cm/packageinfo
deleted file mode 100644
index c72722a..0000000
--- a/src/main/java/org/apache/aries/blueprint/compendium/cm/packageinfo
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# 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.
-#
-version 1.0.0
diff --git a/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java b/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
new file mode 100644
index 0000000..226fdee
--- /dev/null
+++ b/src/main/java/org/apache/aries/blueprint/container/BeanRecipe.java
@@ -0,0 +1,1073 @@
+/*
+ * 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.aries.blueprint.container;
+
+import static org.apache.aries.blueprint.utils.ReflectionUtils.getRealCause;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+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.concurrent.Callable;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.aries.blueprint.BeanProcessor;
+import org.apache.aries.blueprint.ComponentDefinitionRegistry;
+import org.apache.aries.blueprint.Interceptor;
+import org.apache.aries.blueprint.di.AbstractRecipe;
+import org.apache.aries.blueprint.di.Recipe;
+import org.apache.aries.blueprint.proxy.Collaborator;
+import org.apache.aries.blueprint.proxy.ProxyUtils;
+import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
+import org.apache.aries.blueprint.utils.ReflectionUtils;
+import org.apache.aries.blueprint.utils.ReflectionUtils.PropertyDescriptor;
+import org.apache.aries.proxy.UnableToProxyException;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+import org.osgi.service.blueprint.container.ReifiedType;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A <code>Recipe</code> to create POJOs.
+ *
+ * @version $Rev$, $Date$
+ */
+public class BeanRecipe extends AbstractRecipe {
+
+    static class UnwrapperedBeanHolder {
+        final Object unwrapperedBean;
+        final BeanRecipe recipe;
+
+        public UnwrapperedBeanHolder(Object unwrapperedBean, BeanRecipe recipe) {
+            this.unwrapperedBean = unwrapperedBean;
+            this.recipe = recipe;
+        }
+    }
+
+    public class VoidableCallable implements Callable<Object>, Voidable {
+
+        private final AtomicReference<Object> ref = new AtomicReference<Object>();
+
+        private final Semaphore sem = new Semaphore(1);
+
+        private final ThreadLocal<Object> deadlockDetector = new ThreadLocal<Object>();
+
+        public void voidReference() {
+            ref.set(null);
+        }
+
+        public Object call() throws ComponentDefinitionException {
+            Object o = ref.get();
+
+            if (o == null) {
+                if(deadlockDetector.get() != null) {
+                    deadlockDetector.remove();
+                    throw new ComponentDefinitionException("Construction cycle detected for bean " + name);
+                }
+
+                sem.acquireUninterruptibly();
+                try {
+                    o = ref.get();
+                    if (o == null) {
+                        deadlockDetector.set(this);
+                        try {
+                            o = internalCreate2();
+                            ref.set(o);
+                        } finally {
+                            deadlockDetector.remove();
+                        }
+                    }
+                } finally {
+                    sem.release();
+                }
+            }
+
+            return o;
+        }
+
+    }
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(BeanRecipe.class);
+
+    private final ExtendedBlueprintContainer blueprintContainer;
+    private final LinkedHashMap<String,Object> properties = new LinkedHashMap<String,Object>();
+    private final Object type;
+
+    private String initMethod;
+    private String destroyMethod;
+    private List<Recipe> explicitDependencies;
+
+    private Recipe factory;
+    private String factoryMethod;
+    private List<Object> arguments;
+    private List<String> argTypes;
+    private boolean reorderArguments;
+    private final boolean allowsFieldInjection;
+    private BeanMetadata interceptorLookupKey;
+
+
+    public BeanRecipe(String name, ExtendedBlueprintContainer blueprintContainer, Object type, boolean allowsFieldInjection) {
+        super(name);
+        this.blueprintContainer = blueprintContainer;
+        this.type = type;
+        this.allowsFieldInjection = allowsFieldInjection;
+    }
+
+    public Object getProperty(String name) {
+        return properties.get(name);
+    }
+
+    public Map<String, Object> getProperties() {
+        return new LinkedHashMap<String, Object>(properties);
+    }
+
+    public void setProperty(String name, Object value) {
+        properties.put(name, value);
+    }
+
+    public void setFactoryMethod(String method) {
+        this.factoryMethod = method;
+    }
+
+    public void setFactoryComponent(Recipe factory) {
+        this.factory = factory;
+    }
+
+    public void setArgTypes(List<String> argTypes) {
+        this.argTypes = argTypes;
+    }
+
+    public void setArguments(List<Object> arguments) {
+        this.arguments = arguments;
+    }
+
+    public void setReorderArguments(boolean reorder) {
+        this.reorderArguments = reorder;
+    }
+
+    public void setInitMethod(String initMethod) {
+        this.initMethod = initMethod;
+    }
+
+    public String getInitMethod() {
+        return initMethod;
+    }
+
+    public void setDestroyMethod(String destroyMethod) {
+        this.destroyMethod = destroyMethod;
+    }
+
+    public String getDestroyMethod() {
+        return destroyMethod;
+    }
+
+    public List<Recipe> getExplicitDependencies() {
+        return explicitDependencies;
+    }
+
+    public void setExplicitDependencies(List<Recipe> explicitDependencies) {
+        this.explicitDependencies = explicitDependencies;
+    }
+
+    public void setInterceptorLookupKey(BeanMetadata metadata) {
+        interceptorLookupKey = metadata;
+    }
+
+    @Override
+    public List<Recipe> getConstructorDependencies() {
+        List<Recipe> recipes = new ArrayList<Recipe>();
+        if (explicitDependencies != null) {
+            recipes.addAll(explicitDependencies);
+        }
+        if (arguments != null) {
+            for (Object argument : arguments) {
+                if (argument instanceof Recipe) {
+                    recipes.add((Recipe)argument);
+                }
+            }
+        }
+        return recipes;
+    }
+
+    public List<Recipe> getDependencies() {
+        List<Recipe> recipes = new ArrayList<Recipe>();
+        for (Object o : properties.values()) {
+            if (o instanceof Recipe) {
+                Recipe recipe = (Recipe) o;
+                recipes.add(recipe);
+            }
+        }
+        recipes.addAll(getConstructorDependencies());
+        return recipes;
+    }
+
+    private void instantiateExplicitDependencies() {
+        if (explicitDependencies != null) {
+            for (Recipe recipe : explicitDependencies) {
+                recipe.create();
+            }
+        }
+    }
+
+    @Override
+    protected Class loadClass(String className) {
+        ClassLoader loader = type instanceof Class ? ((Class) type).getClassLoader() : null;
+        ReifiedType t = loadType(className, loader);
+        return t != null ? t.getRawClass() : null;
+    }
+
+    @Override
+    protected ReifiedType loadType(String className) {
+        return loadType(className, type instanceof Class ? ((Class) type).getClassLoader() : null);
+    }
+
+    private Object getInstance() throws ComponentDefinitionException {
+        Object instance;
+
+        // Instanciate arguments
+        List<Object> args = new ArrayList<Object>();
+        List<ReifiedType> argTypes = new ArrayList<ReifiedType>();
+        if (arguments != null) {
+            for (int i = 0; i < arguments.size(); i++) {
+                Object arg = arguments.get(i);
+                if (arg instanceof Recipe) {
+                    args.add(((Recipe) arg).create());
+                } else {
+                    args.add(arg);
+                }
+                if (this.argTypes != null) {
+                    argTypes.add(this.argTypes.get(i) != null ? loadType(this.argTypes.get(i)) : null);
+                }
+            }
+        }
+
+        if (factory != null) {
+            // look for instance method on factory object
+            Object factoryObj = factory.create();
+
+            // If the factory is a service reference, we need to get hold of the actual proxy for the service
+            /* BLUEPRINT-NOOSGI
+            if (factoryObj instanceof ReferenceRecipe.ServiceProxyWrapper) {
+                try {
+                    factoryObj = ((ReferenceRecipe.ServiceProxyWrapper) factoryObj).convert(new ReifiedType(Object.class));
+                } catch (Exception e) {
+                    throw new ComponentDefinitionException("Error when instantiating bean " + getName() + " of class " + getType(), getRealCause(e));
+                }
+            } else*/ if (factoryObj instanceof UnwrapperedBeanHolder) {
+                factoryObj = wrap((UnwrapperedBeanHolder) factoryObj, Object.class);
+            }
+
+            // Map of matching methods
+            Map<Method, List<Object>> matches = findMatchingMethods(factoryObj.getClass(), factoryMethod, true, args, argTypes);
+            if (matches.size() == 1) {
+                try {
+                    Map.Entry<Method, List<Object>> match = matches.entrySet().iterator().next();
+                    instance = invoke(match.getKey(), factoryObj, match.getValue().toArray());
+                } catch (Throwable e) {
+                    throw new ComponentDefinitionException("Error when instantiating bean " + getName() + " of class " + getType(), getRealCause(e));
+                }
+            } else if (matches.size() == 0) {
+                throw new ComponentDefinitionException("Unable to find a matching factory method " + factoryMethod + " on class " + factoryObj.getClass().getName() + " for arguments " + args + " when instanciating bean " + getName());
+            } else {
+                throw new ComponentDefinitionException("Multiple matching factory methods " + factoryMethod + " found on class " + factoryObj.getClass().getName() + " for arguments " + args + " when instanciating bean " + getName() + ": " + matches.keySet());
+            }
+        } else if (factoryMethod != null) {
+            // Map of matching methods
+            Map<Method, List<Object>> matches = findMatchingMethods(getType(), factoryMethod, false, args, argTypes);
+            if (matches.size() == 1) {
+                try {
+                    Map.Entry<Method, List<Object>> match = matches.entrySet().iterator().next();
+                    instance = invoke(match.getKey(), null, match.getValue().toArray());
+                } catch (Throwable e) {
+                    throw new ComponentDefinitionException("Error when instanciating bean " + getName() + " of class " + getType(), getRealCause(e));
+                }
+            } else if (matches.size() == 0) {
+                throw new ComponentDefinitionException("Unable to find a matching factory method " + factoryMethod + " on class " + getType().getName() + " for arguments " + args + " when instanciating bean " + getName());
+            } else {
+                throw new ComponentDefinitionException("Multiple matching factory methods " + factoryMethod + " found on class " + getType().getName() + " for arguments " + args + " when instanciating bean " + getName() + ": " + matches.keySet());
+            }
+        } else {
+            if (getType() == null) {
+                throw new ComponentDefinitionException("No factoryMethod nor class is defined for this bean");
+            }
+            // Map of matching constructors
+            Map<Constructor, List<Object>> matches = findMatchingConstructors(getType(), args, argTypes);
+            if (matches.size() == 1) {
+                try {
+                    Map.Entry<Constructor, List<Object>> match = matches.entrySet().iterator().next();
+                    instance = newInstance(match.getKey(), match.getValue().toArray());
+                } catch (Throwable e) {
+                    throw new ComponentDefinitionException("Error when instanciating bean " + getName() + " of class " + getType(), getRealCause(e));
+                }
+            } else if (matches.size() == 0) {
+                throw new ComponentDefinitionException("Unable to find a matching constructor on class " + getType().getName() + " for arguments " + args + " when instanciating bean " + getName());
+            } else {
+                throw new ComponentDefinitionException("Multiple matching constructors found on class " + getType().getName() + " for arguments " + args + " when instanciating bean " + getName() + ": " + matches.keySet());
+            }
+        }
+
+        return instance;
+    }
+
+    private Map<Method, List<Object>> findMatchingMethods(Class type, String name, boolean instance, List<Object> args, List<ReifiedType> types) {
+        Map<Method, List<Object>> matches = new HashMap<Method, List<Object>>();
+        // Get constructors
+        List<Method> methods = new ArrayList<Method>(Arrays.asList(type.getMethods()));
+        // Discard any signature with wrong cardinality
+        for (Iterator<Method> it = methods.iterator(); it.hasNext();) {
+            Method mth = it.next();
+            if (!mth.getName().equals(name)) {
+                it.remove();
+            } else if (mth.getParameterTypes().length != args.size()) {
+                it.remove();
+            } else if (instance ^ !Modifier.isStatic(mth.getModifiers())) {
+                it.remove();
+            } else if (mth.isBridge()) {
+                it.remove();
+            }
+        }
+
+        // on some JVMs (J9) hidden static methods are returned by Class.getMethods so we need to weed them out
+        // to reduce ambiguity
+        if (!instance) {
+            methods = applyStaticHidingRules(methods);
+        }
+
+        // Find a direct match with assignment
+        if (matches.size() != 1) {
+            Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
+            for (Method mth : methods) {
+                boolean found = true;
+                List<Object> match = new ArrayList<Object>();
+                for (int i = 0; i < args.size(); i++) {
+                    ReifiedType argType = new GenericType(mth.getGenericParameterTypes()[i]);
+                    if (types.get(i) != null && !argType.getRawClass().equals(types.get(i).getRawClass())) {
+                        found = false;
+                        break;
+                    }
+                    //If the arg is an Unwrappered bean then we need to do the assignment check against the
+                    //unwrappered bean itself.
+                    Object arg = args.get(i);
+                    Object argToTest = arg;
+                    if(arg instanceof UnwrapperedBeanHolder)
+                        argToTest = ((UnwrapperedBeanHolder)arg).unwrapperedBean;
+                    if (!AggregateConverter.isAssignable(argToTest, argType)) {
+                        found = false;
+                        break;
+                    }
+                    try {
+                        match.add(convert(arg, mth.getGenericParameterTypes()[i]));
+                    } catch (Throwable t) {
+                        found = false;
+                        break;
+                    }
+                }
+                if (found) {
+                    nmatches.put(mth, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        // Find a direct match with conversion
+        if (matches.size() != 1) {
+            Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
+            for (Method mth : methods) {
+                boolean found = true;
+                List<Object> match = new ArrayList<Object>();
+                for (int i = 0; i < args.size(); i++) {
+                    ReifiedType argType = new GenericType(mth.getGenericParameterTypes()[i]);
+                    if (types.get(i) != null && !argType.getRawClass().equals(types.get(i).getRawClass())) {
+                        found = false;
+                        break;
+                    }
+                    try {
+                        Object val = convert(args.get(i), argType);
+                        match.add(val);
+                    } catch (Throwable t) {
+                        found = false;
+                        break;
+                    }
+                }
+                if (found) {
+                    nmatches.put(mth, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        // Start reordering with assignment
+        if (matches.size() != 1 && reorderArguments && args.size() > 1) {
+            Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
+            for (Method mth : methods) {
+                ArgumentMatcher matcher = new ArgumentMatcher(mth.getGenericParameterTypes(), false);
+                List<Object> match = matcher.match(args, types);
+                if (match != null) {
+                    nmatches.put(mth, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        // Start reordering with conversion
+        if (matches.size() != 1 && reorderArguments && args.size() > 1) {
+            Map<Method, List<Object>> nmatches = new HashMap<Method, List<Object>>();
+            for (Method mth : methods) {
+                ArgumentMatcher matcher = new ArgumentMatcher(mth.getGenericParameterTypes(), true);
+                List<Object> match = matcher.match(args, types);
+                if (match != null) {
+                    nmatches.put(mth, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+
+        return matches;
+    }
+
+    private static List<Method> applyStaticHidingRules(Collection<Method> methods) {
+        List<Method> result = new ArrayList<Method>(methods.size());
+        for (Method m : methods) {
+            boolean toBeAdded = true;
+
+            Iterator<Method> it = result.iterator();
+            inner: while (it.hasNext()) {
+                Method other = it.next();
+                if (hasIdenticalParameters(m, other)) {
+                    Class<?> mClass = m.getDeclaringClass();
+                    Class<?> otherClass = other.getDeclaringClass();
+
+                    if (mClass.isAssignableFrom(otherClass)) {
+                        toBeAdded = false;
+                        break inner;
+                    } else if (otherClass.isAssignableFrom(mClass)) {
+                        it.remove();
+                    }
+                }
+            }
+
+            if (toBeAdded) result.add(m);
+        }
+
+        return result;
+    }
+
+    private static boolean hasIdenticalParameters(Method one, Method two) {
+        Class<?>[] oneTypes = one.getParameterTypes();
+        Class<?>[] twoTypes = two.getParameterTypes();
+
+        if (oneTypes.length != twoTypes.length) return false;
+
+        for (int i=0; i<oneTypes.length; i++) {
+            if (!oneTypes[i].equals(twoTypes[i])) return false;
+        }
+
+        return true;
+    }
+
+    private Map<Constructor, List<Object>> findMatchingConstructors(Class type, List<Object> args, List<ReifiedType> types) {
+        Map<Constructor, List<Object>> matches = new HashMap<Constructor, List<Object>>();
+        // Get constructors
+        List<Constructor> constructors = new ArrayList<Constructor>(Arrays.asList(type.getConstructors()));
+        // Discard any signature with wrong cardinality
+        for (Iterator<Constructor> it = constructors.iterator(); it.hasNext();) {
+            if (it.next().getParameterTypes().length != args.size()) {
+                it.remove();
+            }
+        }
+        // Find a direct match with assignment
+        if (matches.size() != 1) {
+            Map<Constructor, List<Object>> nmatches = new HashMap<Constructor, List<Object>>();
+            for (Constructor cns : constructors) {
+                boolean found = true;
+                List<Object> match = new ArrayList<Object>();
+                for (int i = 0; i < args.size(); i++) {
+                    ReifiedType argType = new GenericType(cns.getGenericParameterTypes()[i]);
+                    if (types.get(i) != null && !argType.getRawClass().equals(types.get(i).getRawClass())) {
+                        found = false;
+                        break;
+                    }
+                    //If the arg is an Unwrappered bean then we need to do the assignment check against the
+                    //unwrappered bean itself.
+                    Object arg = args.get(i);
+                    Object argToTest = arg;
+                    if(arg instanceof UnwrapperedBeanHolder)
+                        argToTest = ((UnwrapperedBeanHolder)arg).unwrapperedBean;
+                    if (!AggregateConverter.isAssignable(argToTest, argType)) {
+                        found = false;
+                        break;
+                    }
+                    try {
+                        match.add(convert(arg, cns.getGenericParameterTypes()[i]));
+                    } catch (Throwable t) {
+                        found = false;
+                        break;
+                    }
+                }
+                if (found) {
+                    nmatches.put(cns, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        // Find a direct match with conversion
+        if (matches.size() != 1) {
+            Map<Constructor, List<Object>> nmatches = new HashMap<Constructor, List<Object>>();
+            for (Constructor cns : constructors) {
+                boolean found = true;
+                List<Object> match = new ArrayList<Object>();
+                for (int i = 0; i < args.size(); i++) {
+                    ReifiedType argType = new GenericType(cns.getGenericParameterTypes()[i]);
+                    if (types.get(i) != null && !argType.getRawClass().equals(types.get(i).getRawClass())) {
+                        found = false;
+                        break;
+                    }
+                    try {
+                        Object val = convert(args.get(i), argType);
+                        match.add(val);
+                    } catch (Throwable t) {
+                        found = false;
+                        break;
+                    }
+                }
+                if (found) {
+                    nmatches.put(cns, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        // Start reordering with assignment
+        if (matches.size() != 1 && reorderArguments && arguments.size() > 1) {
+            Map<Constructor, List<Object>> nmatches = new HashMap<Constructor, List<Object>>();
+            for (Constructor cns : constructors) {
+                ArgumentMatcher matcher = new ArgumentMatcher(cns.getGenericParameterTypes(), false);
+                List<Object> match = matcher.match(args, types);
+                if (match != null) {
+                    nmatches.put(cns, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        // Start reordering with conversion
+        if (matches.size() != 1 && reorderArguments && arguments.size() > 1) {
+            Map<Constructor, List<Object>> nmatches = new HashMap<Constructor, List<Object>>();
+            for (Constructor cns : constructors) {
+                ArgumentMatcher matcher = new ArgumentMatcher(cns.getGenericParameterTypes(), true);
+                List<Object> match = matcher.match(args, types);
+                if (match != null) {
+                    nmatches.put(cns, match);
+                }
+            }
+            if (nmatches.size() > 0) {
+                matches = nmatches;
+            }
+        }
+        return matches;
+    }
+
+    /**
+     * Returns init method (if any). Throws exception if the init-method was set explicitly on the bean
+     * and the method is not found on the instance.
+     */
+    protected Method getInitMethod(Object instance) throws ComponentDefinitionException {
+        Method method = null;
+        if (initMethod != null && initMethod.length() > 0) {
+            method = ReflectionUtils.getLifecycleMethod(instance.getClass(), initMethod);
+            if (method == null) {
+                throw new ComponentDefinitionException("Component '" + getName() + "' does not have init-method: " + initMethod);
+            }
+        }
+        return method;
+    }
+
+    /**
+     * Returns destroy method (if any). Throws exception if the destroy-method was set explicitly on the bean
+     * and the method is not found on the instance.
+     */
+    public Method getDestroyMethod(Object instance) throws ComponentDefinitionException {
+        Method method = null;
+        if (instance != null && destroyMethod != null && destroyMethod.length() > 0) {
+            method = ReflectionUtils.getLifecycleMethod(instance.getClass(), destroyMethod);
+            if (method == null) {
+                throw new ComponentDefinitionException("Component '" + getName() + "' does not have destroy-method: " + destroyMethod);
+            }
+        }
+        return method;
+    }
+
+    /**
+     * Small helper class, to construct a chain of BeanCreators.
+     * <br> 
+     * Each bean creator in the chain will return a bean that has been 
+     * processed by every BeanProcessor in the chain before it.
+     */
+    private static class BeanCreatorChain implements BeanProcessor.BeanCreator {
+        public enum ChainType{Before,After};
+        private final BeanProcessor.BeanCreator parentBeanCreator;
+        private final BeanProcessor parentBeanProcessor;
+        private final BeanMetadata beanData;
+        private final String beanName;
+        private final ChainType when;
+        public BeanCreatorChain(BeanProcessor.BeanCreator parentBeanCreator,
+                                BeanProcessor parentBeanProcessor,
+                                BeanMetadata beanData,
+                                String beanName,
+                                ChainType when){
+            this.parentBeanCreator = parentBeanCreator;
+            this.parentBeanProcessor = parentBeanProcessor;
+            this.beanData = beanData;
+            this.beanName = beanName;
+            this.when = when;
+        }
+
+        public Object getBean() {
+            Object previousBean = parentBeanCreator.getBean();
+            Object processed = null;
+            switch(when){
+                case Before :
+                    processed = parentBeanProcessor.beforeInit(previousBean, beanName, parentBeanCreator, beanData);
+                    break;
+                case After:
+                    processed = parentBeanProcessor.afterInit(previousBean, beanName, parentBeanCreator, beanData);
+                    break;
+            }
+            return processed;
+        }
+    }
+
+    private Object runBeanProcPreInit(Object obj){
+        String beanName = getName();
+        BeanMetadata beanData = (BeanMetadata) blueprintContainer
+                .getComponentDefinitionRegistry().getComponentDefinition(beanName);
+        List<BeanProcessor> processors = blueprintContainer.getProcessors(BeanProcessor.class);
+
+        //The start link of the chain, that provides the 
+        //original, unprocessed bean to the head of the chain.
+        BeanProcessor.BeanCreator initialBeanCreator = new BeanProcessor.BeanCreator() {
+            public Object getBean() {
+                Object obj = getInstance();
+                //getinit, getdestroy, addpartial object don't need calling again.
+                //however, property injection does.
+                setProperties(obj);
+                return obj;
+            }
+        };
+
+        BeanProcessor.BeanCreator currentCreator = initialBeanCreator;
+        for(BeanProcessor processor : processors){
+            obj = processor.beforeInit(obj, getName(), currentCreator, beanData);
+            currentCreator = new BeanCreatorChain(currentCreator, processor, beanData, beanName, BeanCreatorChain.ChainType.Before);
+        }
+        return obj;
+    }
+
+    private void runBeanProcInit(Method initMethod, Object obj){
+        // call init method
+        if (initMethod != null) {
+            try {
+                invoke(initMethod, obj, (Object[]) null);
+            } catch (Throwable t) {
+                throw new ComponentDefinitionException("Unable to intialize bean " + getName(), getRealCause(t));
+            }
+        }
+    }
+
+    private Object runBeanProcPostInit(Object obj){
+        String beanName = getName();
+        BeanMetadata beanData = (BeanMetadata) blueprintContainer
+                .getComponentDefinitionRegistry().getComponentDefinition(beanName);
+        List<BeanProcessor> processors = blueprintContainer.getProcessors(BeanProcessor.class);
+
+        //The start link of the chain, that provides the 
+        //original, unprocessed bean to the head of the chain.
+        BeanProcessor.BeanCreator initialBeanCreator = new BeanProcessor.BeanCreator() {
+            public Object getBean() {
+                Object obj = getInstance();
+                //getinit, getdestroy, addpartial object don't need calling again.
+                //however, property injection does.
+                setProperties(obj);
+                //as this is the post init chain, new beans need to go thru 
+                //the pre-init chain, and then have init called, before 
+                //being passed along the post-init chain.
+                obj = runBeanProcPreInit(obj);
+                runBeanProcInit(getInitMethod(obj), obj);
+                return obj;
+            }
+        };
+
+        BeanProcessor.BeanCreator currentCreator = initialBeanCreator;
+        for(BeanProcessor processor : processors){
+            obj = processor.afterInit(obj, getName(), currentCreator, beanData);
+            currentCreator = new BeanCreatorChain(currentCreator, processor, beanData, beanName, BeanCreatorChain.ChainType.After);
+        }
+        return obj;
+    }
+
+    private Object addInterceptors(final Object original, Collection<Class<?>> requiredInterfaces)
+            throws ComponentDefinitionException {
+
+        Object intercepted = null;
+        if(requiredInterfaces.isEmpty())
+            requiredInterfaces.add(original.getClass());
+
+        ComponentDefinitionRegistry reg = blueprintContainer
+                .getComponentDefinitionRegistry();
+        List<Interceptor> interceptors = reg.getInterceptors(interceptorLookupKey);
+        if (interceptors != null && interceptors.size() > 0) {
+            /* BLUEPRINT-NOOSGI
+            try {
+                Bundle b = FrameworkUtil.getBundle(original.getClass());
+                if (b == null) {
+                    // we have a class from the framework parent, so use our bundle for proxying.
+                    b = blueprintContainer.getBundleContext().getBundle();
+                }
+                intercepted = blueprintContainer.getProxyManager().createInterceptingProxy(b,
+                        requiredInterfaces, original, new Collaborator(interceptorLookupKey, interceptors));
+            } catch (org.apache.aries.proxy.UnableToProxyException e) {
+                Bundle b = blueprintContainer.getBundleContext().getBundle();
+                throw new ComponentDefinitionException("Unable to create proxy for bean " + name + " in bundle " + b.getSymbolicName() + " version " + b.getVersion(), e);
+            }
+            */
+            throw new ComponentDefinitionException("Unable to create proxy for bean " + name + ".  Not supported in blueprint-noosgi");
+        } else {
+            intercepted = original;
+        }
+        return intercepted;
+    }
+
+    @Override
+    protected Object internalCreate() throws ComponentDefinitionException {
+        /* BLUEPRINT-NOOSGI
+        if (factory instanceof ReferenceRecipe) {
+            ReferenceRecipe rr = (ReferenceRecipe) factory;
+            if (rr.getProxyChildBeanClasses() != null) {
+                return createProxyBean(rr);
+            }
+        }
+        */
+        return new UnwrapperedBeanHolder(internalCreate2(), this);
+    }
+
+    /* BLUEPRINT-NOOSGI
+    private Object createProxyBean(ReferenceRecipe rr) {
+        try {
+            VoidableCallable vc = new VoidableCallable();
+            rr.addVoidableChild(vc);
+            return blueprintContainer.getProxyManager().createDelegatingProxy(
+                    blueprintContainer.getBundleContext().getBundle(), rr.getProxyChildBeanClasses(),
+                    vc, vc.call());
+        } catch (UnableToProxyException e) {
+            throw new ComponentDefinitionException(e);
+        }
+    }
+    */
+
+    private Object internalCreate2() throws ComponentDefinitionException {
+
+        instantiateExplicitDependencies();
+
+        Object obj = getInstance();
+
+        // check for init lifecycle method (if any)
+        Method initMethod = getInitMethod(obj);
+
+        // check for destroy lifecycle method (if any)
+        getDestroyMethod(obj);
+
+        // Add partially created object to the container
+//        if (initMethod == null) {
+        addPartialObject(obj);
+//        }
+
+        // inject properties
+        setProperties(obj);
+
+        obj = runBeanProcPreInit(obj);
+
+        runBeanProcInit(initMethod, obj);
+
+        obj = runBeanProcPostInit(obj);
+
+        //Replaced by calling wrap on the UnwrapperedBeanHolder
+//        obj = addInterceptors(obj);
+
+        return obj;
+    }
+
+    static Object wrap(UnwrapperedBeanHolder holder, Collection<Class<?>> requiredViews) {
+        return holder.recipe.addInterceptors(holder.unwrapperedBean, requiredViews);
+    }
+
+    static Object wrap(UnwrapperedBeanHolder holder, Class<?> requiredView) {
+        if(requiredView == Object.class) {
+            //We don't know what we need so we have to do everything
+            return holder.recipe.addInterceptors(holder.unwrapperedBean, new ArrayList<Class<?>>(1));
+        } else {
+            return holder.recipe.addInterceptors(holder.unwrapperedBean, ProxyUtils.asList(requiredView));
+        }
+    }
+
+
+    @Override
+    public void destroy(Object obj) {
+        if (!(obj instanceof UnwrapperedBeanHolder)) {
+            LOGGER.warn("Object to be destroyed is not an instance of UnwrapperedBeanHolder, type: " + obj);
+            return;
+        }
+
+        obj = ((UnwrapperedBeanHolder)obj).unwrapperedBean;
+
+        for (BeanProcessor processor : blueprintContainer.getProcessors(BeanProcessor.class)) {
+            processor.beforeDestroy(obj, getName());
+        }
+        try {
+            Method method = getDestroyMethod(obj);
+            if (method != null) {
+                invoke(method, obj, (Object[]) null);
+            }
+        } catch (ComponentDefinitionException e) {
+            // This exception occurs if the destroy method does not exist, so we just output the exception message.
+            LOGGER.error(e.getMessage());
+        } catch (InvocationTargetException ite) {
+            /* BLUEPRINT-OSGI
+            Throwable t = ite.getTargetException();
+            BundleContext ctx = blueprintContainer.getBundleContext();
+            Bundle b = ctx.getBundle();
+            String bundleIdentifier = b.getSymbolicName() + '/' + b.getVersion();
+            LOGGER.error("The blueprint bean " + getName() + " in bundle " + bundleIdentifier + " incorrectly threw an exception from its destroy method.", t);
+            */
+            Throwable t = ite.getTargetException();
+            LOGGER.error("The blueprint bean " + getName() + " in incorrectly threw an exception from its destroy method.", t);
+        } catch (Exception e) {
+            /* BLUEPRINT-OSGI
+            BundleContext ctx = blueprintContainer.getBundleContext();
+            Bundle b = ctx.getBundle();
+            String bundleIdentifier = b.getSymbolicName() + '/' + b.getVersion();
+            LOGGER.error("An exception occurred while calling the destroy method of the blueprint bean " + getName() + " in bundle " + bundleIdentifier + ".", getRealCause(e));
+            */
+            LOGGER.error("An exception occurred while calling the destroy method of the blueprint bean " + getName() + ".", getRealCause(e));
+        }
+        for (BeanProcessor processor : blueprintContainer.getProcessors(BeanProcessor.class)) {
+            processor.afterDestroy(obj, getName());
+        }
+    }
+
+    public void setProperties(Object instance) throws ComponentDefinitionException {
+        // clone the properties so they can be used again
+        Map<String,Object> propertyValues = new LinkedHashMap<String,Object>(properties);
+        setProperties(propertyValues, instance, instance.getClass());
+    }
+
+    public Class getType() {
+        if (type instanceof Class) {
+            return (Class) type;
+        } else if (type instanceof String) {
+            return loadClass((String) type);
+        } else {
+            return null;
+        }
+    }
+
+    private void setProperties(Map<String, Object> propertyValues, Object instance, Class clazz) {
+        // set remaining properties
+        for (Map.Entry<String, Object> entry : propertyValues.entrySet()) {
+            String propertyName = entry.getKey();
+            Object propertyValue = entry.getValue();
+
+            setProperty(instance, clazz, propertyName, propertyValue);
+        }
+
+    }
+
+    private void setProperty(Object instance, Class clazz, String propertyName, Object propertyValue) {
+        String[] names = propertyName.split("\\.");
+        for (int i = 0; i < names.length - 1; i++) {
+            PropertyDescriptor pd = getPropertyDescriptor(clazz, names[i]);
+            if (pd.allowsGet()) {
+                try {
+                    instance = pd.get(instance, blueprintContainer);
+                } catch (Exception e) {
+                    throw new ComponentDefinitionException("Error getting property: " + names[i] + " on bean " + getName() + " when setting property " + propertyName + " on class " + clazz.getName(), getRealCause(e));
+                }
+                if (instance == null) {
+                    throw new ComponentDefinitionException("Error setting compound property " + propertyName + " on bean " + getName() + ". Property " + names[i] + " is null");
+                }
+                clazz = instance.getClass();
+            } else {
+                throw new ComponentDefinitionException("No getter for " + names[i] + " property on bean " + getName() + " when setting property " + propertyName + " on class " + clazz.getName());
+            }
+        }
+
+        // Instantiate value
+        if (propertyValue instanceof Recipe) {
+            propertyValue = ((Recipe) propertyValue).create();
+        }
+
+        final PropertyDescriptor pd = getPropertyDescriptor(clazz, names[names.length - 1]);
+        if (pd.allowsSet()) {
+            try {
+                pd.set(instance, propertyValue, blueprintContainer);
+            } catch (Exception e) {
+                throw new ComponentDefinitionException("Error setting property: " + pd, getRealCause(e));
+            }
+        } else {
+            throw new ComponentDefinitionException("No setter for " + names[names.length - 1] + " property");
+        }
+    }
+
+    private ReflectionUtils.PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String name) {
+        for (ReflectionUtils.PropertyDescriptor pd : ReflectionUtils.getPropertyDescriptors(clazz, allowsFieldInjection)) {
+            if (pd.getName().equals(name)) {
+                return pd;
+            }
+        }
+        throw new ComponentDefinitionException("Unable to find property descriptor " + name + " on class " + clazz.getName());
+    }
+
+    private Object invoke(Method method, Object instance, Object... args) throws Exception {
+        return ReflectionUtils.invoke(blueprintContainer.getAccessControlContext(), method, instance, args);
+    }
+
+    private Object newInstance(Constructor constructor, Object... args) throws Exception {
+        return ReflectionUtils.newInstance(blueprintContainer.getAccessControlContext(), constructor, args);
+    }
+
+    private static Object UNMATCHED = new Object();
+
+    private class ArgumentMatcher {
+
+        private final List<TypeEntry> entries;
+        private final boolean convert;
+
+        public ArgumentMatcher(Type[] types, boolean convert) {
+            entries = new ArrayList<TypeEntry>();
+            for (Type type : types) {
+                entries.add(new TypeEntry(new GenericType(type)));
+            }
+            this.convert = convert;
+        }
+
+        public List<Object> match(List<Object> arguments, List<ReifiedType> forcedTypes) {
+            if (find(arguments, forcedTypes)) {
+                return getArguments();
+            }
+            return null;
+        }
+
+        private List<Object> getArguments() {
+            List<Object> list = new ArrayList<Object>();
+            for (TypeEntry entry : entries) {
+                if (entry.argument == UNMATCHED) {
+                    throw new RuntimeException("There are unmatched types");
+                } else {
+                    list.add(entry.argument);
+                }
+            }
+            return list;
+        }
+
+        private boolean find(List<Object> arguments, List<ReifiedType> forcedTypes) {
+            if (entries.size() == arguments.size()) {
+                boolean matched = true;
+                for (int i = 0; i < arguments.size() && matched; i++) {
+                    matched = find(arguments.get(i), forcedTypes.get(i));
+                }
+                return matched;
+            }
+            return false;
+        }
+
+        private boolean find(Object arg, ReifiedType forcedType) {
+            for (TypeEntry entry : entries) {
+                Object val = arg;
+                if (entry.argument != UNMATCHED) {
+                    continue;
+                }
+                if (forcedType != null) {
+                    if (!forcedType.equals(entry.type)) {
+                        continue;
+                    }
+                } else if (arg != null) {
+                    if (convert) {
+
+                        if(canConvert(arg, entry.type)) {
+                            try {
+                                val = convert(arg, entry.type);
+                            } catch (Exception e) {
+                                throw new ComponentDefinitionException(e);
+                            }
+                        } else {
+                            continue;
+                        }
+                    } else {
+                        UnwrapperedBeanHolder holder = null;
+                        if(arg instanceof UnwrapperedBeanHolder) {
+                            holder = (UnwrapperedBeanHolder)arg;
+                            arg = holder.unwrapperedBean;
+                        }
+                        if (!AggregateConverter.isAssignable(arg, entry.type)) {
+                            continue;
+                        } else if (holder != null) {
+                            val = wrap(holder, entry.type.getRawClass());
+                        }
+                    }
+                }
+                entry.argument = val;
+                return true;
+            }
+            return false;
+        }
+
+    }
+
+    private static class TypeEntry {
+
+        private final ReifiedType type;
+        private Object argument;
+
+        public TypeEntry(ReifiedType type) {
+            this.type = type;
+            this.argument = UNMATCHED;
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java b/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
new file mode 100644
index 0000000..eec1ccd
--- /dev/null
+++ b/src/main/java/org/apache/aries/blueprint/container/BlueprintContainerImpl.java
@@ -0,0 +1,351 @@
+/*
+ * 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.aries.blueprint.container;
+
+import org.apache.aries.blueprint.ComponentDefinitionRegistryProcessor;
+import org.apache.aries.blueprint.ExtendedBeanMetadata;
+import org.apache.aries.blueprint.Processor;
+import org.apache.aries.blueprint.di.Recipe;
+import org.apache.aries.blueprint.di.Repository;
+import org.apache.aries.blueprint.parser.ComponentDefinitionRegistryImpl;
+import org.apache.aries.blueprint.parser.Parser;
+import org.apache.aries.blueprint.reflect.MetadataUtil;
+import org.apache.aries.blueprint.reflect.PassThroughMetadataImpl;
+import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+import org.osgi.service.blueprint.container.Converter;
+import org.osgi.service.blueprint.container.NoSuchComponentException;
+import org.osgi.service.blueprint.reflect.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URI;
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class BlueprintContainerImpl implements ExtendedBlueprintContainer {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(BlueprintContainerImpl.class);
+
+    private final ClassLoader loader;
+    private final List<URL> resources;
+    private final AggregateConverter converter;
+    private final ComponentDefinitionRegistryImpl componentDefinitionRegistry;
+    private final AtomicBoolean destroyed = new AtomicBoolean(false);
+    private final IdSpace tempRecipeIdSpace = new IdSpace();
+    private BlueprintRepository repository;
+    private List<Processor> processors = new ArrayList<Processor>();
+    private Map<String, String> properties;
+
+    public BlueprintContainerImpl(ClassLoader loader, List<URL> resources) throws Exception {
+        this(loader, resources, null, true);
+    }
+
+    public BlueprintContainerImpl(ClassLoader loader, List<URL> resources, boolean init) throws Exception {
+        this(loader, resources, null, init);
+    }
+
+    public BlueprintContainerImpl(ClassLoader loader, List<URL> resources, Map<String, String> properties, boolean init) throws Exception {
+        this.loader = loader;
+        this.converter = new AggregateConverter(this);
+        this.componentDefinitionRegistry = new ComponentDefinitionRegistryImpl();
+        this.resources = resources;
+        this.properties = properties;
+        if (init) {
+            init();
+        }
+    }
+
+    public String getProperty(String key) {
+        if (properties != null && properties.containsKey(key)) {
+            return properties.get(key);
+        }
+        return System.getProperty(key);
+    }
+
+    public void init() throws Exception {
+        // Parse xml resources
+        Parser parser = new Parser();
+        parser.parse(getResources());
+        // Create handler set
+        SimpleNamespaceHandlerSet handlerSet = new SimpleNamespaceHandlerSet();
+        // Check namespaces
+        Set<URI> namespaces = parser.getNamespaces();
+        Set<URI> unsupported = new LinkedHashSet<URI>();
+        for (URI ns : namespaces) {
+            if (!handlerSet.getNamespaces().contains(ns)) {
+                unsupported.add(ns);
+            }
+        }
+        if (unsupported.size() > 0) {
+            throw new IllegalArgumentException("Unsupported namespaces: " + unsupported.toString());
+        }
+        // Add predefined beans
+        componentDefinitionRegistry.registerComponentDefinition(new PassThroughMetadataImpl("blueprintContainer", this));
+        // Validate
+        parser.validate(handlerSet.getSchema());
+        // Populate
+        parser.populate(handlerSet, componentDefinitionRegistry);
+        // Create repository
+        repository = new NoOsgiRecipeBuilder(this, tempRecipeIdSpace).createRepository();
+        // Processors handling
+        processTypeConverters();
+        processProcessors();
+        // Instantiate eager singletons
+        instantiateEagerComponents();
+    }
+
+    public void destroy() {
+        repository.destroy();
+    }
+
+    public List<URL> getResources() {
+        return resources;
+    }
+
+    public Converter getConverter() {
+        return converter;
+    }
+
+    public Class loadClass(String name) throws ClassNotFoundException {
+        return loader.loadClass(name);
+    }
+
+    public URL getResource(String name) {
+        return loader.getResource(name);
+    }
+
+    public AccessControlContext getAccessControlContext() {
+        return null;
+    }
+
+    public ComponentDefinitionRegistryImpl getComponentDefinitionRegistry() {
+        return componentDefinitionRegistry;
+    }
+
+    public <T extends Processor> List<T> getProcessors(Class<T> clazz) {
+        List<T> p = new ArrayList<T>();
+        for (Processor processor : processors) {
+            if (clazz.isInstance(processor)) {
+                p.add(clazz.cast(processor));
+            }
+        }
+        return p;
+    }
+
+    public Set<String> getComponentIds() {
+        return new LinkedHashSet<String>(componentDefinitionRegistry.getComponentDefinitionNames());
+    }
+
+    public Object getComponentInstance(String id) {
+        if (repository == null || destroyed.get()) {
+            throw new NoSuchComponentException(id);
+        }
+        try {
+            LOGGER.debug("Instantiating component {}", id);
+            return repository.create(id);
+        } catch (NoSuchComponentException e) {
+            throw e;
+        } catch (ComponentDefinitionException e) {
+            throw e;
+        } catch (Throwable t) {
+            throw new ComponentDefinitionException("Cound not create component instance for " + id, t);
+        }
+    }
+
+    public ComponentMetadata getComponentMetadata(String id) {
+        ComponentMetadata metadata = componentDefinitionRegistry.getComponentDefinition(id);
+        if (metadata == null) {
+            throw new NoSuchComponentException(id);
+        }
+        return metadata;
+    }
+
+    public <T extends ComponentMetadata> Collection<T> getMetadata(Class<T> clazz) {
+        Collection<T> metadatas = new ArrayList<T>();
+        for (String name : componentDefinitionRegistry.getComponentDefinitionNames()) {
+            ComponentMetadata component = componentDefinitionRegistry.getComponentDefinition(name);
+            getMetadata(clazz, component, metadatas);
+        }
+        metadatas = Collections.unmodifiableCollection(metadatas);
+        return metadatas;
+    }
+
+    public BlueprintRepository getRepository() {
+        return repository;
+    }
+
+    private <T extends ComponentMetadata> void getMetadata(Class<T> clazz, Metadata component, Collection<T> metadatas) {
+        if (component == null) {
+            return;
+        }
+        if (clazz.isInstance(component)) {
+            metadatas.add(clazz.cast(component));
+        }
+        if (component instanceof BeanMetadata) {
+            getMetadata(clazz, ((BeanMetadata) component).getFactoryComponent(), metadatas);
+            for (BeanArgument arg : ((BeanMetadata) component).getArguments()) {
+                getMetadata(clazz, arg.getValue(), metadatas);
+            }
+            for (BeanProperty prop : ((BeanMetadata) component).getProperties()) {
+                getMetadata(clazz, prop.getValue(), metadatas);
+            }
+        }
+        if (component instanceof CollectionMetadata) {
+            for (Metadata m : ((CollectionMetadata) component).getValues()) {
+                getMetadata(clazz, m, metadatas);
+            }
+        }
+        if (component instanceof MapMetadata) {
+            for (MapEntry m : ((MapMetadata) component).getEntries()) {
+                getMetadata(clazz, m.getKey(), metadatas);
+                getMetadata(clazz, m.getValue(), metadatas);
+            }
+        }
+        if (component instanceof PropsMetadata) {
+            for (MapEntry m : ((PropsMetadata) component).getEntries()) {
+                getMetadata(clazz, m.getKey(), metadatas);
+                getMetadata(clazz, m.getValue(), metadatas);
+            }
+        }
+        if (component instanceof ServiceReferenceMetadata) {
+            for (ReferenceListener l : ((ServiceReferenceMetadata) component).getReferenceListeners()) {
+                getMetadata(clazz, l.getListenerComponent(), metadatas);
+            }
+        }
+        if (component instanceof ServiceMetadata) {
+            getMetadata(clazz, ((ServiceMetadata) component).getServiceComponent(), metadatas);
+            for (MapEntry m : ((ServiceMetadata) component).getServiceProperties()) {
+                getMetadata(clazz, m.getKey(), metadatas);
+                getMetadata(clazz, m.getValue(), metadatas);
+            }
+            for (RegistrationListener l : ((ServiceMetadata) component).getRegistrationListeners()) {
+                getMetadata(clazz, l.getListenerComponent(), metadatas);
+            }
+        }
+    }
+
+    private void processTypeConverters() throws Exception {
+        List<String> typeConverters = new ArrayList<String>();
+        for (Target target : componentDefinitionRegistry.getTypeConverters()) {
+            if (target instanceof ComponentMetadata) {
+                typeConverters.add(((ComponentMetadata) target).getId());
+            } else if (target instanceof RefMetadata) {
+                typeConverters.add(((RefMetadata) target).getComponentId());
+            } else {
+                throw new ComponentDefinitionException("Unexpected metadata for type converter: " + target);
+            }
+        }
+
+        Map<String, Object> objects = repository.createAll(typeConverters, Arrays.<Class<?>>asList(Converter.class));
+        for (String name : typeConverters) {
+            Object obj = objects.get(name);
+            if (obj instanceof Converter) {
+                converter.registerConverter((Converter) obj);
+            } else {
+                throw new ComponentDefinitionException("Type converter " + obj + " does not implement the " + Converter.class.getName() + " interface");
+            }
+        }
+    }
+
+    private void processProcessors() throws Exception {
+        // Instantiate ComponentDefinitionRegistryProcessor and BeanProcessor
+        for (BeanMetadata bean : getMetadata(BeanMetadata.class)) {
+            if (bean instanceof ExtendedBeanMetadata && !((ExtendedBeanMetadata) bean).isProcessor()) {
+                continue;
+            }
+
+            Class clazz = null;
+            if (bean instanceof ExtendedBeanMetadata) {
+                clazz = ((ExtendedBeanMetadata) bean).getRuntimeClass();
+            }
+            if (clazz == null && bean.getClassName() != null) {
+                clazz = loadClass(bean.getClassName());
+            }
+            if (clazz == null) {
+                continue;
+            }
+
+            if (ComponentDefinitionRegistryProcessor.class.isAssignableFrom(clazz)) {
+                Object obj = repository.create(bean.getId(), Arrays.<Class<?>>asList(ComponentDefinitionRegistryProcessor.class));
+                ((ComponentDefinitionRegistryProcessor) obj).process(componentDefinitionRegistry);
+            } else if (Processor.class.isAssignableFrom(clazz)) {
+                Object obj = repository.create(bean.getId(), Arrays.<Class<?>>asList(Processor.class));
+                this.processors.add((Processor) obj);
+            } else {
+                continue;
+            }
+            updateUninstantiatedRecipes();
+        }
+    }
+    private void updateUninstantiatedRecipes() {
+        Repository tmpRepo = new NoOsgiRecipeBuilder(this, tempRecipeIdSpace).createRepository();
+
+        LOGGER.debug("Updating blueprint repository");
+
+        for (String name : repository.getNames()) {
+            if (repository.getInstance(name) == null) {
+                LOGGER.debug("Removing uninstantiated recipe {}", new Object[] { name });
+                repository.removeRecipe(name);
+            } else {
+                LOGGER.debug("Recipe {} is already instantiated", new Object[] { name });
+            }
+        }
+
+        for (String name : tmpRepo.getNames()) {
+            if (repository.getInstance(name) == null) {
+                LOGGER.debug("Adding new recipe {}", new Object[] { name });
+                Recipe r = tmpRepo.getRecipe(name);
+                if (r != null) {
+                    repository.putRecipe(name, r);
+                }
+            } else {
+                LOGGER.debug("Recipe {} is already instantiated and cannot be updated", new Object[] { name });
+            }
+        }
+    }
+
+    protected void instantiateEagerComponents() {
+        List<String> components = new ArrayList<String>();
+        for (String name : componentDefinitionRegistry.getComponentDefinitionNames()) {
+            ComponentMetadata component = componentDefinitionRegistry.getComponentDefinition(name);
+            boolean eager = component.getActivation() == ComponentMetadata.ACTIVATION_EAGER;
+            if (component instanceof BeanMetadata) {
+                BeanMetadata local = (BeanMetadata) component;
+                eager &= MetadataUtil.isSingletonScope(local);
+            }
+            if (eager) {
+                components.add(name);
+            }
+        }
+        LOGGER.debug("Instantiating components: {}", components);
+        try {
+            repository.createAll(components);
+        } catch (ComponentDefinitionException e) {
+            throw e;
+        } catch (Throwable t) {
+            throw new ComponentDefinitionException("Unable to instantiate components", t);
+        }
+    }
+
+
+
+}
diff --git a/src/main/java/org/apache/aries/blueprint/container/GenericType.java b/src/main/java/org/apache/aries/blueprint/container/GenericType.java
new file mode 100644
index 0000000..30ef440
--- /dev/null
+++ b/src/main/java/org/apache/aries/blueprint/container/GenericType.java
@@ -0,0 +1,230 @@
+/**
+ *
+ * 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.aries.blueprint.container;
+
+import org.apache.aries.blueprint.di.ExecutionContext;
+import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
+import org.osgi.service.blueprint.container.ReifiedType;
+
+import java.lang.reflect.*;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * XXXX: Currently, in case of arrays getActualTypeArgument(0) returns something similar to what
+ * Class.getComponentType() does for arrays.  I don't think this is quite right since getActualTypeArgument()
+ * should return the given parameterized type not the component type. Need to check this behavior with the spec.
+ */
+public class GenericType extends ReifiedType {
+
+    private static final GenericType[] EMPTY = new GenericType[0];
+
+    private static final Map<String, Class> primitiveClasses = new HashMap<String, Class>();
+
+    static {
+        primitiveClasses.put("int", int.class);
+        primitiveClasses.put("short", short.class);
+        primitiveClasses.put("long", long.class);
+        primitiveClasses.put("byte", byte.class);
+        primitiveClasses.put("char", char.class);
+        primitiveClasses.put("float", float.class);
+        primitiveClasses.put("double", double.class);
+        primitiveClasses.put("boolean", boolean.class);
+    }
+
+    private GenericType[] parameters;
+
+    public GenericType(Type type) {
+        this(getConcreteClass(type), parametersOf(type));
+    }
+
+    public GenericType(Class clazz, GenericType... parameters) {
+        super(clazz);
+        this.parameters = parameters;
+    }
+
+    public static GenericType parse(String rawType, final Object loader) throws ClassNotFoundException, IllegalArgumentException {
+        final String type = rawType.trim();
+        // Check if this is an array
+        if (type.endsWith("[]")) {
+            GenericType t = parse(type.substring(0, type.length() - 2), loader);
+            return new GenericType(Array.newInstance(t.getRawClass(), 0).getClass(), t);
+        }
+        // Check if this is a generic
+        int genericIndex = type.indexOf('<');
+        if (genericIndex > 0) {
+            if (!type.endsWith(">")) {
+                throw new IllegalArgumentException("Can not load type: " + type);
+            }
+            GenericType base = parse(type.substring(0, genericIndex), loader);
+            String[] params = type.substring(genericIndex + 1, type.length() - 1).split(",");
+            GenericType[] types = new GenericType[params.length];
+            for (int i = 0; i < params.length; i++) {
+                types[i] = parse(params[i], loader);
+            }
+            return new GenericType(base.getRawClass(), types);
+        }
+        // Primitive
+        if (primitiveClasses.containsKey(type)) {
+            return new GenericType(primitiveClasses.get(type));
+        }
+        // Class
+        if (loader instanceof ClassLoader) {
+            return new GenericType(((ClassLoader) loader).loadClass(type));
+        } else if (loader instanceof ExecutionContext) {
+            return new GenericType(((ExecutionContext) loader).loadClass(type));
+        } else if (loader instanceof ExtendedBlueprintContainer) {
+            return new GenericType(((ExtendedBlueprintContainer) loader).loadClass(type));
+        } else {
+            throw new IllegalArgumentException("Unsupported loader: " + loader);
+        }
+    }
+
+    @Override
+    public ReifiedType getActualTypeArgument(int i) {
+        if (parameters.length == 0) {
+            return super.getActualTypeArgument(i);
+        }
+        return parameters[i];
+    }
+
+    @Override
+    public int size() {
+        return parameters.length;
+    }
+
+    @Override
+    public String toString() {
+        Class cl = getRawClass();
+        if (cl.isArray()) {
+            if (parameters.length > 0) {
+                return parameters[0].toString() + "[]";
+            } else {
+                return cl.getComponentType().getName() + "[]";
+            }
+        }
+        if (parameters.length > 0) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(cl.getName());
+            sb.append("<");
+            for (int i = 0; i < parameters.length; i++) {
+                if (i > 0) {
+                    sb.append(",");
+                }
+                sb.append(parameters[i].toString());
+            }
+            sb.append(">");
+            return sb.toString();
+        }
+        return cl.getName();
+    }
+
+    public boolean equals(Object object) {
+        if (!(object instanceof GenericType)) {
+            return false;
+        }
+        GenericType other = (GenericType) object;
+        if (getRawClass() != other.getRawClass()) {
+            return false;
+        }
+        if (parameters == null) {
+            return (other.parameters == null);
+        } else {
+            if (other.parameters == null) {
+                return false;
+            }
+            if (parameters.length != other.parameters.length) {
+                return false;
+            }
+            for (int i = 0; i < parameters.length; i++) {
+                if (!parameters[i].equals(other.parameters[i])) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    static GenericType[] parametersOf(Type type) {
+        if (type instanceof Class) {
+            Class clazz = (Class) type;
+            if (clazz.isArray()) {
+                GenericType t = new GenericType(clazz.getComponentType());
+                if (t.size() > 0) {
+                    return new GenericType[] { t };
+                } else {
+                    return EMPTY;
+                }
+            } else {
+                return EMPTY;
+            }
+        }
+        if (type instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType) type;
+            Type [] parameters = pt.getActualTypeArguments();
+            GenericType[] gts = new GenericType[parameters.length];
+            for ( int i =0; i<gts.length; i++) {
+                gts[i] = new GenericType(parameters[i]);
+            }
+            return gts;
+        }
+        if (type instanceof GenericArrayType) {
+            return new GenericType[] { new GenericType(((GenericArrayType) type).getGenericComponentType()) };
+        }
+        if (type instanceof WildcardType) {
+            return EMPTY;
+        }
+        if (type instanceof TypeVariable) {
+            return EMPTY;
+        }
+        throw new IllegalStateException();
+    }
+
+    static Class<?> getConcreteClass(Type type) {
+        Type ntype = collapse(type);
+        if ( ntype instanceof Class )
+            return (Class<?>) ntype;
+
+        if ( ntype instanceof ParameterizedType )
+            return getConcreteClass(collapse(((ParameterizedType)ntype).getRawType()));
+
+        throw new RuntimeException("Unknown type " + type );
+    }
+
+    static Type collapse(Type target) {
+        if (target instanceof Class || target instanceof ParameterizedType ) {
+            return target;
+        } else if (target instanceof TypeVariable) {
+            return collapse(((TypeVariable<?>) target).getBounds()[0]);
+        } else if (target instanceof GenericArrayType) {
+            Type t = collapse(((GenericArrayType) target)
+                    .getGenericComponentType());
+            while ( t instanceof ParameterizedType )
+                t = collapse(((ParameterizedType)t).getRawType());
+            return Array.newInstance((Class<?>)t, 0).getClass();
+        } else if (target instanceof WildcardType) {
+            WildcardType wct = (WildcardType) target;
+            if (wct.getLowerBounds().length == 0)
+                return collapse(wct.getUpperBounds()[0]);
+            else
+                return collapse(wct.getLowerBounds()[0]);
+        }
+        throw new RuntimeException("Huh? " + target);
+    }
+
+}
diff --git a/src/main/java/org/apache/aries/blueprint/container/NoOsgiBlueprintRepository.java b/src/main/java/org/apache/aries/blueprint/container/NoOsgiBlueprintRepository.java
new file mode 100644
index 0000000..a70ad32
--- /dev/null
+++ b/src/main/java/org/apache/aries/blueprint/container/NoOsgiBlueprintRepository.java
@@ -0,0 +1,49 @@
+/*
+ * 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.aries.blueprint.container;
+
+import org.apache.aries.blueprint.di.CollectionRecipe;
+import org.apache.aries.blueprint.di.IdRefRecipe;
+import org.apache.aries.blueprint.di.Recipe;
+import org.apache.aries.blueprint.di.RefRecipe;
+import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+
+public class NoOsgiBlueprintRepository extends BlueprintRepository {
+
+    public NoOsgiBlueprintRepository(ExtendedBlueprintContainer container) {
+        super(container);
+    }
+
+    @Override
+    public void validate() {
+        for (Recipe recipe : getAllRecipes()) {
+            // Check that references are satisfied
+            String ref = null;
+            if (recipe instanceof RefRecipe) {
+                ref = ((RefRecipe) recipe).getIdRef();
+            } else if (recipe instanceof IdRefRecipe) {
+                ref = ((IdRefRecipe) recipe).getIdRef();
+            }
+            if (ref != null && getRecipe(ref) == null) {
+                throw new ComponentDefinitionException("Unresolved ref/idref to component: " + ref);
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/apache/aries/blueprint/container/NoOsgiRecipeBuilder.java b/src/main/java/org/apache/aries/blueprint/container/NoOsgiRecipeBuilder.java
new file mode 100644
index 0000000..6235f3c
--- /dev/null
+++ b/src/main/java/org/apache/aries/blueprint/container/NoOsgiRecipeBuilder.java
@@ -0,0 +1,261 @@
+/*
+ * 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.aries.blueprint.container;
+
+import org.apache.aries.blueprint.ComponentDefinitionRegistry;
+import org.apache.aries.blueprint.ExtendedBeanMetadata;
+import org.apache.aries.blueprint.PassThroughMetadata;
+import org.apache.aries.blueprint.di.*;
+import org.apache.aries.blueprint.ext.ComponentFactoryMetadata;
+import org.apache.aries.blueprint.ext.DependentComponentFactoryMetadata;
+import org.apache.aries.blueprint.reflect.MetadataUtil;
+import org.apache.aries.blueprint.utils.ServiceListener;
+import org.osgi.service.blueprint.reflect.*;
+
+import java.util.*;
+
+public class NoOsgiRecipeBuilder {
+
+    private final Set<String> names = new HashSet<String>();
+    private final BlueprintContainerImpl blueprintContainer;
+    private final ComponentDefinitionRegistry registry;
+    private final IdSpace recipeIdSpace;
+
+    public NoOsgiRecipeBuilder(BlueprintContainerImpl blueprintContainer, IdSpace recipeIdSpace) {
+        this.recipeIdSpace = recipeIdSpace;
+        this.blueprintContainer = blueprintContainer;
+        this.registry = blueprintContainer.getComponentDefinitionRegistry();
+    }
+
+    public BlueprintRepository createRepository() {
+        BlueprintRepository repository = new NoOsgiBlueprintRepository(blueprintContainer);
+        // Create component recipes
+        for (String name : registry.getComponentDefinitionNames()) {
+            ComponentMetadata component = registry.getComponentDefinition(name);
+            Recipe recipe = createRecipe(component);
+            repository.putRecipe(recipe.getName(), recipe);
+        }
+        repository.validate();
+        return repository;
+    }
+
+    public Recipe createRecipe(ComponentMetadata component) {
+
+        // Custom components should be handled before built-in ones
+        // in case we have a custom component that also implements a built-in metadata
+
+        if (component instanceof DependentComponentFactoryMetadata) {
+            return createDependentComponentFactoryMetadata((DependentComponentFactoryMetadata) component);
+        } else if (component instanceof ComponentFactoryMetadata) {
+            return createComponentFactoryMetadata((ComponentFactoryMetadata) component);
+        } else if (component instanceof BeanMetadata) {
+            return createBeanRecipe((BeanMetadata) component);
+        } else if (component instanceof ServiceMetadata) {
+            throw new IllegalArgumentException("OSGi services are not supported");
+        } else if (component instanceof ReferenceMetadata) {
+            throw new IllegalArgumentException("OSGi references are not supported");
+        } else if (component instanceof ReferenceListMetadata) {
+            throw new IllegalArgumentException("OSGi references are not supported");
+        } else if (component instanceof PassThroughMetadata) {
+            return createPassThroughRecipe((PassThroughMetadata) component);
+        } else {
+            throw new IllegalStateException("Unsupported component type " + component.getClass());
+        }
+    }
+
+    private Recipe createComponentFactoryMetadata(ComponentFactoryMetadata metadata) {
+        return new ComponentFactoryRecipe<ComponentFactoryMetadata>(
+                metadata.getId(), metadata, blueprintContainer, getDependencies(metadata));
+    }
+
+    private Recipe createDependentComponentFactoryMetadata(DependentComponentFactoryMetadata metadata) {
+        return new DependentComponentFactoryRecipe(
+                metadata.getId(), metadata, blueprintContainer, getDependencies(metadata));
+    }
+
+    private List<Recipe> getDependencies(ComponentMetadata metadata) {
+        List<Recipe> deps = new ArrayList<Recipe>();
+        for (String name : metadata.getDependsOn()) {
+            deps.add(new RefRecipe(getName(null), name));
+        }
+        return deps;
+    }
+
+    private Recipe createPassThroughRecipe(PassThroughMetadata passThroughMetadata) {
+        return new PassThroughRecipe(getName(passThroughMetadata.getId()),
+                passThroughMetadata.getObject());
+    }
+
+    private Object getBeanClass(BeanMetadata beanMetadata) {
+        if (beanMetadata instanceof ExtendedBeanMetadata) {
+            ExtendedBeanMetadata extBeanMetadata = (ExtendedBeanMetadata) beanMetadata;
+            if (extBeanMetadata.getRuntimeClass() != null) {
+                return extBeanMetadata.getRuntimeClass();
+            }
+        }
+        return beanMetadata.getClassName();
+    }
+
+    private boolean allowsFieldInjection(BeanMetadata beanMetadata) {
+        if (beanMetadata instanceof ExtendedBeanMetadata) {
+            return ((ExtendedBeanMetadata) beanMetadata).getFieldInjection();
+        }
+        return false;
+    }
+
+    private BeanRecipe createBeanRecipe(BeanMetadata beanMetadata) {
+        BeanRecipe recipe = new BeanRecipe(
+                getName(beanMetadata.getId()),
+                blueprintContainer,
+                getBeanClass(beanMetadata),
+                allowsFieldInjection(beanMetadata));
+        // Create refs for explicit dependencies
+        recipe.setExplicitDependencies(getDependencies(beanMetadata));
+        recipe.setPrototype(MetadataUtil.isPrototypeScope(beanMetadata) || MetadataUtil.isCustomScope(beanMetadata));
+        recipe.setInitMethod(beanMetadata.getInitMethod());
+        recipe.setDestroyMethod(beanMetadata.getDestroyMethod());
+        recipe.setInterceptorLookupKey(beanMetadata);
+        List<BeanArgument> beanArguments = beanMetadata.getArguments();
+        if (beanArguments != null && !beanArguments.isEmpty()) {
+            boolean hasIndex = (beanArguments.get(0).getIndex() >= 0);
+            if (hasIndex) {
+                List<BeanArgument> beanArgumentsCopy = new ArrayList<BeanArgument>(beanArguments);
+                Collections.sort(beanArgumentsCopy, MetadataUtil.BEAN_COMPARATOR);
+                beanArguments = beanArgumentsCopy;
+            }
+            List<Object> arguments = new ArrayList<Object>();
+            List<String> argTypes = new ArrayList<String>();
+            for (BeanArgument argument : beanArguments) {
+                Recipe value = getValue(argument.getValue(), null);
+                arguments.add(value);
+                argTypes.add(argument.getValueType());
+            }
+            recipe.setArguments(arguments);
+            recipe.setArgTypes(argTypes);
+            recipe.setReorderArguments(!hasIndex);
+        }
+        recipe.setFactoryMethod(beanMetadata.getFactoryMethod());
+        if (beanMetadata.getFactoryComponent() != null) {
+            recipe.setFactoryComponent(getValue(beanMetadata.getFactoryComponent(), null));
+        }
+        for (BeanProperty property : beanMetadata.getProperties()) {
+            Recipe value = getValue(property.getValue(), null);
+            recipe.setProperty(property.getName(), value);
+        }
+        return recipe;
+    }
+
+    private Recipe createRecipe(RegistrationListener listener) {
+        BeanRecipe recipe = new BeanRecipe(getName(null), blueprintContainer, ServiceListener.class, false);
+        recipe.setProperty("listener", getValue(listener.getListenerComponent(), null));
+        if (listener.getRegistrationMethod() != null) {
+            recipe.setProperty("registerMethod", listener.getRegistrationMethod());
+        }
+        if (listener.getUnregistrationMethod() != null) {
+            recipe.setProperty("unregisterMethod", listener.getUnregistrationMethod());
+        }
+        recipe.setProperty("blueprintContainer", blueprintContainer);
+        return recipe;
+    }
+
+    private Recipe createRecipe(ReferenceListener listener) {
+        BeanRecipe recipe = new BeanRecipe(getName(null), blueprintContainer, AbstractServiceReferenceRecipe.Listener.class, false);
+        recipe.setProperty("listener", getValue(listener.getListenerComponent(), null));
+        recipe.setProperty("metadata", listener);
+        recipe.setProperty("blueprintContainer", blueprintContainer);
+        return recipe;
+    }
+
+    private Recipe getValue(Metadata v, Object groupingType) {
+        if (v instanceof NullMetadata) {
+            return null;
+        } else if (v instanceof ComponentMetadata) {
+            return createRecipe((ComponentMetadata) v);
+        } else if (v instanceof ValueMetadata) {
+            ValueMetadata stringValue = (ValueMetadata) v;
+            Object type = stringValue.getType();
+            type = (type == null) ? groupingType : type;
+            ValueRecipe vr = new ValueRecipe(getName(null), stringValue, type);
+            return vr;
+        } else if (v instanceof RefMetadata) {
+            // TODO: make it work with property-placeholders?
+            String componentName = ((RefMetadata) v).getComponentId();
+            RefRecipe rr = new RefRecipe(getName(null), componentName);
+            return rr;
+        } else if (v instanceof CollectionMetadata) {
+            CollectionMetadata collectionMetadata = (CollectionMetadata) v;
+            Class<?> cl = collectionMetadata.getCollectionClass();
+            String type = collectionMetadata.getValueType();
+            if (cl == Object[].class) {
+                ArrayRecipe ar = new ArrayRecipe(getName(null), type);
+                for (Metadata lv : collectionMetadata.getValues()) {
+                    ar.add(getValue(lv, type));
+                }
+                return ar;
+            } else {
+                CollectionRecipe cr = new CollectionRecipe(getName(null), cl != null ? cl : ArrayList.class, type);
+                for (Metadata lv : collectionMetadata.getValues()) {
+                    cr.add(getValue(lv, type));
+                }
+                return cr;
+            }
+        } else if (v instanceof MapMetadata) {
+            return createMapRecipe((MapMetadata) v);
+        } else if (v instanceof PropsMetadata) {
+            PropsMetadata mapValue = (PropsMetadata) v;
+            MapRecipe mr = new MapRecipe(getName(null), Properties.class, String.class, String.class);
+            for (MapEntry entry : mapValue.getEntries()) {
+                Recipe key = getValue(entry.getKey(), String.class);
+                Recipe val = getValue(entry.getValue(), String.class);
+                mr.put(key, val);
+            }
+            return mr;
+        } else if (v instanceof IdRefMetadata) {
+            // TODO: make it work with property-placeholders?
+            String componentName = ((IdRefMetadata) v).getComponentId();
+            IdRefRecipe rnr = new IdRefRecipe(getName(null), componentName);
+            return rnr;
+        } else {
+            throw new IllegalStateException("Unsupported value: " + v.getClass().getName());
+        }
+    }
+
+    private MapRecipe createMapRecipe(MapMetadata mapValue) {
+        String keyType = mapValue.getKeyType();
+        String valueType = mapValue.getValueType();
+        MapRecipe mr = new MapRecipe(getName(null), HashMap.class, keyType, valueType);
+        for (MapEntry entry : mapValue.getEntries()) {
+            Recipe key = getValue(entry.getKey(), keyType);
+            Recipe val = getValue(entry.getValue(), valueType);
+            mr.put(key, val);
+        }
+        return mr;
+    }
+
+    private String getName(String name) {
+        if (name == null) {
+            do {
+                name = "#recipe-" + recipeIdSpace.nextId();
+            } while (names.contains(name) || registry.containsComponentDefinition(name));
+        }
+        names.add(name);
+        return name;
+    }
+
+}
diff --git a/src/main/java/org/apache/aries/blueprint/container/SimpleNamespaceHandlerSet.java b/src/main/java/org/apache/aries/blueprint/container/SimpleNamespaceHandlerSet.java
new file mode 100644
index 0000000..c937ad8
--- /dev/null
+++ b/src/main/java/org/apache/aries/blueprint/container/SimpleNamespaceHandlerSet.java
@@ -0,0 +1,85 @@
+/*
+ * 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.aries.blueprint.container;
+
+import org.apache.aries.blueprint.NamespaceHandler;
+import org.apache.aries.blueprint.ext.impl.ExtNamespaceHandler;
+import org.apache.aries.blueprint.parser.NamespaceHandlerSet;
+import org.xml.sax.SAXException;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import java.io.IOException;
+import java.net.URI;
+import java.util.*;
+
+public class SimpleNamespaceHandlerSet implements NamespaceHandlerSet {
+
+    public static final URI EXT_1_2_NAMESPACE = URI.create("http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0");
+
+    private Set<URI> namespaces;
+    private Schema schema;
+
+    public SimpleNamespaceHandlerSet() {
+        this.namespaces = new LinkedHashSet<URI>();
+        this.namespaces.add(EXT_1_2_NAMESPACE);
+    }
+
+    public Set<URI> getNamespaces() {
+        return Collections.unmodifiableSet(namespaces);
+    }
+
+    public boolean isComplete() {
+        return true;
+    }
+
+    public NamespaceHandler getNamespaceHandler(URI uri) {
+        if (EXT_1_2_NAMESPACE.equals(uri)) {
+            return new ExtNamespaceHandler();
+        }
+        return null;
+    }
+
+    public Schema getSchema() throws SAXException, IOException {
+        if (schema == null) {
+            final List<StreamSource> schemaSources = new ArrayList<StreamSource>();
+            schemaSources.add(new StreamSource(getClass().getResourceAsStream("/org/apache/aries/blueprint/blueprint.xsd")));
+            schemaSources.add(new StreamSource(getClass().getResourceAsStream("/org/apache/aries/blueprint/ext/impl/blueprint-ext-1.2.xsd")));
+            SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+            schema = schemaFactory.newSchema(schemaSources.toArray(new Source[schemaSources.size()]));
+        }
+        return schema;
+    }
+
+    public void addListener(Listener listener) {
+        throw new IllegalStateException();
+    }
+
+    public void removeListener(Listener listener) {
+        throw new IllegalStateException();
+    }
+
+    public void destroy() {
+        schema = null;
+    }
+
+}
diff --git a/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java b/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java
new file mode 100644
index 0000000..ae2f812
--- /dev/null
+++ b/src/main/java/org/apache/aries/blueprint/ext/AbstractPropertyPlaceholder.java
@@ -0,0 +1,367 @@
+/**
+ * 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.aries.blueprint.ext;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.aries.blueprint.ComponentDefinitionRegistry;
+import org.apache.aries.blueprint.ComponentDefinitionRegistryProcessor;
+import org.apache.aries.blueprint.PassThroughMetadata;
+import org.apache.aries.blueprint.mutable.MutableBeanArgument;
+import org.apache.aries.blueprint.mutable.MutableBeanMetadata;
+import org.apache.aries.blueprint.mutable.MutableBeanProperty;
+import org.apache.aries.blueprint.mutable.MutableCollectionMetadata;
+import org.apache.aries.blueprint.mutable.MutableMapEntry;
+import org.apache.aries.blueprint.mutable.MutableMapMetadata;
+import org.apache.aries.blueprint.mutable.MutablePropsMetadata;
+import org.apache.aries.blueprint.services.ExtendedBlueprintContainer;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+import org.osgi.service.blueprint.reflect.BeanArgument;
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.BeanProperty;
+import org.osgi.service.blueprint.reflect.CollectionMetadata;
+import org.osgi.service.blueprint.reflect.MapEntry;
+import org.osgi.service.blueprint.reflect.MapMetadata;
+import org.osgi.service.blueprint.reflect.Metadata;
+import org.osgi.service.blueprint.reflect.NonNullMetadata;
+import org.osgi.service.blueprint.reflect.PropsMetadata;
+import org.osgi.service.blueprint.reflect.Target;
+import org.osgi.service.blueprint.reflect.ValueMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Abstract class for property placeholders.
+ *
+ * @version $Rev: 1211548 $, $Date: 2011-12-07 17:26:22 +0000 (Wed, 07 Dec 2011) $
+ */
+public abstract class AbstractPropertyPlaceholder implements ComponentDefinitionRegistryProcessor {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPropertyPlaceholder.class);
+
+    private ExtendedBlueprintContainer blueprintContainer;
+    private String placeholderPrefix = "${";
+    private String placeholderSuffix = "}";
+    private Pattern pattern;
+
+    private LinkedList<String> processingStack = new LinkedList<String>();
+
+    public String getPlaceholderPrefix() {
+        return placeholderPrefix;
+    }
+
+    public void setPlaceholderPrefix(String placeholderPrefix) {
+        this.placeholderPrefix = placeholderPrefix;
+    }
+
+    public String getPlaceholderSuffix() {
+        return placeholderSuffix;
+    }
+
+    public void setPlaceholderSuffix(String placeholderSuffix) {
+        this.placeholderSuffix = placeholderSuffix;
+    }
+
+    public ExtendedBlueprintContainer getBlueprintContainer() {
+        return blueprintContainer;
+    }
+
+    public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) {
+        this.blueprintContainer = blueprintContainer;
+    }
+
+    public void process(ComponentDefinitionRegistry registry) throws ComponentDefinitionException {
+        try {
+            for (String name : registry.getComponentDefinitionNames()) {
+                processMetadata(registry.getComponentDefinition(name));
+            }
+        } finally {
+            processingStack.clear();
+        }
+    }
+
+    protected Metadata processMetadata(Metadata metadata) {
+        try {
+            if (metadata instanceof BeanMetadata) {
+                BeanMetadata bmd = (BeanMetadata) metadata;
+                processingStack.add("Bean named " + bmd.getId() + "->");
+                return processBeanMetadata(bmd);
+            } else if (metadata instanceof CollectionMetadata) {
+                CollectionMetadata cmd = (CollectionMetadata) metadata;
+                processingStack.add("Collection of type " + cmd.getCollectionClass() + "->");
+                return processCollectionMetadata(cmd);
+            } else if (metadata instanceof MapMetadata) {
+                processingStack.add("Map->");
+                return processMapMetadata((MapMetadata) metadata);
+            } else if (metadata instanceof PropsMetadata) {
+                processingStack.add("Properties->");
+                return processPropsMetadata((PropsMetadata) metadata);
+            } else if (metadata instanceof ValueMetadata) {
+                processingStack.add("Value->");
+                return processValueMetadata((ValueMetadata) metadata);
+            } else {
+                processingStack.add("Unknown Metadata " + metadata + "->");
+                return metadata;
+            }
+        } finally {
+            processingStack.removeLast();
+        }
+    }
+
+    protected Metadata processBeanMetadata(BeanMetadata component) {
+        for (BeanArgument arg :  component.getArguments()) {
+
+            try {
+                processingStack.add(
+                        "Argument index " + arg.getIndex() + " and value type " + arg.getValueType() + "->");
+                if(arg instanceof MutableBeanArgument) {
+                    ((MutableBeanArgument) arg).setValue(processMetadata(arg.getValue()));
+                } else {
+                    //Say that we can't change this argument, but continue processing
+                    //If the value is mutable then we may be ok!
+                    printWarning(arg, "Constructor Argument");
+                    processMetadata(arg.getValue());
+                }
+            } finally {
+                processingStack.removeLast();
+            }
+        }
+        for (BeanProperty prop : component.getProperties()) {
+
+            try {
+                processingStack.add("Property named " + prop.getName() + "->");
+                if(prop instanceof MutableBeanProperty) {
+                    ((MutableBeanProperty) prop).setValue(processMetadata(prop.getValue()));
+                } else {
+                    //Say that we can't change this property, but continue processing
+                    //If the value is mutable then we may be ok!
+                    printWarning(prop, "Injection Property");
+                    processMetadata(prop.getValue());
+                }
+            } finally {
+                processingStack.removeLast();
+            }
+        }
+
+        Target factoryComponent = component.getFactoryComponent();
+        if(factoryComponent != null) {
+
+            try {
+
+                if(component instanceof MutableBeanMetadata) {
+                    processingStack.add("Factory Component->");
+                    ((MutableBeanMetadata) component).setFactoryComponent(
+                            (Target) processMetadata(factoryComponent));
+                } else {
+                    printWarning(component, "Factory Component");
+                    processingStack.add("Factory Component->");
+                    processMetadata(factoryComponent);
+                }
+            } finally {
+                processingStack.removeLast();
+            }
+        }
+
+        return component;
+    }
+
+    protected Metadata processPropsMetadata(PropsMetadata metadata) {
+
+        List<MapEntry> entries = new ArrayList<MapEntry>(metadata.getEntries());
+        if(!!! entries.isEmpty()) {
+
+            try {
+                if(metadata instanceof MutablePropsMetadata) {
+                    processingStack.add("Properties->");
+                    MutablePropsMetadata mpm = (MutablePropsMetadata) metadata;
+
+                    for (MapEntry entry : entries) {
+                        mpm.removeEntry(entry);
+                    }
+                    for (MapEntry entry : processMapEntries(entries)) {
+                        mpm.addEntry(entry);
+                    }
+                } else {
+                    printWarning(metadata, "Properties");
+                    processingStack.add("Properties->");
+                    processMapEntries(entries);
+                }
+            } finally {
+                processingStack.removeLast();
+            }
+        }
+        return metadata;
+    }
+
+    protected Metadata processMapMetadata(MapMetadata metadata) {
+        List<MapEntry> entries = new ArrayList<MapEntry>(metadata.getEntries());
+        if(!!! entries.isEmpty()) {
+
+            try {
+                if(metadata instanceof MutableMapMetadata) {
+                    processingStack.add("Map->");
+                    MutableMapMetadata mmm = (MutableMapMetadata) metadata;
+
+                    for (MapEntry entry : entries) {
+                        mmm.removeEntry(entry);
+                    }
+                    for (MapEntry entry : processMapEntries(entries)) {
+                        mmm.addEntry(entry);
+                    }
+                } else {
+                    printWarning(metadata, "Map");
+                    processingStack.add("Map->");
+                    processMapEntries(entries);
+                }
+            } finally {
+                processingStack.removeLast();
+            }
+        }
+        return metadata;
+    }
+
+    protected List<MapEntry> processMapEntries(List<MapEntry> entries) {
+        for (MapEntry entry : entries) {
+            try {
+                processingStack.add("Map Entry Key: " + entry.getKey() + " Value: " + entry.getValue() + "->" );
+
+                if(entry instanceof MutableMapEntry) {
+                    ((MutableMapEntry) entry).setKey((NonNullMetadata) processMetadata(entry.getKey()));
+                    ((MutableMapEntry) entry).setValue(processMetadata(entry.getValue()));
+                } else {
+                    printWarning(entry, "Map Entry");
+                    processMetadata(entry.getKey());
+                    processMetadata(entry.getValue());
+                }
+            } finally {
+                processingStack.removeLast();
+            }
+        }
+        return entries;
+    }
+
+    protected Metadata processCollectionMetadata(CollectionMetadata metadata) {
+
+        List<Metadata> values = new ArrayList<Metadata>(metadata.getValues());
+        if(!!! values.isEmpty()) {
+
+            try {
+                if(metadata instanceof MutableCollectionMetadata) {
+                    processingStack.add("Collection type: " + metadata.getValueType() + "->");
+                    MutableCollectionMetadata mcm = (MutableCollectionMetadata) metadata;
+
+                    for (Metadata value : values) {
+                        mcm.removeValue(value);
+                    }
+                    for (Metadata value : values) {
+                        mcm.addValue(processMetadata(value));
+                    }
+                } else {
+                    printWarning(metadata, "Collection type: " + metadata.getValueType());
+                    processingStack.add("Collection type: " + metadata.getValueType() + "->");
+                    for (Metadata value : values) {
+                        processMetadata(value);
+                    }
+                }
+            } finally {
+                processingStack.removeLast();
+            }
+        }
+        return metadata;
+    }
+
+    protected Metadata processValueMetadata(ValueMetadata metadata) {
+
+        return new LateBindingValueMetadata(metadata);
+    }
+
+    private void printWarning(Object immutable, String processingType) {
+        StringBuilder sb = new StringBuilder("The property placeholder processor for ");
+        sb.append(placeholderPrefix).append(',').append(" ").append(placeholderSuffix)
+                .append(" found an immutable ").append(processingType)
+                .append(" at location ");
+
+        for(String s : processingStack) {
+            sb.append(s);
+        }
+
+        sb.append(". This may prevent properties, beans, or other items referenced by this component from being properly processed.");
+
+        LOGGER.info(sb.toString());
+    }
+
+    protected String retrieveValue(String expression) {
+        return getProperty(expression);
+    }
+
+    protected String processString(String str) {
+        // TODO: we need to handle escapes on the prefix / suffix
+        Matcher matcher = getPattern().matcher(str);
+        while (matcher.find()) {
+            String rep = retrieveValue(matcher.group(1));
+            if (rep != null) {
+                str = str.replace(matcher.group(0), rep);
+                matcher.reset(str);
+            }
+        }
+        return str;
+    }
+
+    protected String getProperty(String val) {
+        return null;
+    }
+
+    protected Pattern getPattern() {
+        if (pattern == null) {
+            pattern = Pattern.compile("\\Q" + placeholderPrefix + "\\E(.+?)\\Q" + placeholderSuffix + "\\E");
+        }
+        return pattern;
+    }
+
+    public class LateBindingValueMetadata implements ValueMetadata {
+
+        private final ValueMetadata metadata;
+        private boolean retrieved;
+        private String retrievedValue;
+
+        public LateBindingValueMetadata(ValueMetadata metadata) {
+            this.metadata = metadata;
+        }
+
+        public String getStringValue() {
+            if (!retrieved) {
+                String v = metadata.getStringValue();
+                LOGGER.debug("Before process: {}", v);
+                retrievedValue = processString(v);
+                LOGGER.debug("After process: {}", retrievedValue);
+
+                retrieved = true;
+            }
+            return retrievedValue;
+        }
+
+        public String getType() {
+            return metadata.getType();
+        }
+    }
+}
diff --git a/src/main/java/org/apache/aries/blueprint/ext/PropertyPlaceholder.java b/src/main/java/org/apache/aries/blueprint/ext/PropertyPlaceholder.java
new file mode 100644
index 0000000..f3b6162
--- /dev/null
+++ b/src/main/java/org/apache/aries/blueprint/ext/PropertyPlaceholder.java
@@ -0,0 +1,208 @@
+/**
+ * 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.aries.blueprint.ext;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.aries.blueprint.ext.evaluator.PropertyEvaluator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Property placeholder that looks for properties in the System properties.
+ *
+ * @version $Rev$, $Date$
+ */
+public class PropertyPlaceholder extends AbstractPropertyPlaceholder {
+
+    public enum SystemProperties {
+        never,
+        fallback,
+        override
+    }
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(PropertyPlaceholder.class);
+
+    private Map defaultProperties;
+    private Properties properties;
+    private List<String> locations;
+    private boolean ignoreMissingLocations;
+    private SystemProperties systemProperties = SystemProperties.override;
+    private PropertyEvaluator evaluator = null;
+
+    public Map getDefaultProperties() {
+        return defaultProperties;
+    }
+
+    public void setDefaultProperties(Map defaultProperties) {
+        this.defaultProperties = defaultProperties;
+    }
+
+    public List<String> getLocations() {
+        return locations;
+    }
+
+    public void setLocations(List<String> locations) {
+        this.locations = locations;
+    }
+
+    public boolean isIgnoreMissingLocations() {
+        return ignoreMissingLocations;
+    }
+
+    public void setIgnoreMissingLocations(boolean ignoreMissingLocations) {
+        this.ignoreMissingLocations = ignoreMissingLocations;
+    }
+
+    public SystemProperties getSystemProperties() {
+        return systemProperties;
+    }
+
+    public void setSystemProperties(SystemProperties systemProperties) {
+        this.systemProperties = systemProperties;
+    }
+
+    public PropertyEvaluator getEvaluator() {
+        return evaluator;
+    }
+
+    public void setEvaluator(PropertyEvaluator evaluator) {
+        this.evaluator = evaluator;
+    }
+
+    public void init() throws Exception {
+        properties = new Properties();
+        if (locations != null) {
+            for (String url : locations) {
+                InputStream is = null;
+                try {
+                    if (url.startsWith("classpath:")) {
+                        is = getBlueprintContainer().getResource(url.substring("classpath:".length())).openStream();
+                    } else {
+                        is = new URL(url).openStream();
+                    }
+                } catch (IOException e) {
+                    if (ignoreMissingLocations) {
+                        LOGGER.debug("Unable to load properties from url " + url + " while ignoreMissingLocations is set to true");
+                    } else {
+                        throw e;
+                    }
+                }
+                if (is != null) {
+                    try {
+                        properties.load(is);
+                    } finally {
+                        is.close();
+                    }
+                }
+            }
+        }
+    }
+
+    protected String getProperty(String val) {
+        LOGGER.debug("Retrieving property {}", val);
+        Object v = null;
+        if (v == null && systemProperties == SystemProperties.override) {
+            v = getBlueprintContainer().getProperty(val);
+            if (v != null) {
+                LOGGER.debug("Found system property {} with value {}", val, v);
+            }
+        }
+        if (v == null && properties != null) {
+            v = properties.getProperty(val);
+            if (v != null) {
+                LOGGER.debug("Found property {} from locations with value {}", val, v);
+            }
+        }
+        if (v == null && systemProperties == SystemProperties.fallback) {
+            v = getBlueprintContainer().getProperty(val);
+            if (v != null) {
+                LOGGER.debug("Found system property {} with value {}", val, v);
+            }
+        }
+        if (v == null && defaultProperties != null) {
+            v = defaultProperties.get(val);
+            if (v != null) {
+                LOGGER.debug("Retrieved property {} value from defaults {}", val, v);
+            }
+        }
+        if (v == null) {
+            LOGGER.debug("Property {} not found", val);
+        }
+        return v != null ? v.toString() : null;
+    }
+
+    @Override
+    protected String retrieveValue(String expression) {
+        LOGGER.debug("Retrieving Value from expression: {}", expression);
+
+        if (evaluator == null) {
+            return super.retrieveValue(expression);
+        } else {
+            return evaluator.evaluate(expression, new Dictionary<String, String>(){
+                @Override
+                public String get(Object key) {
+                    return getProperty((String) key);
+                }
+
+                // following are not important
+                @Override
+                public String put(String key, String value) {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public Enumeration<String> elements() {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public boolean isEmpty() {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public Enumeration<String> keys() {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public String remove(Object key) {
+                    throw new UnsupportedOperationException();
+                }
+
+                @Override
+                public int size() {
+                    throw new UnsupportedOperationException();
+                }
+
+            });
+        }
+
+    }
+
+
+}
diff --git a/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java b/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java
new file mode 100644
index 0000000..4101a53
--- /dev/null
+++ b/src/main/java/org/apache/aries/blueprint/ext/impl/ExtNamespaceHandler.java
@@ -0,0 +1,445 @@
+/**
+ * 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.aries.blueprint.ext.impl;
+
+import org.apache.aries.blueprint.ComponentDefinitionRegistry;
+import org.apache.aries.blueprint.ExtendedBeanMetadata;
+import org.apache.aries.blueprint.ExtendedReferenceListMetadata;
+import org.apache.aries.blueprint.ParserContext;
+import org.apache.aries.blueprint.ext.AbstractPropertyPlaceholder;
+import org.apache.aries.blueprint.ext.PlaceholdersUtils;
+import org.apache.aries.blueprint.ext.PropertyPlaceholder;
+import org.apache.aries.blueprint.ext.evaluator.PropertyEvaluator;
+import org.apache.aries.blueprint.mutable.*;
+import org.osgi.service.blueprint.container.ComponentDefinitionException;
+import org.osgi.service.blueprint.reflect.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.*;
+import org.w3c.dom.CharacterData;
+
+import java.net.URL;
+import java.util.*;
+
+/**
+ * A namespace handler for Aries blueprint extensions
+ *
+ * @version $Rev$, $Date$
+ */
+public class ExtNamespaceHandler implements org.apache.aries.blueprint.NamespaceHandler {
+
+    public static final String BLUEPRINT_NAMESPACE = "http://www.osgi.org/xmlns/blueprint/v1.0.0";
+    public static final String BLUEPRINT_EXT_NAMESPACE_V1_0 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.0.0";
+    public static final String BLUEPRINT_EXT_NAMESPACE_V1_1 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.1.0";
+    public static final String BLUEPRINT_EXT_NAMESPACE_V1_2 = "http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0";
+    
+    public static final String PROPERTY_PLACEHOLDER_ELEMENT = "property-placeholder";
+    public static final String DEFAULT_PROPERTIES_ELEMENT = "default-properties";
+    public static final String PROPERTY_ELEMENT = "property";
+    public static final String VALUE_ELEMENT = "value";
+    public static final String LOCATION_ELEMENT = "location";
+
+    public static final String ID_ATTRIBUTE = "id";
+    public static final String PLACEHOLDER_PREFIX_ATTRIBUTE = "placeholder-prefix";
+    public static final String PLACEHOLDER_SUFFIX_ATTRIBUTE = "placeholder-suffix";
+    public static final String DEFAULTS_REF_ATTRIBUTE = "defaults-ref";
+    public static final String IGNORE_MISSING_LOCATIONS_ATTRIBUTE = "ignore-missing-locations";
+    public static final String EVALUATOR_ATTRIBUTE = "evaluator";
+
+    public static final String SYSTEM_PROPERTIES_ATTRIBUTE = "system-properties";
+    public static final String SYSTEM_PROPERTIES_NEVER = "never";
+    public static final String SYSTEM_PROPERTIES_FALLBACK = "fallback";
+    public static final String SYSTEM_PROPERTIES_OVERRIDE = "override";
+
+    public static final String PROXY_METHOD_ATTRIBUTE = "proxy-method";
+    public static final String PROXY_METHOD_DEFAULT = "default";
+    public static final String PROXY_METHOD_CLASSES = "classes";
+    public static final String PROXY_METHOD_GREEDY = "greedy";
+
+    public static final String ROLE_ATTRIBUTE = "role";
+    public static final String ROLE_PROCESSOR = "processor";
+    
+    public static final String FIELD_INJECTION_ATTRIBUTE = "field-injection";
+    
+    public static final String DEFAULT_REFERENCE_BEAN = "default";
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(ExtNamespaceHandler.class);
+
+    private int idCounter;
+    
+    public URL getSchemaLocation(String namespace) {
+        if (BLUEPRINT_EXT_NAMESPACE_V1_0.equals(namespace)) {
+          return getClass().getResource("blueprint-ext.xsd");
+        } else if (BLUEPRINT_EXT_NAMESPACE_V1_1.equals(namespace)) {
+          return getClass().getResource("blueprint-ext-1.1.xsd");
+        } else if (BLUEPRINT_EXT_NAMESPACE_V1_2.equals(namespace)) {
+          return getClass().getResource("blueprint-ext-1.2.xsd");
+        } else {
+          return null;
+        }
+    }
+
+    public Set<Class> getManagedClasses() {
+        return new HashSet<Class>(Arrays.asList(
+                PropertyPlaceholder.class
+        ));
+    }
+
+    public Metadata parse(Element element, ParserContext context) {
+        LOGGER.debug("Parsing element {{}}{}", element.getNamespaceURI(), element.getLocalName());
+        if (nodeNameEquals(element, PROPERTY_PLACEHOLDER_ELEMENT)) {
+            return parsePropertyPlaceholder(context, element);
+        } else {
+            throw new ComponentDefinitionException("Unsupported element: " + element.getNodeName());
+        }
+    }
+
+    public ComponentMetadata decorate(Node node, ComponentMetadata component, ParserContext context) {
+        if (node instanceof Attr && nodeNameEquals(node, PROXY_METHOD_ATTRIBUTE)) {
+            return decorateProxyMethod(node, component, context);
+        } else if (node instanceof Attr && nodeNameEquals(node, ROLE_ATTRIBUTE)) {
+            return decorateRole(node, component, context);
+        } else if (node instanceof Attr && nodeNameEquals(node, FIELD_INJECTION_ATTRIBUTE)) {
+            return decorateFieldInjection(node, component, context);
+        } else if (node instanceof Attr && nodeNameEquals(node, DEFAULT_REFERENCE_BEAN)) {
+            return decorateDefaultBean(node, component, context);
+        } else {
+            throw new ComponentDefinitionException("Unsupported node: " + node.getNodeName());
+        }
+    }
+    
+    private ComponentMetadata decorateDefaultBean(Node node,
+        ComponentMetadata component, ParserContext context) 
+    {
+        if (!(component instanceof ReferenceMetadata)) {
+            throw new ComponentDefinitionException("Attribute " + node.getNodeName() + " can only be used on a <reference> element");
+        }
+      
+        if (!(component instanceof MutableReferenceMetadata)) {
+            throw new ComponentDefinitionException("Expected an instanceof MutableReferenceMetadata");
+        }
+        
+        String value = ((Attr) node).getValue();
+        ((MutableReferenceMetadata) component).setDefaultBean(value);
+        return component;
+    }
+
+    private ComponentMetadata decorateFieldInjection(Node node, ComponentMetadata component, ParserContext context) {
+        if (!(component instanceof BeanMetadata)) {
+            throw new ComponentDefinitionException("Attribute " + node.getNodeName() + " can only be used on a <bean> element");
+        }
+        
+        if (!(component instanceof MutableBeanMetadata)) {
+            throw new ComponentDefinitionException("Expected an instanceof MutableBeanMetadata");
+        }
+        
+        String value = ((Attr) node).getValue();
+        ((MutableBeanMetadata) component).setFieldInjection("true".equals(value) || "1".equals(value));
+        return component;
+    }
+
+    private ComponentMetadata decorateRole(Node node, ComponentMetadata component, ParserContext context) {
+        if (!(component instanceof BeanMetadata)) {
+            throw new ComponentDefinitionException("Attribute " + node.getNodeName() + " can only be used on a <bean> element");
+        }
+        if (!(component instanceof MutableBeanMetadata)) {
+            throw new ComponentDefinitionException("Expected an instance of MutableBeanMetadata");
+        }
+        boolean processor = false;
+        String value = ((Attr) node).getValue();
+        String[] flags = value.trim().split(" ");
+        for (String flag : flags) {
+            if (ROLE_PROCESSOR.equals(flag)) {
+                processor = true;
+            } else {
+                throw new ComponentDefinitionException("Unknown proxy method: " + flag);
+            }
+        }
+        ((MutableBeanMetadata) component).setProcessor(processor);
+        return component;
+    }
+
+    private ComponentMetadata decorateProxyMethod(Node node, ComponentMetadata component, ParserContext context) {
+        if (!(component instanceof ServiceReferenceMetadata)) {
+            throw new ComponentDefinitionException("Attribute " + node.getNodeName() + " can only be used on a <reference> or <reference-list> element");
+        }
+        if (!(component instanceof MutableServiceReferenceMetadata)) {
+            throw new ComponentDefinitionException("Expected an instance of MutableServiceReferenceMetadata");
+        }
+        int method = 0;
+        String value = ((Attr) node).getValue();
+        String[] flags = value.trim().split(" ");
+        for (String flag : flags) {
+            if (PROXY_METHOD_DEFAULT.equals(flag)) {
+                method += ExtendedReferenceListMetadata.PROXY_METHOD_DEFAULT;
+            } else if (PROXY_METHOD_CLASSES.equals(flag)) {
+                method += ExtendedReferenceListMetadata.PROXY_METHOD_CLASSES;
+            } else if (PROXY_METHOD_GREEDY.equals(flag)) {
+                method += ExtendedReferenceListMetadata.PROXY_METHOD_GREEDY;
+            } else {
+                throw new ComponentDefinitionException("Unknown proxy method: " + flag);
+            }
+        }
+        if ((method & ExtendedReferenceListMetadata.PROXY_METHOD_GREEDY) != 0 && !(component instanceof ReferenceListMetadata)) {
+            throw new ComponentDefinitionException("Greedy proxying is only available for <reference-list> element");
+        }
+        ((MutableServiceReferenceMetadata) component).setProxyMethod(method);
+        return component;
+    }
+
+    private Metadata parsePropertyPlaceholder(ParserContext context, Element element) {
+        MutableBeanMetadata metadata = context.createMetadata(MutableBeanMetadata.class);
+        metadata.setProcessor(true);
+        metadata.setId(getId(context, element));
+        metadata.setScope(BeanMetadata.SCOPE_SINGLETON);
+        metadata.setRuntimeClass(PropertyPlaceholder.class);
+        metadata.setInitMethod("init");
+        String prefix = element.hasAttribute(PLACEHOLDER_PREFIX_ATTRIBUTE)
+                                    ? element.getAttribute(PLACEHOLDER_PREFIX_ATTRIBUTE)
+                                    : "${";
+        metadata.addProperty("placeholderPrefix", createValue(context, prefix));
+        String suffix = element.hasAttribute(PLACEHOLDER_SUFFIX_ATTRIBUTE)
+                                    ? element.getAttribute(PLACEHOLDER_SUFFIX_ATTRIBUTE)
+                                    : "}";
+        metadata.addProperty("placeholderSuffix", createValue(context, suffix));
+        metadata.addProperty("blueprintContainer", createRef(context, "blueprintContainer"));
+        String defaultsRef = element.hasAttribute(DEFAULTS_REF_ATTRIBUTE) ? element.getAttribute(DEFAULTS_REF_ATTRIBUTE) : null;
+        if (defaultsRef != null) {
+            metadata.addProperty("defaultProperties", createRef(context, defaultsRef));
+        }
+        String ignoreMissingLocations = element.hasAttribute(IGNORE_MISSING_LOCATIONS_ATTRIBUTE) ? element.getAttribute(IGNORE_MISSING_LOCATIONS_ATTRIBUTE) : null;
+        if (ignoreMissingLocations != null) {
+            metadata.addProperty("ignoreMissingLocations", createValue(context, ignoreMissingLocations));
+        }
+        String systemProperties = element.hasAttribute(SYSTEM_PROPERTIES_ATTRIBUTE) ? element.getAttribute(SYSTEM_PROPERTIES_ATTRIBUTE) : null;
+        if (systemProperties != null) {
+            metadata.addProperty("systemProperties", createValue(context, systemProperties));
+        }
+        String evaluator = element.hasAttribute(EVALUATOR_ATTRIBUTE) ? element.getAttribute(EVALUATOR_ATTRIBUTE) : null;
+        if (evaluator != null) {
+            throw new IllegalStateException("Evaluators are not supported outside OSGi");
+        }
+        // Parse elements
+        List<String> locations = new ArrayList<String>();
+        NodeList nl = element.getChildNodes();
+        for (int i = 0; i < nl.getLength(); i++) {
+            Node node = nl.item(i);
+            if (node instanceof Element) {
+                Element e = (Element) node;
+                if (BLUEPRINT_EXT_NAMESPACE_V1_0.equals(e.getNamespaceURI())
+                        || BLUEPRINT_EXT_NAMESPACE_V1_1.equals(e.getNamespaceURI())
+                        || BLUEPRINT_EXT_NAMESPACE_V1_2.equals(e.getNamespaceURI())) {
+                    if (nodeNameEquals(e, DEFAULT_PROPERTIES_ELEMENT)) {
+                        if (defaultsRef != null) {
+                            throw new ComponentDefinitionException("Only one of " + DEFAULTS_REF_ATTRIBUTE + " attribute or " + DEFAULT_PROPERTIES_ELEMENT + " element is allowed");
+                        }
+                        Metadata props = parseDefaultProperties(context, metadata, e);
+                        metadata.addProperty("defaultProperties", props);
+                    } else if (nodeNameEquals(e, LOCATION_ELEMENT)) {
+                        locations.add(getTextValue(e));
+                    }
+                }
+            }
+        }
+        if (!locations.isEmpty()) {
+            metadata.addProperty("locations", createList(context, locations));
+        }
+
+        boolean result = validatePlaceholder(metadata, context.getComponentDefinitionRegistry());
+
+        return result ? metadata : null;
+    }
+
+    private boolean validatePlaceholder(MutableBeanMetadata metadata, ComponentDefinitionRegistry registry) {
+        for (String id : registry.getComponentDefinitionNames()) {
+            ComponentMetadata component = registry.getComponentDefinition(id);
+            if (component instanceof ExtendedBeanMetadata) {
+                ExtendedBeanMetadata bean = (ExtendedBeanMetadata) component;
+                if (bean.getRuntimeClass() != null && AbstractPropertyPlaceholder.class.isAssignableFrom(bean.getRuntimeClass())) {
+                    if (arePropertiesEquals(bean, metadata, "placeholderPrefix")
+                            && arePropertiesEquals(bean, metadata, "placeholderSuffix")) {
+                        if (!arePropertiesEquals(bean, metadata, "systemProperties")
+                                || !arePropertiesEquals(bean, metadata, "ignoreMissingLocations")) {
+                            throw new ComponentDefinitionException("Multiple incompatible placeholders found");
+                        }
+                        // Merge both placeholders
+                        mergeList(bean, metadata, "locations");
+                        mergeMap(bean, metadata, "defaultProperties");
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    private void mergeList(ExtendedBeanMetadata bean1, MutableBeanMetadata bean2, String name) {
+        Metadata m1 = getProperty(bean1, name);
+        Metadata m2 = getProperty(bean2, name);
+        if (m1 == null && m2 != null) {
+            ((MutableBeanMetadata) bean1).addProperty(name, m2);
+        } else if (m1 != null && m2 != null) {
+            if (!(m1 instanceof MutableCollectionMetadata) || !(m2 instanceof MutableCollectionMetadata)) {
+                throw new ComponentDefinitionException("Unable to merge " + name + " list properties");
+            }
+            MutableCollectionMetadata c1 = (MutableCollectionMetadata) m1;
+            MutableCollectionMetadata c2 = (MutableCollectionMetadata) m2;
+            for (Metadata v : c2.getValues()) {
+                c1.addValue(v);
+            }
+        }
+    }
+
+    private void mergeMap(ExtendedBeanMetadata bean1, MutableBeanMetadata bean2, String name) {
+        Metadata m1 = getProperty(bean1, name);
+        Metadata m2 = getProperty(bean2, name);
+        if (m1 == null && m2 != null) {
+            ((MutableBeanMetadata) bean1).addProperty(name, m2);
+        } else if (m1 != null && m2 != null) {
+            if (!(m1 instanceof MutableMapMetadata) || !(m2 instanceof MutableMapMetadata)) {
+                throw new ComponentDefinitionException("Unable to merge " + name + " list properties");
+            }
+            MutableMapMetadata c1 = (MutableMapMetadata) m1;
+            MutableMapMetadata c2 = (MutableMapMetadata) m2;
+            for (MapEntry e : c2.getEntries()) {
+                c1.addEntry(e);
+            }
+        }
+    }
+
+    private boolean arePropertiesEquals(BeanMetadata bean1, BeanMetadata bean2, String name) {
+        String v1 = getPlaceholderProperty(bean1, name);
+        String v2 = getPlaceholderProperty(bean2, name);
+        return v1 == null ? v2 == null : v1.equals(v2);
+    }
+
+    private String getPlaceholderProperty(BeanMetadata bean, String name) {
+        Metadata metadata = getProperty(bean, name);
+        if (metadata instanceof ValueMetadata) {
+            return ((ValueMetadata) metadata).getStringValue();
+        }
+        return null;
+    }
+
+    private Metadata getProperty(BeanMetadata bean, String name) {
+        for (BeanProperty property : bean.getProperties()) {
+            if (name.equals(property.getName())) {
+                return property.getValue();
+            }
+        }
+        return null;
+    }
+
+
+    private Metadata parseDefaultProperties(ParserContext context, MutableBeanMetadata enclosingComponent, Element element) {
+        MutableMapMetadata props = context.createMetadata(MutableMapMetadata.class);
+        NodeList nl = element.getChildNodes();
+        for (int i = 0; i < nl.getLength(); i++) {
+            Node node = nl.item(i);
+            if (node instanceof Element) {
+                Element e = (Element) node;
+                if (BLUEPRINT_EXT_NAMESPACE_V1_0.equals(e.getNamespaceURI())
+                        || BLUEPRINT_EXT_NAMESPACE_V1_1.equals(e.getNamespaceURI())
+                        || BLUEPRINT_EXT_NAMESPACE_V1_2.equals(e.getNamespaceURI())) {
+                    if (nodeNameEquals(e, PROPERTY_ELEMENT)) {
+                        BeanProperty prop = context.parseElement(BeanProperty.class, enclosingComponent, e);
+                        props.addEntry(createValue(context, prop.getName(), String.class.getName()), prop.getValue());
+                    }
+                }
+            }
+        }
+        return props;
+    }
+
+    public String getId(ParserContext context, Element element) {
+        if (element.hasAttribute(ID_ATTRIBUTE)) {
+            return element.getAttribute(ID_ATTRIBUTE);
+        } else {
+            return generateId(context);
+        }
+    }
+
+    public void generateIdIfNeeded(ParserContext context, MutableComponentMetadata metadata) {
+        if (metadata.getId() == null) {
+            metadata.setId(generateId(context));
+        }
+    }
+
+    private String generateId(ParserContext context) {
+        String id;
+        do {
+            id = ".ext-" + ++idCounter;
+        } while (context.getComponentDefinitionRegistry().containsComponentDefinition(id));
+        return id;
+    }
+
+    private static ValueMetadata createValue(ParserContext context, String value) {
+        return createValue(context, value, null);
+    }
+
+    private static ValueMetadata createValue(ParserContext context, String value, String type) {
+        MutableValueMetadata m = context.createMetadata(MutableValueMetadata.class);
+        m.setStringValue(value);
+        m.setType(type);
+        return m;
+    }
+
+    private static RefMetadata createRef(ParserContext context, String value) {
+        MutableRefMetadata m = context.createMetadata(MutableRefMetadata.class);
+        m.setComponentId(value);
+        return m;
+    }
+
+    private static IdRefMetadata createIdRef(ParserContext context, String value) {
+        MutableIdRefMetadata m = context.createMetadata(MutableIdRefMetadata.class);
+        m.setComponentId(value);
+        return m;
+    }
+    
+    private static CollectionMetadata createList(ParserContext context, List<String> list) {
+        MutableCollectionMetadata m = context.createMetadata(MutableCollectionMetadata.class);
+        m.setCollectionClass(List.class);
+        m.setValueType(String.class.getName());
+        for (String v : list) {
+            m.addValue(createValue(context, v, String.class.getName()));
+        }
+        return m;
+    }
+
+    private static String getTextValue(Element element) {
+        StringBuffer value = new StringBuffer();
+        NodeList nl = element.getChildNodes();
+        for (int i = 0; i < nl.getLength(); i++) {
+            Node item = nl.item(i);
+            if ((item instanceof CharacterData && !(item instanceof Comment)) || item instanceof EntityReference) {
+                value.append(item.getNodeValue());
+            }
+        }
+        return value.toString();
+    }
+
+    private static boolean nodeNameEquals(Node node, String name) {
+        return (name.equals(node.getNodeName()) || name.equals(node.getLocalName()));
+    }
+
+    public static boolean isBlueprintNamespace(String ns) {
+        return BLUEPRINT_NAMESPACE.equals(ns);
+    }
+
+}
diff --git a/src/main/java/org/apache/aries/blueprint/services/ExtendedBlueprintContainer.java b/src/main/java/org/apache/aries/blueprint/services/ExtendedBlueprintContainer.java
new file mode 100644
index 0000000..d490c71
--- /dev/null
+++ b/src/main/java/org/apache/aries/blueprint/services/ExtendedBlueprintContainer.java
@@ -0,0 +1,46 @@
+/*
+ * 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.aries.blueprint.services;
+
+import org.apache.aries.blueprint.ComponentDefinitionRegistry;
+import org.apache.aries.blueprint.Processor;
+import org.osgi.service.blueprint.container.BlueprintContainer;
+import org.osgi.service.blueprint.container.Converter;
+
+import java.net.URL;
+import java.security.AccessControlContext;
+import java.util.List;
+
+public interface ExtendedBlueprintContainer extends BlueprintContainer {
+
+    Converter getConverter();
+
+    Class loadClass(String name) throws ClassNotFoundException;
+
+    URL getResource(String name);
+
+    AccessControlContext getAccessControlContext();
+
+    ComponentDefinitionRegistry getComponentDefinitionRegistry();
+
+    <T extends Processor> List<T> getProcessors(Class<T> type);
+
+    String getProperty(String key);
+
+}
diff --git a/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml b/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml
deleted file mode 100644
index c9ffa4e..0000000
--- a/src/main/resources/OSGI-INF/blueprint/blueprint-cm.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-
-    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.
-
--->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" default-activation="lazy">
-
-    <bean id="CmNamespaceHandler" class="org.apache.aries.blueprint.compendium.cm.CmNamespaceHandler"/>
-
-    <service ref="CmNamespaceHandler" interface="org.apache.aries.blueprint.NamespaceHandler">
-        <service-properties>
-            <entry key="osgi.service.blueprint.namespace" value="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"/>
-        </service-properties>
-    </service>
-    <service ref="CmNamespaceHandler" interface="org.apache.aries.blueprint.NamespaceHandler">
-        <service-properties>
-            <entry key="osgi.service.blueprint.namespace" value="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"/>
-        </service-properties>
-    </service>
-    <service ref="CmNamespaceHandler" interface="org.apache.aries.blueprint.NamespaceHandler">
-        <service-properties>
-            <entry key="osgi.service.blueprint.namespace" value="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0"/>
-        </service-properties>
-    </service>
-    
-</blueprint>
diff --git a/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.0.0.xsd b/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.0.0.xsd
deleted file mode 100644
index 30c4d36..0000000
--- a/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.0.0.xsd
+++ /dev/null
@@ -1,121 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    /*
-    * $Revision$
-    *
-    * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
-    *
-    * Licensed 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.
-    */
-    -->
-<xsd:schema xmlns="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
-            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
-            xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-            targetNamespace="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.0.0"
-            elementFormDefault="qualified"
-            attributeFormDefault="unqualified"
-            version="1.0.0">
-
-    <xsd:import namespace="http://www.osgi.org/xmlns/blueprint/v1.0.0" />
-
-    <!-- property placeholder -->
-
-    <xsd:element name="property-placeholder" type="TpropertyPlaceholder"/>
-
-    <xsd:complexType name="TpropertyPlaceholder">
-        <xsd:complexContent>
-            <xsd:extension base="bp:Tcomponent">
-                <xsd:sequence>
-                    <!-- nested properties declaration -->
-                    <xsd:element name="default-properties" type="TdefaultProperties" minOccurs="0" maxOccurs="1"/>
-                </xsd:sequence>
-
-                <!-- #### What should be the type for a persistent id?  I think we need to define one like class and method -->
-                <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
-                <xsd:attribute name="placeholder-prefix" type="xsd:string" use="optional" default="${"/>
-                <xsd:attribute name="placeholder-suffix" type="xsd:string" use="optional" default="}"/>
-                <xsd:attribute name="defaults-ref" type="bp:Tidref" use="optional"/>
-            </xsd:extension>
-        </xsd:complexContent>
-    </xsd:complexType>
-
-    <!-- #### is this the correct type here?  This is defining placeholder properties,
-         so should this be a restricted set of value types or should this be expanded to
-         all of the elements you can inject into a bean property? -->
-    <xsd:complexType name="TdefaultProperties">
-        <xsd:sequence minOccurs="0" maxOccurs="unbounded">
-            <xsd:element name="property" type="bp:Tproperty"/>
-        </xsd:sequence>
-    </xsd:complexType>
-
-
-    <!--  managed-properties  -->
-
-    <xsd:element name="managed-properties" type="TmanagedProperties"/>
-
-    <xsd:complexType name="TmanagedProperties">
-        <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
-        <xsd:attribute name="update-strategy" type="TupdateStrategyType" use="optional"/>
-        <xsd:attribute name="update-method" type="xsd:string" use="optional"/>
-    </xsd:complexType>
-
-    <xsd:simpleType name="TupdateStrategyType">
-        <xsd:restriction base="xsd:NMTOKEN">
-            <xsd:enumeration value="none"/>
-            <xsd:enumeration value="component-managed"/>
-            <xsd:enumeration value="container-managed"/>
-        </xsd:restriction>
-    </xsd:simpleType>
-
-    <!--  managed-service-factory -->
-
-    <xsd:element name="managed-service-factory" type="TmanagedServiceFactory"/>
-
-    <xsd:complexType name="TmanagedServiceFactory">
-        <xsd:complexContent>
-            <xsd:extension base="bp:Tcomponent">
-                <xsd:sequence>
-                    <xsd:group ref="bp:GbaseServiceElements"/>
-                    <xsd:element name="managed-component" type="TmanagedComponent" minOccurs="1" maxOccurs="1"/>
-                </xsd:sequence>
-                <xsd:attribute name="interface" type="bp:Tclass" use="optional" />
-                <xsd:attribute name="ref" type="bp:Tidref" use="optional" />
-                <xsd:attribute name="auto-export" type="bp:TautoExportModes" default="disabled" />
-                <xsd:attribute name="ranking" type="xsd:int" default="0"/>
-                <xsd:attribute name="factory-pid" type="xsd:string" use="required"/>
-                <xsd:anyAttribute namespace="##other" processContents="strict"/>
-            </xsd:extension>
-        </xsd:complexContent>
-    </xsd:complexType>
-
-    <xsd:complexType name="TmanagedComponent">
-        <xsd:group ref="bp:GbeanElements"/>
-        <xsd:attribute name="class" type="bp:Tclass"/>
-        <xsd:attribute name="init-method" type="bp:Tmethod"/>
-        <xsd:attribute name="destroy-method" type="bp:Tmethod"/>
-        <xsd:attribute name="factory-method" type="bp:Tmethod"/>
-        <xsd:attribute name="factory-component" type="bp:Tidref"/>
-        <xsd:anyAttribute namespace="##other" processContents="strict"/>
-    </xsd:complexType>
-
-
-    <!-- cm-properties -->
-
-    <xsd:element name="cm-properties" type="TcmProperties"/>
-
-    <xsd:complexType name="TcmProperties">
-        <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
-        <xsd:attribute name="update" type="xsd:boolean" use="optional" default="false"/>
-    </xsd:complexType>
-
-</xsd:schema>
diff --git a/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.1.0.xsd b/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.1.0.xsd
deleted file mode 100644
index 8db6d9c..0000000
--- a/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.1.0.xsd
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    /*
-    * $Revision$
-    *
-    * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
-    *
-    * Licensed 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.
-    */
-    -->
-<xsd:schema xmlns="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
-            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
-            xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-            targetNamespace="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
-            elementFormDefault="qualified"
-            attributeFormDefault="unqualified"
-            version="1.0.0">
-
-    <xsd:import namespace="http://www.osgi.org/xmlns/blueprint/v1.0.0" />
-
-    <!-- property placeholder -->
-
-    <xsd:element name="property-placeholder" type="TpropertyPlaceholder"/>
-
-    <xsd:complexType name="TpropertyPlaceholder">
-        <xsd:complexContent>
-            <xsd:extension base="bp:Tcomponent">
-                <xsd:sequence>
-                    <!-- nested properties declaration -->
-                    <xsd:element name="default-properties" type="TdefaultProperties" minOccurs="0" maxOccurs="1"/>
-                </xsd:sequence>
-
-                <!-- #### What should be the type for a persistent id?  I think we need to define one like class and method -->
-                <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
-                <xsd:attribute name="placeholder-prefix" type="xsd:string" use="optional" default="${"/>
-                <xsd:attribute name="placeholder-suffix" type="xsd:string" use="optional" default="}"/>
-                <xsd:attribute name="defaults-ref" type="bp:Tidref" use="optional"/>
-                <xsd:attribute name="update-strategy" type="TplaceholderUpdateStrategyType" use="optional" default="none"/>
-            </xsd:extension>
-        </xsd:complexContent>
-    </xsd:complexType>
-
-    <xsd:simpleType name="TplaceholderUpdateStrategyType">
-        <xsd:restriction base="xsd:NMTOKEN">
-            <xsd:enumeration value="none"/>
-            <xsd:enumeration value="reload"/>
-        </xsd:restriction>
-    </xsd:simpleType>
-
-    <!-- #### is this the correct type here?  This is defining placeholder properties,
-         so should this be a restricted set of value types or should this be expanded to
-         all of the elements you can inject into a bean property? -->
-    <xsd:complexType name="TdefaultProperties">
-        <xsd:sequence minOccurs="0" maxOccurs="unbounded">
-            <xsd:element name="property" type="bp:Tproperty"/>
-        </xsd:sequence>
-    </xsd:complexType>
-
-
-    <!--  managed-properties  -->
-
-    <xsd:element name="managed-properties" type="TmanagedProperties"/>
-
-    <xsd:complexType name="TmanagedProperties">
-        <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
-        <xsd:attribute name="update-strategy" type="TupdateStrategyType" use="optional"/>
-        <xsd:attribute name="update-method" type="xsd:string" use="optional"/>
-    </xsd:complexType>
-
-    <xsd:simpleType name="TupdateStrategyType">
-        <xsd:restriction base="xsd:NMTOKEN">
-            <xsd:enumeration value="none"/>
-            <xsd:enumeration value="component-managed"/>
-            <xsd:enumeration value="container-managed"/>
-        </xsd:restriction>
-    </xsd:simpleType>
-
-    <!--  managed-service-factory -->
-
-    <xsd:element name="managed-service-factory" type="TmanagedServiceFactory"/>
-
-    <xsd:complexType name="TmanagedServiceFactory">
-        <xsd:complexContent>
-            <xsd:extension base="bp:Tcomponent">
-                <xsd:sequence>
-                    <xsd:group ref="bp:GbaseServiceElements"/>
-                    <xsd:element name="managed-component" type="TmanagedComponent" minOccurs="1" maxOccurs="1"/>
-                </xsd:sequence>
-                <xsd:attribute name="interface" type="bp:Tclass" use="optional" />
-                <xsd:attribute name="ref" type="bp:Tidref" use="optional" />
-                <xsd:attribute name="auto-export" type="bp:TautoExportModes" default="disabled" />
-                <xsd:attribute name="ranking" type="xsd:int" default="0"/>
-                <xsd:attribute name="factory-pid" type="xsd:string" use="required"/>
-                <xsd:anyAttribute namespace="##other" processContents="strict"/>
-            </xsd:extension>
-        </xsd:complexContent>
-    </xsd:complexType>
-
-    <xsd:complexType name="TmanagedComponent">
-        <xsd:group ref="bp:GbeanElements"/>
-        <xsd:attribute name="class" type="bp:Tclass"/>
-        <xsd:attribute name="init-method" type="bp:Tmethod"/>
-        <xsd:attribute name="destroy-method" type="bp:Tmethod"/>
-        <xsd:attribute name="factory-method" type="bp:Tmethod"/>
-        <xsd:attribute name="factory-component" type="bp:Tidref"/>
-        <xsd:anyAttribute namespace="##other" processContents="strict"/>
-    </xsd:complexType>
-
-
-    <!-- cm-properties -->
-
-    <xsd:element name="cm-properties" type="TcmProperties"/>
-
-    <xsd:complexType name="TcmProperties">
-        <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
-        <xsd:attribute name="update" type="xsd:boolean" use="optional" default="false"/>
-    </xsd:complexType>
-
-</xsd:schema>
diff --git a/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.2.0.xsd b/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.2.0.xsd
deleted file mode 100644
index 9851f51..0000000
--- a/src/main/resources/org/apache/aries/blueprint/compendium/cm/blueprint-cm-1.2.0.xsd
+++ /dev/null
@@ -1,133 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-    /*
-    * $Revision$
-    *
-    * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
-    *
-    * Licensed 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.
-    */
-    -->
-<xsd:schema xmlns="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0"
-            xmlns:xsd="http://www.w3.org/2001/XMLSchema"
-            xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-            targetNamespace="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0"
-            elementFormDefault="qualified"
-            attributeFormDefault="unqualified"
-            version="1.0.0">
-
-    <xsd:import namespace="http://www.osgi.org/xmlns/blueprint/v1.0.0" />
-
-    <!-- property placeholder -->
-
-    <xsd:element name="property-placeholder" type="TpropertyPlaceholder"/>
-
-    <xsd:complexType name="TpropertyPlaceholder">
-        <xsd:complexContent>
-            <xsd:extension base="bp:Tcomponent">
-                <xsd:sequence>
-                    <!-- nested properties declaration -->
-                    <xsd:element name="default-properties" type="TdefaultProperties" minOccurs="0" maxOccurs="1"/>
-                </xsd:sequence>
-
-                <!-- #### What should be the type for a persistent id?  I think we need to define one like class and method -->
-                <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
-                <xsd:attribute name="placeholder-prefix" type="xsd:string" use="optional" default="${"/>
-                <xsd:attribute name="placeholder-suffix" type="xsd:string" use="optional" default="}"/>
-                <xsd:attribute name="defaults-ref" type="bp:Tidref" use="optional"/>
-                <xsd:attribute name="update-strategy" type="TplaceholderUpdateStrategyType" use="optional" default="none"/>
-            </xsd:extension>
-        </xsd:complexContent>
-    </xsd:complexType>
-
-    <xsd:simpleType name="TplaceholderUpdateStrategyType">
-        <xsd:restriction base="xsd:NMTOKEN">
-            <xsd:enumeration value="none"/>
-            <xsd:enumeration value="reload"/>
-        </xsd:restriction>
-    </xsd:simpleType>
-
-    <!-- #### is this the correct type here?  This is defining placeholder properties,
-         so should this be a restricted set of value types or should this be expanded to
-         all of the elements you can inject into a bean property? -->
-    <xsd:complexType name="TdefaultProperties">
-        <xsd:sequence minOccurs="0" maxOccurs="unbounded">
-            <xsd:element name="property" type="bp:Tproperty"/>
-        </xsd:sequence>
-    </xsd:complexType>
-
-
-    <!--  managed-properties  -->
-
-    <xsd:element name="managed-properties" type="TmanagedProperties"/>
-
-    <xsd:complexType name="TmanagedProperties">
-        <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
-        <xsd:attribute name="update-strategy" type="TupdateStrategyType" use="optional"/>
-        <xsd:attribute name="update-method" type="xsd:string" use="optional"/>
-    </xsd:complexType>
-
-    <xsd:simpleType name="TupdateStrategyType">
-        <xsd:restriction base="xsd:NMTOKEN">
-            <xsd:enumeration value="none"/>
-            <xsd:enumeration value="component-managed"/>
-            <xsd:enumeration value="container-managed"/>
-        </xsd:restriction>
-    </xsd:simpleType>
-
-    <!--  managed-service-factory -->
-
-    <xsd:element name="managed-service-factory" type="TmanagedServiceFactory"/>
-
-    <xsd:complexType name="TmanagedServiceFactory">
-        <xsd:complexContent>
-            <xsd:extension base="bp:Tcomponent">
-                <xsd:sequence>
-                    <xsd:group ref="bp:GbaseServiceElements"/>
-                    <xsd:element name="managed-component" type="TmanagedComponent" minOccurs="1" maxOccurs="1"/>
-                </xsd:sequence>
-                <xsd:attribute name="interface" type="bp:Tclass" use="optional" />
-                <xsd:attribute name="ref" type="bp:Tidref" use="optional" />
-                <xsd:attribute name="auto-export" type="bp:TautoExportModes" default="disabled" />
-                <xsd:attribute name="ranking" type="xsd:int" default="0"/>
-                <xsd:attribute name="factory-pid" type="xsd:string" use="required"/>
-                <xsd:anyAttribute namespace="##other" processContents="strict"/>
-            </xsd:extension>
-        </xsd:complexContent>
-    </xsd:complexType>
-
-    <xsd:complexType name="TmanagedComponent">
-        <xsd:group ref="bp:GbeanElements"/>
-        <xsd:attribute name="class" type="bp:Tclass"/>
-        <xsd:attribute name="init-method" type="bp:Tmethod"/>
-        <xsd:attribute name="destroy-method" type="bp:Tmethod"/>
-        <xsd:attribute name="factory-method" type="bp:Tmethod"/>
-        <xsd:attribute name="factory-component" type="bp:Tidref"/>
-        <xsd:anyAttribute namespace="##other" processContents="strict"/>
-    </xsd:complexType>
-
-
-    <!-- cm-properties -->
-
-    <xsd:element name="cm-properties" type="TcmProperties"/>
-
-    <xsd:complexType name="TcmProperties">
-        <xsd:complexContent>
-            <xsd:extension base="bp:Tcomponent">
-                <xsd:attribute name="persistent-id" type="xsd:string" use="required"/>
-                <xsd:attribute name="update" type="xsd:boolean" use="optional" default="false"/>
-            </xsd:extension>
-        </xsd:complexContent>
-    </xsd:complexType>
-
-</xsd:schema>
diff --git a/src/test/java/org.apache.aries.blueprint/BlueprintContainerTest.java b/src/test/java/org.apache.aries.blueprint/BlueprintContainerTest.java
new file mode 100644
index 0000000..3e41c6d
--- /dev/null
+++ b/src/test/java/org.apache.aries.blueprint/BlueprintContainerTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.aries.blueprint;
+
+import org.apache.aries.blueprint.container.BlueprintContainerImpl;
+import org.apache.aries.blueprint.sample.Foo;
+import org.junit.Test;
+
+import java.net.URL;
+import java.util.Arrays;
+
+import static org.junit.Assert.*;
+
+public class BlueprintContainerTest {
+
+    @Test
+    public void testSimple() throws Exception {
+        URL url = getClass().getClassLoader().getResource("test.xml");
+        BlueprintContainerImpl container = new BlueprintContainerImpl(getClass().getClassLoader(), Arrays.asList(url));
+
+        Foo foo = (Foo) container.getComponentInstance("foo");
+        System.out.println(foo);
+        assertNotNull(foo);
+        assertEquals(5, foo.getA());
+        assertEquals(1, foo.getB());
+
+        container.destroy();
+    }
+
+    @Test
+    public void testPlaceholders() throws Exception {
+        URL url1 = getClass().getClassLoader().getResource("test.xml");
+        URL url2 = getClass().getClassLoader().getResource("test2.xml");
+        BlueprintContainerImpl container = new BlueprintContainerImpl(getClass().getClassLoader(), Arrays.asList(url1, url2));
+
+        Foo foo = (Foo) container.getComponentInstance("foo");
+        System.out.println(foo);
+        assertNotNull(foo);
+        assertEquals(5, foo.getA());
+        assertEquals(1, foo.getB());
+
+        container.destroy();
+    }
+
+    public static void main(String[] args) throws Exception {
+        URL url = BlueprintContainerTest.class.getClassLoader().getResource("test.xml");
+        BlueprintContainerImpl container = new BlueprintContainerImpl(BlueprintContainerTest.class.getClassLoader(), Arrays.asList(url));
+        System.out.println(container.getComponentInstance("foo"));
+        container.destroy();
+    }
+}
diff --git a/src/test/java/org.apache.aries.blueprint/sample/Bar.java b/src/test/java/org.apache.aries.blueprint/sample/Bar.java
new file mode 100644
index 0000000..25f70cf
--- /dev/null
+++ b/src/test/java/org.apache.aries.blueprint/sample/Bar.java
@@ -0,0 +1,46 @@
+/**
+ *  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.aries.blueprint.sample;
+
+import java.util.List;
+
+public class Bar {
+    
+    private String value;
+    private List list;
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String s) {
+        value = s;
+    }
+
+    public List getList() {
+        return list;
+    }
+
+    public void setList(List l) {
+        list = l;
+    }
+
+    public String toString() {
+        return hashCode() + ": " + value + " " + list;
+    }
+
+}
diff --git a/src/test/java/org.apache.aries.blueprint/sample/CurrencyTypeConverter.java b/src/test/java/org.apache.aries.blueprint/sample/CurrencyTypeConverter.java
new file mode 100644
index 0000000..986787a
--- /dev/null
+++ b/src/test/java/org.apache.aries.blueprint/sample/CurrencyTypeConverter.java
@@ -0,0 +1,34 @@
+/**
+ *  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.aries.blueprint.sample;
+
+import org.osgi.service.blueprint.container.Converter;
+import org.osgi.service.blueprint.container.ReifiedType;
+
+import java.util.Currency;
+
+public class CurrencyTypeConverter implements Converter {
+
+    public boolean canConvert(Object fromValue, ReifiedType toType) {
+        return Currency.class.isAssignableFrom(toType.getRawClass());
+    }
+
+    public Object convert(Object source, ReifiedType toType) throws Exception {
+        return Currency.getInstance(source.toString());
+    }
+
+}
diff --git a/src/test/java/org.apache.aries.blueprint/sample/DateTypeConverter.java b/src/test/java/org.apache.aries.blueprint/sample/DateTypeConverter.java
new file mode 100644
index 0000000..11e9014
--- /dev/null
+++ b/src/test/java/org.apache.aries.blueprint/sample/DateTypeConverter.java
@@ -0,0 +1,42 @@
+/**
+ *  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.aries.blueprint.sample;
+
+import org.osgi.service.blueprint.container.Converter;
+import org.osgi.service.blueprint.container.ReifiedType;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DateTypeConverter implements Converter {
+
+    DateFormat dateFormat;
+    
+    public void setFormat(String format) {
+        dateFormat = new SimpleDateFormat(format);
+    }
+    
+    public Object convert(Object source, ReifiedType toType) throws Exception {
+        return dateFormat.parse(source.toString());
+    }
+
+    public boolean canConvert(Object fromValue, ReifiedType toType) {
+        return Date.class.isAssignableFrom(toType.getRawClass());
+    }
+
+}
diff --git a/src/test/java/org.apache.aries.blueprint/sample/Foo.java b/src/test/java/org.apache.aries.blueprint/sample/Foo.java
new file mode 100644
index 0000000..7eedebd
--- /dev/null
+++ b/src/test/java/org.apache.aries.blueprint/sample/Foo.java
@@ -0,0 +1,107 @@
+/**
+ *  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.aries.blueprint.sample;
+
+import java.io.Serializable;
+import java.util.Currency;
+import java.util.Date;
+import java.util.Map;
+
+public class Foo implements Serializable {
+    
+    private int a;
+    private int b;
+    private Bar bar;
+    private Currency currency;
+    private Date date;
+
+    public boolean initialized;
+    public boolean destroyed;
+    private Map<String, Object> props;
+
+    public int getA() {
+        return a;
+    }
+
+    public void setA(int i) {
+        a = i;
+    }
+
+    public int getB() {
+        return b;
+    }
+
+    public void setB(int i) {
+        b = i;
+    }
+
+    public Bar getBar() {
+        return bar;
+    }
+
+    public void setBar(Bar b) {
+        bar = b;
+    }
+
+    public Currency getCurrency() {
+        return currency;
+    }
+
+    public void setCurrency(Currency c) {
+        currency = c;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date d) {
+        date = d;
+    }
+
+    public String toString() {
+        return a + " " + b + " " + bar + " " + currency + " " + date;
+    }
+
+    public void init() {
+        System.out.println("======== Initializing Foo =========");
+        initialized = true;
+    }
+
+    public void destroy() {
+        System.out.println("======== Destroying Foo =========");
+        destroyed = true;
+    }
+
+    public boolean isInitialized() {
+        return initialized;
+    }
+
+    public boolean isDestroyed() {
+        return destroyed;
+    }
+
+    public void update(Map<String,Object> props) {
+        this.props = props;
+    }
+
+    public Map<String, Object> getProps() {
+        return props;
+    }
+
+}
+
diff --git a/src/test/java/org/apache/aries/blueprint/compendium/cm/BaseTest.java b/src/test/java/org/apache/aries/blueprint/compendium/cm/BaseTest.java
deleted file mode 100644
index 11b01c6..0000000
--- a/src/test/java/org/apache/aries/blueprint/compendium/cm/BaseTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import org.junit.After;
-import org.junit.Before;
-import org.ops4j.pax.swissbox.tinybundles.core.TinyBundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.service.blueprint.container.BlueprintContainer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class BaseTest {
-
-    private BundleContext bundleContext;
-    protected transient Logger log = LoggerFactory.getLogger(getClass());
-
-    @Before
-    public void setUp() throws Exception {
-        String symbolicName = getClass().getSimpleName();
-
-        TinyBundle cmBundle = Helper.createTestBundle("blueprint-cm", "1.0.0.SNAPSHOT", "OSGI-INF/blueprint/blueprint-cm.xml");
-        TinyBundle testBundle = Helper.createTestBundle(symbolicName, "1.0.0.SNAPSHOT", getBlueprintDescriptor());
-
-        this.bundleContext = Helper.createBundleContext(getBundleFilter(), new TinyBundle[] { cmBundle, testBundle });
-
-        // must wait for blueprint container to be published then the namespace parser is complete and we are ready for testing
-        log.debug("Waiting for BlueprintContainer to be published with symbolicName: {}", symbolicName);
-        getOsgiService(BlueprintContainer.class, "(osgi.blueprint.container.symbolicname=" + symbolicName + ")");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        Helper.disposeBundleContext(bundleContext);
-    }
-
-    /**
-     * Return the system bundle context
-     * @return
-     */
-    protected BundleContext getBundleContext() {
-        return bundleContext;
-    }
-
-    /**
-     * Gets the bundle descriptor from the classpath.
-     * <p/>
-     * Return the location(s) of the bundle descriptors from the classpath.
-     * Separate multiple locations by comma, or return a single location.
-     * <p/>
-     * For example override this method and return <tt>OSGI-INF/blueprint/camel-context.xml</tt>
-     *
-     * @return the location of the bundle descriptor file.
-     */
-    protected String getBlueprintDescriptor() {
-        return null;
-    }
-
-    /**
-     * Gets filter expression of bundle descriptors.
-     * Modify this method if you wish to change default behavior.
-     *
-     * @return filter expression for OSGi bundles.
-     */
-    protected String getBundleFilter() {
-        return Helper.BUNDLE_FILTER;
-    }
-
-    /**
-     * Gets test bundle version.
-     * Modify this method if you wish to change default behavior.
-     *
-     * @return test bundle version
-     */
-    protected String getBundleVersion() {
-        return Helper.BUNDLE_VERSION;
-    }
-
-    protected <T> T getOsgiService(Class<T> type) {
-        return Helper.getOsgiService(bundleContext, type);
-    }
-
-    protected <T> T getOsgiService(Class<T> type, long timeout) {
-        return Helper.getOsgiService(bundleContext, type, timeout);
-    }
-
-    protected <T> T getOsgiService(Class<T> type, String filter) {
-        return Helper.getOsgiService(bundleContext, type, filter);
-    }
-
-    protected <T> T getOsgiService(Class<T> type, String filter, long timeout) {
-        return Helper.getOsgiService(bundleContext, type, filter, timeout);
-    }
-
-}
diff --git a/src/test/java/org/apache/aries/blueprint/compendium/cm/CmPropertiesTest.java b/src/test/java/org/apache/aries/blueprint/compendium/cm/CmPropertiesTest.java
deleted file mode 100644
index 4409c68..0000000
--- a/src/test/java/org/apache/aries/blueprint/compendium/cm/CmPropertiesTest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.util.Hashtable;
-
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-public class CmPropertiesTest extends BaseTest {
-
-    @Override
-    protected String getBlueprintDescriptor() {
-        return "org/apache/aries/blueprint/compendium/cm/CmPropertiesTest.xml";
-    }
-
-    @Test
-    public void test4() throws Exception {
-        BundleContext context = getBundleContext();
-        ServiceReference sr = Helper.getOsgiServiceReference(context, FooInterface.class, "(key=foo4)", Helper.DEFAULT_TIMEOUT);
-        assertNotNull(sr);
-
-        FooInterface foo = (FooInterface) context.getService(sr);
-        assertNotNull(foo);
-        assertNotNull(foo.getProps());
-        assertTrue(foo.getProps().isEmpty());
-
-        ConfigurationAdmin ca = getOsgiService(ConfigurationAdmin.class);
-        Configuration cf = ca.getConfiguration("blueprint-sample-properties.pid", null);
-        Hashtable<String,String> props = new Hashtable<String,String>();
-        props.put("a", "5");
-        cf.update(props);
-
-        Thread.sleep(500);
-        assertFalse(foo.getProps().isEmpty());
-        assertEquals("5", foo.getProps().getProperty("a"));
-    }
-
-}
diff --git a/src/test/java/org/apache/aries/blueprint/compendium/cm/Foo.java b/src/test/java/org/apache/aries/blueprint/compendium/cm/Foo.java
deleted file mode 100644
index d2eac1d..0000000
--- a/src/test/java/org/apache/aries/blueprint/compendium/cm/Foo.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.util.Properties;
-
-public class Foo implements FooInterface {
-
-    public Foo() {
-    }
-
-    private int a;
-    private String b;
-    private Properties props;
-
-    public int getA() {
-        return a;
-    }
-
-    public void setA(int i) {
-        a = i;
-    }
-
-    public String getB() {
-        return b;
-    }
-
-    public void setB(String i) {
-        b = i;
-    }
-
-    public Properties getProps() {
-        return props;
-    }
-
-    public void setProps(Properties props) {
-        this.props = props;
-    }
-}
-
diff --git a/src/test/java/org/apache/aries/blueprint/compendium/cm/FooInterface.java b/src/test/java/org/apache/aries/blueprint/compendium/cm/FooInterface.java
deleted file mode 100644
index 9ab860d..0000000
--- a/src/test/java/org/apache/aries/blueprint/compendium/cm/FooInterface.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.util.Properties;
-
-public interface FooInterface {
-
-    Properties getProps();
-
-}
diff --git a/src/test/java/org/apache/aries/blueprint/compendium/cm/Helper.java b/src/test/java/org/apache/aries/blueprint/compendium/cm/Helper.java
deleted file mode 100644
index 56c749f..0000000
--- a/src/test/java/org/apache/aries/blueprint/compendium/cm/Helper.java
+++ /dev/null
@@ -1,781 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Scanner;
-import java.util.jar.JarInputStream;
-
-import de.kalpatec.pojosr.framework.PojoServiceRegistryFactoryImpl;
-import de.kalpatec.pojosr.framework.launch.BundleDescriptor;
-import de.kalpatec.pojosr.framework.launch.ClasspathScanner;
-import de.kalpatec.pojosr.framework.launch.PojoServiceRegistry;
-import de.kalpatec.pojosr.framework.launch.PojoServiceRegistryFactory;
-import org.ops4j.pax.swissbox.tinybundles.core.TinyBundle;
-import org.ops4j.pax.swissbox.tinybundles.core.TinyBundles;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-public final class Helper {
-
-    public static final long DEFAULT_TIMEOUT = 30000;
-    public static final String BUNDLE_FILTER = "(Bundle-SymbolicName=*)";
-    public static final String BUNDLE_VERSION = "1.0.0";
-    private static final transient Logger LOG = LoggerFactory.getLogger(Helper.class);
-
-    private Helper() {
-    }
-
-    public static BundleContext createBundleContext(String name, String descriptors, boolean includeTestBundle) throws Exception {
-        return createBundleContext(name, descriptors, includeTestBundle, BUNDLE_FILTER, BUNDLE_VERSION);
-    }
-
-    public static BundleContext createBundleContext(String name, String descriptors, boolean includeTestBundle,
-                                                    String bundleFilter, String testBundleVersion) throws Exception {
-        TinyBundle bundle = null;
-
-        if (includeTestBundle) {
-            // add ourselves as a bundle
-            bundle = createTestBundle(name, testBundleVersion, descriptors);
-        }
-
-        return createBundleContext(bundleFilter, new TinyBundle[] { bundle });
-    }
-
-    public static BundleContext createBundleContext(String bundleFilter, TinyBundle[] testBundles) throws Exception {
-        deleteDirectory("target/bundles");
-        createDirectory("target/bundles");
-
-        // ensure pojosr stores bundles in an unique target directory
-        System.setProperty("org.osgi.framework.storage", "target/bundles/" + System.currentTimeMillis());
-
-        // get the bundles
-        List<BundleDescriptor> bundles = getBundleDescriptors(bundleFilter);
-
-        if (testBundles != null) {
-            for (TinyBundle bundle : testBundles) {
-                File tmp = File.createTempFile("test-", ".jar", new File("target/bundles/"));
-                tmp.delete();
-                bundles.add(getBundleDescriptor(tmp.getPath(), bundle));
-            }
-        }
-
-        if (LOG.isDebugEnabled()) {
-            for (int i = 0; i < bundles.size(); i++) {
-                BundleDescriptor desc = bundles.get(i);
-                LOG.debug("Bundle #{} -> {}", i, desc);
-            }
-        }
-
-        // setup pojosr to use our bundles
-        Map<String, List<BundleDescriptor>> config = new HashMap<String, List<BundleDescriptor>>();
-        config.put(PojoServiceRegistryFactory.BUNDLE_DESCRIPTORS, bundles);
-
-        // create pojorsr osgi service registry
-        PojoServiceRegistry reg = new PojoServiceRegistryFactoryImpl().newPojoServiceRegistry(config);
-        return reg.getBundleContext();
-    }
-
-    public static void disposeBundleContext(BundleContext bundleContext) throws BundleException {
-        try {
-            if (bundleContext != null) {
-                bundleContext.getBundle().stop();
-            }
-        } finally {
-            System.clearProperty("org.osgi.framework.storage");
-        }
-    }
-
-    public static <T> T getOsgiService(BundleContext bundleContext, Class<T> type, long timeout) {
-        return getOsgiService(bundleContext, type, null, timeout);
-    }
-
-    public static <T> T getOsgiService(BundleContext bundleContext, Class<T> type) {
-        return getOsgiService(bundleContext, type, null, DEFAULT_TIMEOUT);
-    }
-
-    public static <T> T getOsgiService(BundleContext bundleContext, Class<T> type, String filter) {
-        return getOsgiService(bundleContext, type, filter, DEFAULT_TIMEOUT);
-    }
-
-    public static <T> ServiceReference getOsgiServiceReference(BundleContext bundleContext, Class<T> type, String filter, long timeout) {
-        ServiceTracker tracker = null;
-        try {
-            String flt;
-            if (filter != null) {
-                if (filter.startsWith("(")) {
-                    flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")" + filter + ")";
-                } else {
-                    flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")(" + filter + "))";
-                }
-            } else {
-                flt = "(" + Constants.OBJECTCLASS + "=" + type.getName() + ")";
-            }
-            Filter osgiFilter = FrameworkUtil.createFilter(flt);
-            tracker = new ServiceTracker(bundleContext, osgiFilter, null);
-            tracker.open(true);
-            // Note that the tracker is not closed to keep the reference
-            // This is buggy, as the service reference may change i think
-            Object svc = tracker.waitForService(timeout);
-            if (svc == null) {
-                Dictionary<?, ?> dic = bundleContext.getBundle().getHeaders();
-                System.err.println("Test bundle headers: " + explode(dic));
-
-                for (ServiceReference ref : asCollection(bundleContext.getAllServiceReferences(null, null))) {
-                    System.err.println("ServiceReference: " + ref + ", bundle: " + ref.getBundle() + ", symbolicName: " + ref.getBundle().getSymbolicName());
-                }
-
-                for (ServiceReference ref : asCollection(bundleContext.getAllServiceReferences(null, flt))) {
-                    System.err.println("Filtered ServiceReference: " + ref + ", bundle: " + ref.getBundle() + ", symbolicName: " + ref.getBundle().getSymbolicName());
-                }
-
-                throw new RuntimeException("Gave up waiting for service " + flt);
-            }
-            return tracker.getServiceReference();
-        } catch (InvalidSyntaxException e) {
-            throw new IllegalArgumentException("Invalid filter", e);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static <T> T getOsgiService(BundleContext bundleContext, Class<T> type, String filter, long timeout) {
-        ServiceTracker tracker = null;
-        try {
-            String flt;
-            if (filter != null) {
-                if (filter.startsWith("(")) {
-                    flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")" + filter + ")";
-                } else {
-                    flt = "(&(" + Constants.OBJECTCLASS + "=" + type.getName() + ")(" + filter + "))";
-                }
-            } else {
-                flt = "(" + Constants.OBJECTCLASS + "=" + type.getName() + ")";
-            }
-            Filter osgiFilter = FrameworkUtil.createFilter(flt);
-            tracker = new ServiceTracker(bundleContext, osgiFilter, null);
-            tracker.open(true);
-            // Note that the tracker is not closed to keep the reference
-            // This is buggy, as the service reference may change i think
-            Object svc = tracker.waitForService(timeout);
-            if (svc == null) {
-                Dictionary<?, ?> dic = bundleContext.getBundle().getHeaders();
-                System.err.println("Test bundle headers: " + explode(dic));
-
-                for (ServiceReference ref : asCollection(bundleContext.getAllServiceReferences(null, null))) {
-                    System.err.println("ServiceReference: " + ref + ", bundle: " + ref.getBundle() + ", symbolicName: " + ref.getBundle().getSymbolicName());
-                }
-
-                for (ServiceReference ref : asCollection(bundleContext.getAllServiceReferences(null, flt))) {
-                    System.err.println("Filtered ServiceReference: " + ref + ", bundle: " + ref.getBundle() + ", symbolicName: " + ref.getBundle().getSymbolicName());
-                }
-
-                throw new RuntimeException("Gave up waiting for service " + flt);
-            }
-            return type.cast(svc);
-        } catch (InvalidSyntaxException e) {
-            throw new IllegalArgumentException("Invalid filter", e);
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    protected static TinyBundle createTestBundle(String name, String version, String descriptors) throws FileNotFoundException, MalformedURLException {
-        TinyBundle bundle = TinyBundles.newBundle();
-        for (URL url : getBlueprintDescriptors(descriptors)) {
-            LOG.info("Using Blueprint XML file: " + url.getFile());
-            bundle.add("OSGI-INF/blueprint/blueprint-" + url.getFile().replace("/", "-"), url);
-        }
-        bundle.set("Manifest-Version", "2")
-                .set("Bundle-ManifestVersion", "2")
-                .set("Bundle-SymbolicName", name)
-                .set("Bundle-Version", version);
-        return bundle;
-    }
-
-    /**
-     * Explode the dictionary into a <code>,</code> delimited list of <code>key=value</code> pairs.
-     */
-    private static String explode(Dictionary<?, ?> dictionary) {
-        Enumeration<?> keys = dictionary.keys();
-        StringBuffer result = new StringBuffer();
-        while (keys.hasMoreElements()) {
-            Object key = keys.nextElement();
-            result.append(String.format("%s=%s", key, dictionary.get(key)));
-            if (keys.hasMoreElements()) {
-                result.append(", ");
-            }
-        }
-        return result.toString();
-    }
-
-    /**
-     * Provides an iterable collection of references, even if the original array is <code>null</code>.
-     */
-    private static Collection<ServiceReference> asCollection(ServiceReference[] references) {
-        return references  == null ? new ArrayList<ServiceReference>(0) : Arrays.asList(references);
-    }
-
-    /**
-     * Gets list of bundle descriptors.
-     * @param bundleFilter Filter expression for OSGI bundles.
-     *
-     * @return List pointers to OSGi bundles.
-     * @throws Exception If looking up the bundles fails.
-     */
-    private static List<BundleDescriptor> getBundleDescriptors(final String bundleFilter) throws Exception {
-        return new ClasspathScanner().scanForBundles(bundleFilter);
-    }
-
-    /**
-     * Gets the bundle descriptors as {@link URL} resources.
-     *
-     * @param descriptors the bundle descriptors, can be separated by comma
-     * @return the bundle descriptors.
-     * @throws FileNotFoundException is thrown if a bundle descriptor cannot be found
-     */
-    private static Collection<URL> getBlueprintDescriptors(String descriptors) throws FileNotFoundException, MalformedURLException {
-        List<URL> answer = new ArrayList<URL>();
-        String descriptor = descriptors;
-        if (descriptor != null) {
-            // there may be more resources separated by comma
-            Iterator<Object> it = createIterator(descriptor);
-            while (it.hasNext()) {
-                String s = (String) it.next();
-                LOG.trace("Resource descriptor: {}", s);
-
-                // remove leading / to be able to load resource from the classpath
-                s = stripLeadingSeparator(s);
-
-                // if there is wildcards for *.xml then we need to find the urls from the package
-                if (s.endsWith("*.xml")) {
-                    String packageName = s.substring(0, s.length() - 5);
-                    // remove trailing / to be able to load resource from the classpath
-                    Enumeration<URL> urls = loadResourcesAsURL(packageName);
-                    while (urls.hasMoreElements()) {
-                        URL url = urls.nextElement();
-                        File dir = new File(url.getFile());
-                        if (dir.isDirectory()) {
-                            File[] files = dir.listFiles();
-                            if (files != null) {
-                                for (File file : files) {
-                                    if (file.isFile() && file.exists() && file.getName().endsWith(".xml")) {
-                                        String name = packageName + file.getName();
-                                        LOG.debug("Resolving resource: {}", name);
-                                        URL xmlUrl = loadResourceAsURL(name);
-                                        if (xmlUrl != null) {
-                                            answer.add(xmlUrl);
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                } else {
-                    LOG.debug("Resolving resource: {}", s);
-                    URL url = resolveMandatoryResourceAsUrl(s);
-                    if (url == null) {
-                        throw new FileNotFoundException("Resource " + s + " not found");
-                    }
-                    answer.add(url);
-                }
-            }
-        } else {
-            throw new IllegalArgumentException("No bundle descriptor configured. Override getBlueprintDescriptor() or getBlueprintDescriptors() method");
-        }
-
-        if (answer.isEmpty()) {
-            throw new IllegalArgumentException("Cannot find any resources in classpath from descriptor " + descriptors);
-        }
-        return answer;
-    }
-
-    private static BundleDescriptor getBundleDescriptor(String path, TinyBundle bundle) throws Exception {
-        File file = new File(path);
-        FileOutputStream fos = new FileOutputStream(file, true);
-        try {
-            copy(bundle.build(), fos);
-        } finally {
-            close(fos);
-        }
-
-        FileInputStream fis = null;
-        JarInputStream jis = null;
-        try {
-            fis = new FileInputStream(file);
-            jis = new JarInputStream(fis);
-            Map<String, String> headers = new HashMap<String, String>();
-            for (Map.Entry<Object, Object> entry : jis.getManifest().getMainAttributes().entrySet()) {
-                headers.put(entry.getKey().toString(), entry.getValue().toString());
-            }
-
-            return new BundleDescriptor(
-                    bundle.getClass().getClassLoader(),
-                    new URL("jar:" + file.toURI().toString() + "!/"),
-                    headers);
-        } finally {
-            close(fis, jis);
-        }
-    }
-
-    /**
-     * Closes the given resource if it is available, logging any closing exceptions to the given log.
-     *
-     * @param closeable the object to close
-     * @param name the name of the resource
-     * @param log the log to use when reporting closure warnings, will use this class's own {@link Logger} if <tt>log == null</tt>
-     */
-    public static void close(Closeable closeable, String name, Logger log) {
-        if (closeable != null) {
-            try {
-                closeable.close();
-            } catch (IOException e) {
-                if (log == null) {
-                    // then fallback to use the own Logger
-                    log = LOG;
-                }
-                if (name != null) {
-                    log.warn("Cannot close: " + name + ". Reason: " + e.getMessage(), e);
-                } else {
-                    log.warn("Cannot close. Reason: " + e.getMessage(), e);
-                }
-            }
-        }
-    }
-
-    /**
-     * Closes the given resource if it is available.
-     *
-     * @param closeable the object to close
-     * @param name the name of the resource
-     */
-    public static void close(Closeable closeable, String name) {
-        close(closeable, name, LOG);
-    }
-
-    /**
-     * Closes the given resource if it is available.
-     *
-     * @param closeable the object to close
-     */
-    public static void close(Closeable closeable) {
-        close(closeable, null, LOG);
-    }
-
-    /**
-     * Closes the given resources if they are available.
-     *
-     * @param closeables the objects to close
-     */
-    public static void close(Closeable... closeables) {
-        for (Closeable closeable : closeables) {
-            close(closeable);
-        }
-    }
-
-    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
-    private static final String DEFAULT_DELIMITER = ",";
-
-    public static int copy(InputStream input, OutputStream output) throws IOException {
-        return copy(input, output, DEFAULT_BUFFER_SIZE);
-    }
-
-    public static int copy(final InputStream input, final OutputStream output, int bufferSize) throws IOException {
-        int avail = input.available();
-        if (avail > 262144) {
-            avail = 262144;
-        }
-        if (avail > bufferSize) {
-            bufferSize = avail;
-        }
-
-        final byte[] buffer = new byte[bufferSize];
-        int n = input.read(buffer);
-        int total = 0;
-        while (-1 != n) {
-            output.write(buffer, 0, n);
-            total += n;
-            n = input.read(buffer);
-        }
-        output.flush();
-        return total;
-    }
-
-    /**
-     * Creates an iterator over the value if the value is a collection, an
-     * Object[], a String with values separated by comma,
-     * or a primitive type array; otherwise to simplify the caller's code,
-     * we just create a singleton collection iterator over a single value
-     * <p/>
-     * Will default use comma for String separating String values.
-     * This method does <b>not</b> allow empty values
-     *
-     * @param value  the value
-     * @return the iterator
-     */
-    public static Iterator<Object> createIterator(Object value) {
-        return createIterator(value, DEFAULT_DELIMITER);
-    }
-
-    /**
-     * Creates an iterator over the value if the value is a collection, an
-     * Object[], a String with values separated by the given delimiter,
-     * or a primitive type array; otherwise to simplify the caller's
-     * code, we just create a singleton collection iterator over a single value
-     * <p/>
-     * This method does <b>not</b> allow empty values
-     *
-     * @param value      the value
-     * @param delimiter  delimiter for separating String values
-     * @return the iterator
-     */
-    public static Iterator<Object> createIterator(Object value, String delimiter) {
-        return createIterator(value, delimiter, false);
-    }
-
-    /**
-     * Creates an iterator over the value if the value is a collection, an
-     * Object[], a String with values separated by the given delimiter,
-     * or a primitive type array; otherwise to simplify the caller's
-     * code, we just create a singleton collection iterator over a single value
-     *
-     * @param value             the value
-     * @param delimiter         delimiter for separating String values
-     * @param allowEmptyValues  whether to allow empty values
-     * @return the iterator
-     */
-    @SuppressWarnings("unchecked")
-    public static Iterator<Object> createIterator(Object value, String delimiter, final boolean allowEmptyValues) {
-        if (value == null) {
-            return Collections.emptyList().iterator();
-        } else if (value instanceof Iterator) {
-            return (Iterator<Object>)value;
-        } else if (value instanceof Iterable) {
-            return ((Iterable<Object>)value).iterator();
-        } else if (value.getClass().isArray()) {
-            // TODO we should handle primitive array types?
-            List<Object> list = Arrays.asList((Object[])value);
-            return list.iterator();
-        } else if (value instanceof NodeList) {
-            // lets iterate through DOM results after performing XPaths
-            final NodeList nodeList = (NodeList) value;
-            return cast(new Iterator<Node>() {
-                int idx = -1;
-
-                public boolean hasNext() {
-                    return (idx + 1) < nodeList.getLength();
-                }
-
-                public Node next() {
-                    idx++;
-                    return nodeList.item(idx);
-                }
-
-                public void remove() {
-                    throw new UnsupportedOperationException();
-                }
-            });
-        } else if (value instanceof String) {
-            final String s = (String) value;
-
-            // this code is optimized to only use a Scanner if needed, eg there is a delimiter
-
-            if (delimiter != null && s.contains(delimiter)) {
-                // use a scanner if it contains the delimiter
-                Scanner scanner = new Scanner((String)value);
-
-                if (DEFAULT_DELIMITER.equals(delimiter)) {
-                    // we use the default delimiter which is a comma, then cater for bean expressions with OGNL
-                    // which may have balanced parentheses pairs as well.
-                    // if the value contains parentheses we need to balance those, to avoid iterating
-                    // in the middle of parentheses pair, so use this regular expression (a bit hard to read)
-                    // the regexp will split by comma, but honor parentheses pair that may include commas
-                    // as well, eg if value = "bean=foo?method=killer(a,b),bean=bar?method=great(a,b)"
-                    // then the regexp will split that into two:
-                    // -> bean=foo?method=killer(a,b)
-                    // -> bean=bar?method=great(a,b)
-                    // http://stackoverflow.com/questions/1516090/splitting-a-title-into-separate-parts
-                    delimiter = ",(?!(?:[^\\(,]|[^\\)],[^\\)])+\\))";
-                }
-
-                scanner.useDelimiter(delimiter);
-                return cast(scanner);
-            } else {
-                // use a plain iterator that returns the value as is as there are only a single value
-                return cast(new Iterator<String>() {
-                    int idx = -1;
-
-                    public boolean hasNext() {
-                        return idx + 1 == 0 && (allowEmptyValues || isNotEmpty(s));
-                    }
-
-                    public String next() {
-                        idx++;
-                        return s;
-                    }
-
-                    public void remove() {
-                        throw new UnsupportedOperationException();
-                    }
-                });
-            }
-        } else {
-            return Collections.singletonList(value).iterator();
-        }
-    }
-
-    /**
-     * Tests whether the value is <b>not</b> <tt>null</tt> or an empty string.
-     *
-     * @param value  the value, if its a String it will be tested for text length as well
-     * @return true if <b>not</b> empty
-     */
-    public static boolean isNotEmpty(Object value) {
-        if (value == null) {
-            return false;
-        } else if (value instanceof String) {
-            String text = (String) value;
-            return text.trim().length() > 0;
-        } else {
-            return true;
-        }
-    }
-
-    public static <T> Iterator<T> cast(Iterator<?> p) {
-        return (Iterator<T>) p;
-    }
-
-    /**
-     * Strip any leading separators
-     */
-    public static String stripLeadingSeparator(String name) {
-        if (name == null) {
-            return null;
-        }
-        while (name.startsWith("/") || name.startsWith(File.separator)) {
-            name = name.substring(1);
-        }
-        return name;
-    }
-
-    /**
-     * Attempts to load the given resources from the given package name using the thread context
-     * class loader or the class loader used to load this class
-     *
-     * @param packageName the name of the package to load its resources
-     * @return the URLs for the resources or null if it could not be loaded
-     */
-    public static Enumeration<URL> loadResourcesAsURL(String packageName) {
-        Enumeration<URL> url = null;
-
-        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-        if (contextClassLoader != null) {
-            try {
-                url = contextClassLoader.getResources(packageName);
-            } catch (IOException e) {
-                // ignore
-            }
-        }
-        if (url == null) {
-            try {
-                url = Helper.class.getClassLoader().getResources(packageName);
-            } catch (IOException e) {
-                // ignore
-            }
-        }
-
-        return url;
-    }
-
-    /**
-     * Attempts to load the given resource as a stream using the thread context
-     * class loader or the class loader used to load this class
-     *
-     * @param name the name of the resource to load
-     * @return the stream or null if it could not be loaded
-     */
-    public static URL loadResourceAsURL(String name) {
-        URL url = null;
-
-        String resolvedName = resolveUriPath(name);
-        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-        if (contextClassLoader != null) {
-            url = contextClassLoader.getResource(resolvedName);
-        }
-        if (url == null) {
-            url = Helper.class.getClassLoader().getResource(resolvedName);
-        }
-
-        return url;
-    }
-
-    /**
-     * Helper operation used to remove relative path notation from
-     * resources.  Most critical for resources on the Classpath
-     * as resource loaders will not resolve the relative paths correctly.
-     *
-     * @param name the name of the resource to load
-     * @return the modified or unmodified string if there were no changes
-     */
-    private static String resolveUriPath(String name) {
-        String answer = name;
-        if (answer.indexOf("//") > -1) {
-            answer = answer.replaceAll("//", "/");
-        }
-        if (answer.indexOf("../") > -1) {
-            answer = answer.replaceAll("[A-Za-z0-9]*/\\.\\./", "");
-        }
-        if (answer.indexOf("./") > -1) {
-            answer = answer.replaceAll("\\./", "");
-        }
-        return answer;
-    }
-
-    /**
-     * Resolves the mandatory resource.
-     *
-     * @param uri uri of the resource
-     * @return the resource as an {@link InputStream}.  Remember to close this stream after usage.
-     * @throws java.io.FileNotFoundException is thrown if the resource file could not be found
-     * @throws java.net.MalformedURLException if the URI is malformed
-     */
-    public static URL resolveMandatoryResourceAsUrl(String uri) throws FileNotFoundException, MalformedURLException {
-        if (uri.startsWith("file:")) {
-            // check if file exists first
-            String name = after(uri, "file:");
-            File file = new File(name);
-            if (!file.exists()) {
-                throw new FileNotFoundException("File " + file + " not found");
-            }
-            return new URL(uri);
-        } else if (uri.startsWith("http:")) {
-            return new URL(uri);
-        } else if (uri.startsWith("classpath:")) {
-            uri = after(uri, "classpath:");
-        }
-
-        // load from classpath by default
-        URL url = loadResourceAsURL(uri);
-        if (url == null) {
-            throw new FileNotFoundException("Cannot find resource in classpath for URI: " + uri);
-        } else {
-            return url;
-        }
-    }
-
-    public static String after(String text, String after) {
-        if (!text.contains(after)) {
-            return null;
-        }
-        return text.substring(text.indexOf(after) + after.length());
-    }
-
-    /**
-     * Recursively delete a directory, useful to zapping test data
-     *
-     * @param file the directory to be deleted
-     * @return <tt>false</tt> if error deleting directory
-     */
-    public static boolean deleteDirectory(String file) {
-        return deleteDirectory(new File(file));
-    }
-
-    /**
-     * Recursively delete a directory, useful to zapping test data
-     *
-     * @param file the directory to be deleted
-     * @return <tt>false</tt> if error deleting directory
-     */
-    public static boolean deleteDirectory(File file) {
-        int tries = 0;
-        int maxTries = 5;
-        boolean exists = true;
-        while (exists && (tries < maxTries)) {
-            recursivelyDeleteDirectory(file);
-            tries++;
-            exists = file.exists();
-            if (exists) {
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e) {
-                    // Ignore
-                }
-            }
-        }
-        return !exists;
-    }
-
-    private static void recursivelyDeleteDirectory(File file) {
-        if (!file.exists()) {
-            return;
-        }
-
-        if (file.isDirectory()) {
-            File[] files = file.listFiles();
-            for (File child : files) {
-                recursivelyDeleteDirectory(child);
-            }
-        }
-        boolean success = file.delete();
-        if (!success) {
-            LOG.warn("Deletion of file: " + file.getAbsolutePath() + " failed");
-        }
-    }
-
-    /**
-     * create the directory
-     *
-     * @param file the directory to be created
-     */
-    public static void createDirectory(String file) {
-        File dir = new File(file);
-        dir.mkdirs();
-    }
-
-
-}
diff --git a/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java b/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java
deleted file mode 100644
index be68982..0000000
--- a/src/test/java/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/**
- * 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.aries.blueprint.compendium.cm;
-
-import java.util.Hashtable;
-
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.cm.Configuration;
-import org.osgi.service.cm.ConfigurationAdmin;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-
-public class ManagedServiceFactoryTest extends BaseTest {
-
-    @Override
-    protected String getBlueprintDescriptor() {
-        return "org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.xml";
-    }
-
-    @Test
-    public void test1() throws Exception {
-        ConfigurationAdmin ca = getOsgiService(ConfigurationAdmin.class);
-        Configuration cf = ca.createFactoryConfiguration("blueprint-sample-managed-service-factory", null);
-        Hashtable<String,String> props = new Hashtable<String,String>();
-        props.put("a", "5");
-        cf.update(props);
-
-        BundleContext context = getBundleContext();
-        ServiceReference sr = Helper.getOsgiServiceReference(context, Foo.class, "(key=foo1)", Helper.DEFAULT_TIMEOUT);
-        assertNotNull(sr);
-        Foo foo = (Foo) context.getService(sr);
-        assertNotNull(foo);
-        assertEquals(5, foo.getA());
-        assertEquals("default", foo.getB());
-        assertEquals("5", sr.getProperty("a"));
-        assertNull(sr.getProperty("b"));
-
-        props = new Hashtable<String,String>();
-        props.put("a", "5");
-        props.put("b", "foo");
-        cf.update(props);
-        Thread.sleep(500);
-
-        // No update of bean after creation
-        assertEquals(5, foo.getA());
-        assertEquals("default", foo.getB());
-
-        // Only initial update of service properties
-        assertEquals("5", sr.getProperty("a"));
-        assertNull(sr.getProperty("b"));
-    }
-
-    @Test
-    public void test2() throws Exception {
-        ConfigurationAdmin ca = getOsgiService(ConfigurationAdmin.class);
-        Configuration cf = ca.createFactoryConfiguration("blueprint-sample-managed-service-factory2", null);
-        Hashtable<String,String> props = new Hashtable<String,String>();
-        props.put("a", "5");
-        cf.update(props);
-
-        BundleContext context = getBundleContext();
-        ServiceReference sr = Helper.getOsgiServiceReference(context, Foo.class, "(key=foo2)", Helper.DEFAULT_TIMEOUT);
-        assertNotNull(sr);
-
-        Foo foo = (Foo) context.getService(sr);
-        assertNotNull(foo);
-        assertEquals(5, foo.getA());
-        assertEquals("default", foo.getB());
-        assertNull(sr.getProperty("a"));
-        assertNull(sr.getProperty("b"));
-
-        props = new Hashtable<String,String>();
-        props.put("a", "5");
-        props.put("b", "foo");
-        cf.update(props);
-
-        // Update after creation
-        Thread.sleep(500);
-        assertEquals(5, foo.getA());
-        assertEquals("foo", foo.getB());
-
-        // No update of service properties
-        assertNull(sr.getProperty("a"));
-        assertNull(sr.getProperty("b"));
-    }
-
-    @Test
-    public void test3() throws Exception {
-        ConfigurationAdmin ca = getOsgiService(ConfigurationAdmin.class);
-        Configuration cf = ca.createFactoryConfiguration("blueprint-sample-managed-service-factory3", null);
-        Hashtable<String,String> props = new Hashtable<String,String>();
-        props.put("a", "5");
-        cf.update(props);
-
-        BundleContext context = getBundleContext();
-        ServiceReference sr = Helper.getOsgiServiceReference(context, Foo.class, "(key=foo3)", Helper.DEFAULT_TIMEOUT);
-        assertNotNull(sr);
-
-        Foo foo = (Foo) context.getService(sr);
-        assertNotNull(foo);
-        assertEquals(5, foo.getA());
-        assertEquals("default", foo.getB());
-        assertEquals("5", sr.getProperty("a"));
-        assertNull(sr.getProperty("b"));
-
-        props = new Hashtable<String,String>();
-        props.put("a", "5");
-        props.put("b", "foo");
-        cf.update(props);
-
-        // Update after creation
-        Thread.sleep(500);
-        assertEquals(5, foo.getA());
-        assertEquals("foo", foo.getB());
-
-        // Update of service properties
-        assertEquals("5", sr.getProperty("a"));
-        assertEquals("foo", sr.getProperty("b"));
-    }
-
-}
diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties
deleted file mode 100644
index 4d791eb..0000000
--- a/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,42 +0,0 @@
-## ------------------------------------------------------------------------
-## 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.
-## ------------------------------------------------------------------------
-
-#
-# The logging properties used for testing
-#
-log4j.rootLogger=DEBUG, out, file
-
-#log4j.logger.de.kalpatec.pojosr=DEBUG
-#log4j.logger.org.apache.camel.test.blueprint=DEBUG
-#log4j.logger.org.apache.camel=DEBUG
-#log4j.logger.org.apache.camel.blueprint=TRACE
-
-# CONSOLE appender not used by default
-log4j.appender.out=org.apache.log4j.ConsoleAppender
-log4j.appender.out.layout=org.apache.log4j.PatternLayout
-log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
-# MDC
-#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %-10.10X{camel.breadcrumbId} - %-10.10X{camel.exchangeId} - %-10.10X{camel.correlationId} - %-10.10X{camel.routeId} - %m%n
-
-# File appender
-log4j.appender.file=org.apache.log4j.FileAppender
-log4j.appender.file.layout=org.apache.log4j.PatternLayout
-log4j.appender.file.file=target/camel-test-blueprint.log
-log4j.appender.file.append=true
-log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
-# MDC
-#log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %-10.10X{camel.breadcrumbId} - %-10.10X{camel.exchangeId} - %-10.10X{camel.correlationId} - %-10.10X{camel.routeId} - %m%n
diff --git a/src/test/resources/org/apache/aries/blueprint/compendium/cm/CmPropertiesTest.xml b/src/test/resources/org/apache/aries/blueprint/compendium/cm/CmPropertiesTest.xml
deleted file mode 100644
index b705ae3..0000000
--- a/src/test/resources/org/apache/aries/blueprint/compendium/cm/CmPropertiesTest.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-        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.
-    -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-           xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0"
-           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0">
-
-    <cm:cm-properties id="myProps" persistent-id="blueprint-sample-properties.pid" />
-
-    <service id="myService" auto-export="interfaces">
-        <service-properties>
-            <entry key="key" value="foo4" />
-            <!--<cm:cm-properties persistent-id="org.foo.bar" />-->
-        </service-properties>
-        <bean class="org.apache.aries.blueprint.compendium.cm.Foo">
-            <property name="props" ref="myProps" />
-        </bean>
-    </service>
-
-
-</blueprint>
diff --git a/src/test/resources/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.xml b/src/test/resources/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.xml
deleted file mode 100644
index 457e8a8..0000000
--- a/src/test/resources/org/apache/aries/blueprint/compendium/cm/ManagedServiceFactoryTest.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!--
-        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.
-    -->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-           xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0">
-
-    <cm:managed-service-factory id="managed-service-factory"
-                                factory-pid="blueprint-sample-managed-service-factory"
-                                interface="org.apache.aries.blueprint.compendium.cm.Foo">
-        <service-properties>
-            <entry key="key" value="foo1" />
-            <cm:cm-properties persistent-id="" />
-        </service-properties>
-        <cm:managed-component class="org.apache.aries.blueprint.compendium.cm.Foo">
-            <cm:managed-properties persistent-id="" />
-            <property name="a" value="1" />
-            <property name="b" value="default" />
-        </cm:managed-component>
-    </cm:managed-service-factory>
-
-    <cm:managed-service-factory id="managed-service-factory2"
-                                factory-pid="blueprint-sample-managed-service-factory2"
-                                interface="org.apache.aries.blueprint.compendium.cm.Foo">
-        <service-properties>
-            <entry key="key" value="foo2" />
-        </service-properties>
-        <cm:managed-component class="org.apache.aries.blueprint.compendium.cm.Foo">
-            <cm:managed-properties persistent-id="" update-strategy="container-managed" />
-            <property name="a" value="1" />
-            <property name="b" value="default" />
-        </cm:managed-component>
-    </cm:managed-service-factory>
-
-    <cm:managed-service-factory id="managed-service-factory3"
-                                factory-pid="blueprint-sample-managed-service-factory3"
-                                interface="org.apache.aries.blueprint.compendium.cm.Foo">
-        <service-properties>
-            <entry key="key" value="foo3" />
-            <cm:cm-properties persistent-id="" update="true"/>
-        </service-properties>
-        <cm:managed-component class="org.apache.aries.blueprint.compendium.cm.Foo">
-            <cm:managed-properties persistent-id="" update-strategy="container-managed" />
-            <property name="a" value="1" />
-            <property name="b" value="default" />
-        </cm:managed-component>
-    </cm:managed-service-factory>
-
-</blueprint>
diff --git a/src/test/resources/test.properties b/src/test/resources/test.properties
new file mode 100644
index 0000000..23ffda0
--- /dev/null
+++ b/src/test/resources/test.properties
@@ -0,0 +1,20 @@
+################################################################################
+#
+#    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.
+#
+################################################################################
+
+key.b=1
diff --git a/src/test/resources/test.xml b/src/test/resources/test.xml
new file mode 100644
index 0000000..9e57a1a
--- /dev/null
+++ b/src/test/resources/test.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0"
+           default-availability="optional">
+
+    <type-converters>
+        <bean id="converter1" class="org.apache.aries.blueprint.sample.DateTypeConverter">
+            <property name="format" value="yyyy.MM.dd" />
+        </bean>
+        <bean id="converter2"
+              class="org.apache.aries.blueprint.sample.CurrencyTypeConverter" />
+
+    </type-converters>
+
+    <ext:property-placeholder placeholder-prefix="$["
+                              placeholder-suffix="]" ignore-missing-locations="true"
+                              system-properties="override">
+        <ext:default-properties>
+            <ext:property name="name" value="value" />
+            <ext:property name="a" value="Hello " />
+            <ext:property name="b" value="FooBar" />
+            <ext:property name="key.b" value="-1" />
+        </ext:default-properties>
+        <ext:location>file:///url</ext:location>
+        <ext:location>classpath:test.properties</ext:location>
+    </ext:property-placeholder>
+
+    <bean id="foo" class="org.apache.aries.blueprint.sample.Foo"
+          init-method="init" destroy-method="destroy">
+        <property name="a" value="5" />
+        <property name="b" value="$[key.b]" />
+        <property name="bar" ref="bar" />
+        <property name="currency">
+            <value>PLN</value>
+        </property>
+        <property name="date">
+            <value>2009.04.17</value>
+        </property>
+    </bean>
+
+    <bean id="bar" class="org.apache.aries.blueprint.sample.Bar">
+        <property name="value" value="$[a]$[b]">
+            <!--value>Hello FooBar</value-->
+        </property>
+        <property name="list">
+            <list>
+                <value>a list element</value>
+                <value type="java.lang.Integer">5</value>
+            </list>
+        </property>
+    </bean>
+
+</blueprint>
+
diff --git a/src/test/resources/test2.xml b/src/test/resources/test2.xml
new file mode 100644
index 0000000..40f093a
--- /dev/null
+++ b/src/test/resources/test2.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    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.
+-->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+           xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0"
+           default-availability="optional">
+
+    <ext:property-placeholder placeholder-prefix="$["
+                              placeholder-suffix="]" ignore-missing-locations="true"
+                              system-properties="override">
+        <ext:default-properties>
+            <ext:property name="c" value="FooBar" />
+        </ext:default-properties>
+    </ext:property-placeholder>
+
+</blueprint>
+