Move the iPOJO API in the trunk.

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@742381 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/api/LICENSE b/ipojo/api/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/ipojo/api/LICENSE
@@ -0,0 +1,202 @@
+
+                                 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/ipojo/api/LICENSE.asm b/ipojo/api/LICENSE.asm
new file mode 100644
index 0000000..9496b17
--- /dev/null
+++ b/ipojo/api/LICENSE.asm
@@ -0,0 +1,28 @@
+

+ ASM: a very small and fast Java bytecode manipulation framework

+ Copyright (c) 2000-2005 INRIA, France Telecom

+ All rights reserved.

+

+ Redistribution and use in source and binary forms, with or without

+ modification, are permitted provided that the following conditions

+ are met:

+ 1. Redistributions of source code must retain the above copyright

+    notice, this list of conditions and the following disclaimer.

+ 2. Redistributions in binary form must reproduce the above copyright

+    notice, this list of conditions and the following disclaimer in the

+    documentation and/or other materials provided with the distribution.

+ 3. Neither the name of the copyright holders nor the names of its

+    contributors may be used to endorse or promote products derived from

+    this software without specific prior written permission.

+

+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE

+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR

+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF

+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS

+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN

+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)

+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF

+ THE POSSIBILITY OF SUCH DAMAGE.

diff --git a/ipojo/api/NOTICE b/ipojo/api/NOTICE
new file mode 100644
index 0000000..6b4ac5d
--- /dev/null
+++ b/ipojo/api/NOTICE
@@ -0,0 +1,27 @@
+Apache Felix iPOJO API
+Copyright 2008 The Apache Software Foundation
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Copyright (c) 2000-2005 INRIA, France Telecom
+Licensed under BSD License.
+
+II. Used Software
+
+This product uses software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org).
+Copyright (c) OSGi Alliance (2000, 2007).
+Licensed under the Apache License 2.0.
+
+III. License Summary
+- Apache License 2.0
+- BSD Licence
diff --git a/ipojo/api/pom.xml b/ipojo/api/pom.xml
new file mode 100644
index 0000000..234dabb
--- /dev/null
+++ b/ipojo/api/pom.xml
@@ -0,0 +1,102 @@
+<!--

+	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.

+-->

+<project>

+	<modelVersion>4.0.0</modelVersion>

+	<packaging>bundle</packaging>

+	<groupId>org.apache.felix</groupId>

+	<artifactId>org.apache.felix.ipojo.api

+	</artifactId>

+	<version>1.1.0-SNAPSHOT</version>

+	<name>iPOJO API</name>

+	<build>

+		<plugins>

+			<plugin>

+				<groupId>org.apache.felix</groupId>

+				<artifactId>maven-bundle-plugin</artifactId>

+				<version>1.4.2</version>

+				<extensions>true</extensions>

+				<configuration>

+					<instructions>

+						<Bundle-SymbolicName>${pom.artifactId}

+						</Bundle-SymbolicName>

+						<Import-Package>!org.objectweb.asm.tree, *</Import-Package>

+						<Export-Package>org.apache.felix.ipojo.api

+						</Export-Package>

+						<Private-Package>org.apache.felix.ipojo.manipulation,

+							org.apache.felix.ipojo.manipulation.annotations,

+							org.objectweb.asm.commons, org.objectweb.asm</Private-Package>

+						<Include-Resource> META-INF/LICENCE=LICENSE,

+							META-INF/NOTICE=NOTICE, META-INF/LICENCE.asm=LICENSE.asm

+						</Include-Resource>

+					</instructions>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.codehaus.mojo</groupId>

+				<artifactId>rat-maven-plugin</artifactId>

+				<configuration>

+					<excludeSubProjects>false</excludeSubProjects>

+					<useEclipseDefaultExcludes>true</useEclipseDefaultExcludes>

+					<useMavenDefaultExcludes>true</useMavenDefaultExcludes>

+					<excludes>

+						<param>doc/**/*</param>

+						<param>maven-eclipse.xml</param>

+						<param>.checkstyle</param>

+						<param>.externalToolBuilders/*</param>

+						<param>LICENSE.asm</param>

+						<param>.fbprefs</param>

+					</excludes>

+				</configuration>

+			</plugin>

+			<plugin>

+				<groupId>org.apache.maven.plugins</groupId>

+				<artifactId>maven-checkstyle-plugin</artifactId>

+				<configuration>

+					<enableRulesSummary>false</enableRulesSummary>

+					<violationSeverity>warning</violationSeverity>

+					<configLocation>http://felix.apache.org/ipojo/dev/checkstyle_ipojo.xml</configLocation>

+				</configuration>

+			</plugin>

+		</plugins>

+	</build>

+	<dependencies>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo</artifactId>

+			<version>1.1.0-SNAPSHOT</version>

+		</dependency>

+		<dependency>

+			<groupId>org.apache.felix</groupId>

+			<artifactId>org.apache.felix.ipojo.manipulator

+			</artifactId>

+			<version>1.1.0-SNAPSHOT</version>

+		</dependency>

+		<dependency>

+			<groupId>asm</groupId>

+			<artifactId>asm-all</artifactId>

+			<version>3.0</version>

+			<exclusions>

+				<exclusion>

+					<groupId>asm</groupId>

+					<artifactId>asm-tree</artifactId>

+				</exclusion>

+			</exclusions>

+		</dependency>

+	</dependencies>

+</project>

diff --git a/ipojo/api/src/main/java/org/apache/felix/ipojo/api/ComponentType.java b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/ComponentType.java
new file mode 100644
index 0000000..b45d0b4
--- /dev/null
+++ b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/ComponentType.java
@@ -0,0 +1,197 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+
+
+/**
+ * The component type class allows specifying a new component type
+ * and its attached factory. It also allows creating instances form 
+ * the specified component type. 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class ComponentType {
+        
+    /**
+     * The list of instances created from the
+     * current component type.
+     */
+    private List m_instances = new ArrayList();
+    
+    /**
+     * Gets the factory attached to the current
+     * component type.
+     * @return the factory
+     */
+    public abstract Factory getFactory();
+    
+    /**
+     * Starts the factory attached to this 
+     * component type. Once started a factory 
+     * and its attached component type
+     * cannot be modified.
+     */
+    public abstract void start();
+    
+    /**
+     * Stops the factory attached to this 
+     * component type.
+     */
+    public abstract void stop();
+    
+    
+    /**
+     * Creates a component instance from the current type 
+     * with an empty configuration.
+     * @return the component instance object.
+     * @throws UnacceptableConfiguration the configuration is not acceptable 
+     * @throws MissingHandlerException the factory in invalid
+     * @throws ConfigurationException the instance configuration failed
+     */
+    public ComponentInstance createInstance() throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        ComponentInstance ci = ensureAndGetFactory().createComponentInstance(null); 
+        m_instances.add(ci);
+        return ci;
+    }
+    
+    /**
+     * Creates a component instance from the current type 
+     * with the given name.
+     * @param name the instance name
+     * @return the component instance object.
+     * @throws UnacceptableConfiguration the configuration is not acceptable 
+     * @throws MissingHandlerException the factory in invalid
+     * @throws ConfigurationException the instance configuration failed
+     */
+    public ComponentInstance createInstance(String name) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        Dictionary dict = null;
+        if (name != null) {
+            dict = new Properties();
+            dict.put("instance.name", name);
+        } 
+        ComponentInstance ci = ensureAndGetFactory().createComponentInstance(dict); 
+        m_instances.add(ci);
+        return ci;
+    }
+    
+    /**
+     * Creates a component instance from the current type 
+     * with the given configuration.
+     * @param conf the configuration
+     * @return the component instance object.
+     * @throws UnacceptableConfiguration the configuration is not acceptable 
+     * @throws MissingHandlerException the factory in invalid
+     * @throws ConfigurationException the instance configuration failed
+     */
+    public ComponentInstance createInstance(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        ComponentInstance ci = ensureAndGetFactory().createComponentInstance(conf);
+        m_instances.add(ci);
+        return ci;
+    }
+    
+    /**
+     * Disposes the given name. The instance must be created from this
+     * component type.
+     * @param ci the component instance to delete
+     * @return <code>true</code> if the instance was
+     * successfully disposed.
+     */
+    public boolean disposeInstance(ComponentInstance ci) {
+        if (m_instances.remove(ci)) {
+            ci.dispose();
+            return true;
+        } else {
+            System.err.println("The instance was not created from this component type");
+            return false;
+        }
+    }
+    
+    /**
+     * Gets the component instance created from this component type.
+     * with the given name.
+     * @param name the instance name.
+     * @return the component instance with the given name and created
+     * from the current component type factory. <code>null</code> if
+     * the instance cannot be found.
+     */
+    public ComponentInstance getInstanceByName(String name) {
+        for (int i = 0; i < m_instances.size(); i++) {
+            ComponentInstance ci = (ComponentInstance) m_instances.get(i);
+            if (ci.getInstanceName().equals(name)) {
+                return ci;
+            }
+        }
+        return null;
+    }
+    
+    /**
+     * Disposes the instance created with this component type which 
+     * has the given name.
+     * @param name the name of the instance to delete.
+     * @return <code>true</code> is the instance is successfully disposed.
+     */
+    public boolean disposeInstance(String name) {
+        ComponentInstance ci = getInstanceByName(name);
+        if (ci == null) {
+            System.err.println("The instance was not found in this component type");
+            return false;
+        } else {
+            return disposeInstance(ci);
+        }
+    }
+    
+    /**
+     * Returns the attached factory.
+     * Before returning the factory, the consistency of the
+     * factory is checked.
+     * @return the attached factory to the current component type
+     */
+    private Factory ensureAndGetFactory() {
+        ensureFactory();
+        return getFactory();
+    }
+    
+    /**
+     * Checks if the factory is already created.
+     */
+    private void ensureFactory() {
+        if (getFactory() == null) {
+            throw new IllegalStateException("The factory associated with the component type is not created");
+        } else {
+            if (getFactory().getState() == Factory.INVALID) {
+                throw new IllegalStateException("The factory associated with the component type is invalid (not started or missing handlers)");
+            }
+        }
+    }
+    
+    
+    
+
+
+}
diff --git a/ipojo/api/src/main/java/org/apache/felix/ipojo/api/Dependency.java b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/Dependency.java
new file mode 100644
index 0000000..a2dbe29
--- /dev/null
+++ b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/Dependency.java
@@ -0,0 +1,352 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.PrimitiveInstanceDescription;
+import org.apache.felix.ipojo.handlers.dependency.DependencyDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Allows configuring a service dependencies.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Dependency {
+    
+    /**
+     * The dynamic binding policy.
+     */
+    public static final int DYNAMIC = org.apache.felix.ipojo.handlers.dependency.Dependency.DYNAMIC_BINDING_POLICY;
+    
+    /**
+     * The static binding policy. 
+     */
+    public static final int STATIC = org.apache.felix.ipojo.handlers.dependency.Dependency.STATIC_BINDING_POLICY;
+    
+    /**
+     * The dynamic-priority binding policy.
+     */
+    public static final int DYNAMIC_PRIORITY = org.apache.felix.ipojo.handlers.dependency.Dependency.DYNAMIC_PRIORITY_BINDING_POLICY;
+
+    /**
+     * The required specification.
+     */
+    private String m_specification;
+    
+    /**
+     * The LDAP filter of the dependency. 
+     */
+    private String m_filter;
+    
+    /**
+     * The field of the implementation class attached to
+     * this dependency. 
+     */
+    private String m_field;
+    
+    /**
+     * Is the dependency optional? 
+     */
+    private boolean m_optional;
+    
+    /**
+     * Is the dependency aggregate? 
+     */
+    private boolean m_aggregate;
+    
+    /**
+     * Bind method attached to the dependency. 
+     */
+    private String m_bind;
+    
+    /**
+     * Unbind method attached to the dependency. 
+     */
+    private String m_unbind;
+    
+    /**
+     * The dependency binding policy. 
+     */
+    private int m_policy;
+    
+    /**
+     * The dependency comparator.
+     * (used to compare service providers) 
+     */
+    private String m_comparator;
+    
+    /**
+     * The dependency default-implementation. 
+     */
+    private String m_di;
+    
+    /**
+     * The dependency specific provider. 
+     */
+    private String m_from;
+    
+    /**
+     * The dependency id. 
+     */
+    private String m_id;
+    
+    /**
+     * Does the dependency supports nullable? 
+     */
+    private boolean m_nullable = true;
+
+    /**
+     * Gets the dependency metadata.
+     * @return the 'requires' element describing
+     * the current dependency.
+     */
+    public Element getElement() {
+        ensureValidity();
+        
+        Element dep = new Element("requires", "");
+        if (m_specification != null) {
+            dep.addAttribute(new Attribute("specification", m_specification));
+        }
+        if (m_filter != null) {
+            dep.addAttribute(new Attribute("filter", m_filter));
+        }
+        if (m_field != null) {
+            dep.addAttribute(new Attribute("field", m_field));
+        }
+        if (m_bind != null) {
+            Element cb = new Element("callback", "");
+            cb.addAttribute(new Attribute("type", "bind"));
+            cb.addAttribute(new Attribute("method", m_bind));
+            dep.addElement(cb);
+        }
+        if (m_unbind != null) {
+            Element cb = new Element("callback", "");
+            cb.addAttribute(new Attribute("type", "unbind"));
+            cb.addAttribute(new Attribute("method", m_unbind));
+            dep.addElement(cb);
+        }
+        if (m_comparator != null) {
+            dep.addAttribute(new Attribute("comparator", m_comparator));
+        }
+        if (m_di != null) {
+            dep.addAttribute(new Attribute("default-implementation", m_di));
+        }
+        if (m_from != null) {
+            dep.addAttribute(new Attribute("from", m_from));
+        }
+        if (m_id != null) {
+            dep.addAttribute(new Attribute("id", m_id));
+        }
+        if (! m_nullable) {
+            dep.addAttribute(new Attribute("nullable", "false"));
+        }
+        if (m_optional) {
+            dep.addAttribute(new Attribute("optional", "true"));
+        }
+        if (m_aggregate) {
+            dep.addAttribute(new Attribute("aggregate", "true"));
+        }
+        if (m_policy != -1) {
+            if (m_policy == DYNAMIC) {
+                dep.addAttribute(new Attribute("policy", "dynamic"));
+            } else if (m_policy == STATIC) {
+                dep.addAttribute(new Attribute("policy", "static"));
+            } else if (m_policy == DYNAMIC_PRIORITY) {
+                dep.addAttribute(new Attribute("policy", "dynamic-priority"));
+            }
+            // No other possibilities.
+        }
+        return dep;
+    }
+    
+    /**
+     * Sets the required service specification.
+     * @param spec the specification
+     * @return the current dependency object.
+     */
+    public Dependency setSpecification(String spec) {
+        m_specification = spec;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency filter.
+     * @param filter the LDAP filter
+     * @return the current dependency object
+     */
+    public Dependency setFilter(String filter) {
+        m_filter = filter;
+        return this;
+    }
+    
+    /**
+     * Sets the field attached to the dependency.
+     * @param field the implementation class field name.
+     * @return the current dependency object
+     */
+    public Dependency setField(String field) {
+        m_field = field;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency optionality.
+     * @param opt <code>true</code> to set the 
+     * dependency to optional.
+     * @return the current dependency object.
+     */
+    public Dependency setOptional(boolean opt) {
+        m_optional = opt;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency cardinality.
+     * @param agg <code>true</code> to set the 
+     * dependency to aggregate.
+     * @return the current dependency object.
+     */
+    public Dependency setAggregate(boolean agg) {
+        m_aggregate = agg;
+        return this;
+    }
+    
+    /**
+     * Sets if the dependency supports nullable objects.
+     * @param nullable <code>false</code> if the dependency does not
+     * support the nullable object injection
+     * @return the current dependency object.
+     */
+    public Dependency setNullable(boolean nullable) {
+        m_nullable = nullable;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency bind method.
+     * @param bind the bind method name
+     * @return the current dependency object.
+     */
+    public Dependency setBindMethod(String bind) {
+        m_bind = bind;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency unbind method.
+     * @param unbind the unbind method
+     * @return the current dependency object.
+     */
+    public Dependency setUnbindMethod(String unbind) {
+        m_unbind = unbind;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency binding policy.
+     * @param policy the binding policy
+     * @return the current dependency object
+     */
+    public Dependency setBindingPolicy(int policy) {
+        m_policy = policy;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency comparator.
+     * @param cmp the comparator class name
+     * @return the current dependency object
+     */
+    public Dependency setComparator(String cmp) {
+        m_comparator = cmp;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency default-implementation.
+     * @param di the default-implementation class name
+     * @return the current dependency object
+     */
+    public Dependency setDefaultImplementation(String di) {
+        m_di = di;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency 'from' attribute.
+     * @param from the name of the service provider.
+     * @return the current dependency object
+     */
+    public Dependency setFrom(String from) {
+        m_from = from;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency id.
+     * @param id the dependency id.
+     * @return the current dependency object.
+     */
+    public Dependency setId(String id) {
+        m_id = id;
+        return this;
+    }
+    
+    /**
+     * Checks dependency configuration validity.
+     */
+    private void ensureValidity() {
+        // At least a field or methods.
+        if (m_field == null && m_bind == null && m_unbind == null) {
+            throw new IllegalStateException("A dependency must have a field or bind/unbind methods");
+        }
+        // Check binding policy.
+        if (m_policy != -1) {
+            if (!(m_policy == DYNAMIC || m_policy == STATIC || m_policy == DYNAMIC_PRIORITY)) {
+                throw new IllegalStateException("Unknow binding policy : " + m_policy);
+            }
+        }
+    }
+    
+    /**
+     * Gets the dependency description object attached to
+     * this dependency.
+     * @param instance the instance on which searching the dependency
+     * @return the dependency description attached to this dependency or 
+     * <code>null</code> if the dependency cannot be found.
+     */
+    public DependencyDescription getDependencyDescription(ComponentInstance instance) {
+        PrimitiveInstanceDescription desc = (PrimitiveInstanceDescription) instance.getInstanceDescription();
+        if (m_id != null) {
+            return desc.getDependency(m_id);
+        }
+        if (m_specification != null) {
+            return desc.getDependency(m_specification);
+        }
+        DependencyDescription[] deps = desc.getDependencies();
+        if (deps.length == 1) {
+            return deps[0];
+        }
+        // Cannot determine the dependency. 
+        return null;
+    }
+    
+    
+}
diff --git a/ipojo/api/src/main/java/org/apache/felix/ipojo/api/PrimitiveComponentType.java b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/PrimitiveComponentType.java
new file mode 100644
index 0000000..5626615
--- /dev/null
+++ b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/PrimitiveComponentType.java
@@ -0,0 +1,459 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.manipulation.Manipulator;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Allows defining primitive component types.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PrimitiveComponentType extends ComponentType {
+
+    /**
+     * The bundle context.
+     */
+    private BundleContext m_context;
+    
+    /**
+     * The implementation class name. 
+     */
+    private String m_classname;
+    
+    /**
+     * The component type name. 
+     */
+    private String m_name;
+    
+    /**
+     * Is the component type immediate. 
+     */
+    private boolean m_immediate;
+    
+    /**
+     * Manipulation metadata of the component type.  
+     */
+    private Element m_manipulation;
+    
+    /**
+     * Component factory attached to the component
+     * type. 
+     */
+    private ComponentFactory m_factory;
+    
+    /**
+     * Component type metadata. 
+     */
+    private Element m_metadata;
+    
+    /**
+     * List of provided services. 
+     */
+    private List m_services = new ArrayList(1);
+    
+    /**
+     * List of service dependencies. 
+     */
+    private List m_dependencies = new ArrayList();
+    
+    /**
+     * List of configuration properties. 
+     */
+    private List m_properties = new ArrayList();
+    
+    /**
+     * The validate callback. 
+     */
+    private String m_validate;
+    
+    /**
+     * The invalidate callback. 
+     */
+    private String m_invalidate;
+    
+    /**
+     * Are the properties propagated to provided services? 
+     */
+    private boolean m_propagation;
+    
+    /**
+     * The factory method. 
+     */
+    private String m_factoryMethod;
+    
+    /**
+     * Is the factory public? 
+     */
+    private boolean m_public = true;
+    
+    /**
+     * The Managed Service PID.
+     */
+    private String m_msPID;
+
+    /**
+     * The temporal dependencies.
+     */
+    private ArrayList m_temporals = new ArrayList();;
+    
+    /**
+     * Checks that the component type is not already
+     * started.
+     */
+    private void ensureNotInitialized() {
+        if (m_factory != null) {
+            throw new IllegalStateException("The component type was already initialized, cannot modify metadata");
+        }
+    }
+    
+    /**
+     * Checks that the component type description is valid.
+     */
+    private void ensureValidity() {
+        if (m_classname == null) {
+            throw new IllegalStateException("The primitive component type has no implementation class");
+        }
+        if (m_context == null) {
+            throw new IllegalStateException("The primitive component type has no bundle context");
+        }
+    }
+
+    /**
+     * Gets the component factory.
+     * @return the factory attached to this component type.
+     * @see org.apache.felix.ipojo.api.ComponentType#getFactory()
+     */
+    public Factory getFactory() {
+        initializeFactory();
+        return m_factory;
+    }
+
+    /**
+     * Starts the component type.
+     * @see org.apache.felix.ipojo.api.ComponentType#start()
+     */
+    public void start() {
+        initializeFactory();
+        m_factory.start();
+    }
+
+    /**
+     * Stops the component type.
+     * @see org.apache.felix.ipojo.api.ComponentType#stop()
+     */
+    public void stop() {
+        initializeFactory();
+        m_factory.stop();
+    }
+    
+    /**
+     * Initializes the factory.
+     */
+    private void initializeFactory() {
+        if (m_factory == null) {
+            createFactory();
+        }
+    }
+    
+    /**
+     * Sets the bundle context.
+     * @param bc the bundle context
+     * @return the current component type
+     */
+    public PrimitiveComponentType setBundleContext(BundleContext bc) {
+        ensureNotInitialized();
+        m_context = bc;
+        return this;
+    }
+    
+    /**
+     * Sets the implementation class.
+     * @param classname the class name 
+     * @return the current component type
+     */
+    public PrimitiveComponentType setClassName(String classname) {
+        ensureNotInitialized();
+        m_classname = classname;
+        return this;
+    }
+    
+    /**
+     * Sets the component type name.
+     * @param name the factory name
+     * @return the current component type
+     */
+    public PrimitiveComponentType setComponentTypeName(String name) {
+        ensureNotInitialized();
+        m_name = name;
+        return this;
+    }
+    
+    /**
+     * Sets if the component type is immediate or not.
+     * @param immediate <code>true</code> to set the component
+     * type to immediate
+     * @return the current component type
+     */
+    public PrimitiveComponentType setImmediate(boolean immediate) {
+        ensureNotInitialized();
+        m_immediate = immediate;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency factory method.
+     * @param method the method used to create pojo object.
+     * @return the current component type
+     */
+    public PrimitiveComponentType setFactoryMethod(String method) {
+        ensureNotInitialized();
+        m_factoryMethod = method;
+        return this;
+    }
+    
+    /**
+     * Sets if the component type propagates properties to service properties.
+     * @param propagation <code>true</code> to enable propagation
+     * @return the current component type
+     */
+    public PrimitiveComponentType setPropagation(boolean propagation) {
+        ensureNotInitialized();
+        m_propagation = propagation;
+        return this;
+    }
+    
+    /**
+     * Sets the factory public aspect.
+     * @param visible <code>false</code> to create a private factory. 
+     * @return the current component type
+     */
+    public PrimitiveComponentType setPublic(boolean visible) {
+        ensureNotInitialized();
+        m_public = visible;
+        return this;
+    }
+    
+    /**
+     * Sets the managed service pid.
+     * @param pid the managed service pid
+     * @return the current component type
+     */
+    public PrimitiveComponentType setManagedServicePID(String pid) {
+        ensureNotInitialized();
+        m_msPID = pid;
+        return this;
+    }
+    
+    /**
+     * Sets the validate method.
+     * @param method the validate method
+     * @return the current component type
+     */
+    public PrimitiveComponentType setValidateMethod(String method) {
+        ensureNotInitialized();
+        m_validate = method;
+        return this;
+    }
+    
+    /**
+     * Sets the invalidate method.
+     * @param method the invalidate method
+     * @return the current component type
+     */
+    public PrimitiveComponentType setInvalidateMethod(String method) {
+        ensureNotInitialized();
+        m_invalidate = method;
+        return this;
+    }
+    
+    /**
+     * Generates the component description.
+     * @return the component type description of 
+     * the current component type
+     */
+    private Element generateComponentMetadata() {
+        Element element = new Element("component", "");
+        element.addAttribute(new Attribute("classname", m_classname));
+        if (m_name != null) {
+            element.addAttribute(new Attribute("name", m_name));
+        }
+        if (m_factoryMethod != null) {
+            element.addAttribute(new Attribute("factory-method", m_factoryMethod));
+        }
+        if (! m_public) {
+            element.addAttribute(new Attribute("public", "false"));
+        }
+        if (m_immediate) {
+            element.addAttribute(new Attribute("immediate", "true"));
+        }
+        for (int i = 0; i < m_services.size(); i++) {
+            Service svc = (Service) m_services.get(i);
+            element.addElement(svc.getElement());
+        }
+        for (int i = 0; i < m_dependencies.size(); i++) {
+            Dependency dep = (Dependency) m_dependencies.get(i);
+            element.addElement(dep.getElement());
+        }
+        for (int i = 0; i < m_temporals.size(); i++) {
+            TemporalDependency dep = (TemporalDependency) m_temporals.get(i);
+            element.addElement(dep.getElement());
+        }
+        if (m_validate != null) {
+            Element callback = new Element("callback", "");
+            callback.addAttribute(new Attribute("transition", "validate"));
+            callback.addAttribute(new Attribute("method", m_validate));
+            element.addElement(callback);
+        }
+        if (m_invalidate != null) {
+            Element callback = new Element("callback", "");
+            callback.addAttribute(new Attribute("transition", "invalidate"));
+            callback.addAttribute(new Attribute("method", m_invalidate));
+            element.addElement(callback);
+        }
+        
+        // Properties
+        // First determine if we need the properties element
+        if (m_propagation || m_msPID != null || ! m_properties.isEmpty()) {
+            Element properties = new Element("properties", "");
+            if (m_propagation) {
+                properties.addAttribute(new Attribute("propagation", "true"));
+            }
+            if (m_msPID != null) {
+                properties.addAttribute(new Attribute("pid", m_msPID));
+            }
+            for (int i = 0; i < m_properties.size(); i++) {
+                Property prop = (Property) m_properties.get(i);
+                properties.addElement(prop.getElement());
+            }
+            element.addElement(properties);
+        }
+        
+        return element;
+    }
+    
+    /**
+     * Creates the component factory.
+     */
+    private void createFactory() {
+        ensureValidity();
+        byte[] clazz = manipulate();
+        m_metadata = generateComponentMetadata();
+        Element meta = m_metadata;
+        meta.addElement(m_manipulation);
+        try {
+            m_factory = new ComponentFactory(m_context, clazz, meta);
+        } catch (ConfigurationException e) {
+            throw new IllegalStateException("An exception occurs during factory initialization : " + e.getMessage());
+        }
+       
+    }
+    
+    /**
+     * Manipulates the implementation class.
+     * @return the manipulated class
+     */
+    private byte[] manipulate() {
+        Manipulator manipulator = new Manipulator();
+        try {
+            byte[] array = getClassByteArray();
+            byte[] newclazz = manipulator.manipulate(array);
+            m_manipulation = manipulator.getManipulationMetadata();
+            return newclazz;
+        } catch (IOException e) {
+            throw new IllegalStateException("An exception occurs during implementation class manipulation : " + e.getMessage());
+        }
+    }
+    
+    /**
+     * Gets a class file as a byte array.
+     * @return the byte array.
+     * @throws IOException the class file cannot be read.
+     */
+    private byte[] getClassByteArray() throws IOException {
+        String filename = m_classname.replace('.', '/') + ".class";
+        URL url = m_context.getBundle().getResource(filename);
+        if (url == null) {
+            throw new IllegalStateException("An exception occurs during implementation class manipulation : cannot found the class file " + filename);
+        }
+        InputStream is = url.openStream();
+        if (is == null) {
+            throw new IllegalStateException("An exception occurs during implementation class manipulation : cannot read the class file " + url);
+        }
+        byte[] b = new byte[is.available()]; 
+        is.read(b); 
+        return b;
+    }
+
+    /**
+     * Adds a provided service.
+     * @param svc the service to add
+     * @return the current component type
+     */
+    public PrimitiveComponentType addService(Service svc) {
+        ensureNotInitialized();
+        m_services.add(svc);
+        return this;
+    }
+    
+    /**
+     * Adds a service dependency.
+     * @param dep the dependency to add
+     * @return the current component type
+     */
+    public PrimitiveComponentType addDependency(Dependency dep) {
+        ensureNotInitialized();
+        m_dependencies.add(dep);
+        return this;
+    }
+    
+    /**
+     * Adds a temporal service dependency.
+     * @param dep the temporal dependency to add
+     * @return the current component type
+     */
+    public PrimitiveComponentType addDependency(TemporalDependency dep) {
+        ensureNotInitialized();
+        m_temporals.add(dep);
+        return this;
+    }
+    
+    /**
+     * Adds a configuration property.
+     * @param prop the property to add
+     * @return the current component type
+     */
+    public PrimitiveComponentType addProperty(Property prop) {
+        ensureNotInitialized();
+        m_properties.add(prop);
+        return this;
+    }
+
+}
diff --git a/ipojo/api/src/main/java/org/apache/felix/ipojo/api/Property.java b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/Property.java
new file mode 100644
index 0000000..0e510bd
--- /dev/null
+++ b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/Property.java
@@ -0,0 +1,185 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.PrimitiveInstanceDescription;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Allows configuring a configuration property.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Property {
+    
+    /**
+     * The property name.
+     */
+    private String m_name;
+    
+    /**
+     * The property field. 
+     */
+    private String m_field;
+    
+    /**
+     * The property value. 
+     */
+    private String m_value;
+    
+    /**
+     * The property method. 
+     */
+    private String m_method;
+    
+    /**
+     * Is the property mandatory. 
+     */
+    private boolean m_mandatory;
+    
+    /**
+     * Is the property immutable. 
+     */
+    private boolean m_immutable;
+    
+    /**
+     * Sets the property name.
+     * @param name the property name
+     * @return the current property object
+     */
+    public Property setName(String name) {
+        m_name = name;
+        return this;
+    }
+    
+    /**
+     * Sets the property field.
+     * @param name the property field
+     * @return the current property object
+     */
+    public Property setField(String name) {
+        m_field = name;
+        return this;
+    }
+    
+    /**
+     * Sets the property method.
+     * @param name the property method
+     * @return the current property object
+     */
+    public Property setMethod(String name) {
+        m_method = name;
+        return this;
+    }
+    
+    /**
+     * Sets the property value.
+     * @param name the property value
+     * @return the current property object
+     */
+    public Property setValue(String name) {
+        m_value = name;
+        return this;
+    }
+    
+    /**
+     * Sets if the property is mandatory.
+     * @param mandatory <code>true</code> if the dependency is mandatory.
+     * @return the current property object
+     */
+    public Property setMandatory(boolean mandatory) {
+        m_mandatory = mandatory;
+        return this;
+    }
+    
+    /**
+     * Sets if the property is immutable.
+     * @param immutable <code>true</code> if the dependency is immutable.
+     * @return the current property object
+     */
+    public Property setImmutable(boolean immutable) {
+        m_immutable = immutable;
+        return this;
+    }
+    
+    /**
+     * Gets the property element.
+     * @return the property element.
+     */
+    public Element getElement() {
+        ensureValidity();
+        Element element = new Element("property", "");
+        if (m_name != null) {
+            element.addAttribute(new Attribute("name", m_name));
+        }
+        if (m_method != null) {
+            element.addAttribute(new Attribute("method", m_method));
+        }
+        if (m_value != null) {
+            element.addAttribute(new Attribute("value", m_value));
+        }
+        if (m_field != null) {
+            element.addAttribute(new Attribute("field", m_field));
+        }
+        if (m_mandatory) {
+            element.addAttribute(new Attribute("mandatory", Boolean.toString(m_mandatory)));
+        }
+        if (m_immutable) {
+            element.addAttribute(new Attribute("immutable", Boolean.toString(m_immutable)));
+        }
+        return element;
+    }
+
+    /**
+     * Checks the configuration validity.
+     */
+    private void ensureValidity() {
+        // Two cases
+        // Field or Method
+        if (m_field == null && m_method == null) {
+            throw new IllegalStateException("A property must have either a field or a method");
+        }
+        if (m_immutable && m_value == null) {
+            throw new IllegalStateException("A immutable service property must have a value");
+        }
+    }
+    
+    /**
+     * Gets the property description for the current property.
+     * @param instance the component instance on which looking for the property.
+     * @return the property description associated with the current property 
+     * or <code>null</code> if not found.
+     */
+    public PropertyDescription getPropertyDescription(ComponentInstance instance) {
+        PrimitiveInstanceDescription desc = (PrimitiveInstanceDescription) instance.getInstanceDescription();
+        PropertyDescription[] props = desc.getProperties();
+        
+        for (int i = 0; i < props.length; i++) {
+            if ((m_name != null && m_name.equals(props[i].getName())) 
+                    || (m_field != null && m_field.equals(props[i].getName()))) {
+                return props[i];
+            }
+        }
+           
+        return null;
+    }
+    
+}
diff --git a/ipojo/api/src/main/java/org/apache/felix/ipojo/api/Service.java b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/Service.java
new file mode 100644
index 0000000..f015735
--- /dev/null
+++ b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/Service.java
@@ -0,0 +1,212 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.PrimitiveInstanceDescription;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedService;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Allows configuring a provided service.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Service {
+    
+    /**
+     * The provided service specification. 
+     */
+    private List m_specifications; // null be default computed. 
+    
+    /**
+     * The provided service strategy. 
+     */
+    private int m_strategy = ProvidedService.SINGLETON_STRATEGY;
+    
+    /**
+     * The provided service custom strategy. 
+     */
+    private String m_customStrategy;
+    
+    /**
+     * The service properties. 
+     */
+    private List m_properties = new ArrayList();
+    
+    /**
+     * Gets the provided service element.
+     * @return the 'provides' element.
+     */
+    public Element getElement() {
+        ensureValidity();
+        Element element = new Element("provides", "");
+        if (m_specifications != null) {
+            element.addAttribute(new Attribute("specifications", getSpecificationsArray()));
+        }
+        element.addAttribute(new Attribute("strategy", getStringStrategy()));
+        for (int i = 0; i < m_properties.size(); i++) {
+            element.addElement(((ServiceProperty) m_properties.get(i)).getElement());
+        }
+        return element;   
+    }
+    
+    /**
+     * Gets the provided service description associated with the current service.
+     * @param instance the instance on which looking for the provided service description
+     * @return the provided service description or <code>null</code> if not found. 
+     */
+    public ProvidedServiceDescription getProvidedServiceDescription(ComponentInstance instance) {
+        PrimitiveInstanceDescription desc = (PrimitiveInstanceDescription) instance.getInstanceDescription();
+        ProvidedServiceDescription[] pss = desc.getProvidedServices();
+        if (pss.length == 0) {
+            return null;
+        }
+        
+        if (pss.length == 1) {
+            return pss[0];
+        }
+        
+        if (m_specifications == null) {
+            return null;
+        } else {
+            for (int j = 0; j < pss.length; j++) {
+                ProvidedServiceDescription psd = pss[j];
+                List specs = Arrays.asList(psd.getServiceSpecifications());
+                if (specs.containsAll(m_specifications)) {
+                    return psd;
+                }
+            }
+        }
+        
+        return null;
+    }
+
+
+    
+    /**
+     * Checks the validity of the configuration.
+     */
+    private void ensureValidity() {
+        // No check required.
+    }
+
+
+    /**
+     * The the service specification array as a String.
+     * @return the string-from of the service specifications.
+     */
+    private String getSpecificationsArray() {
+        if (m_specifications.size() == 1) {
+            return (String) m_specifications.get(0);
+        } else {
+            StringBuffer buffer = new StringBuffer("{");
+            for (int i = 0; i < m_specifications.size(); i++) {
+                if (i != 0) {
+                    buffer.append(',');
+                }
+                buffer.append(m_specifications.get(i));
+            }
+            buffer.append('}');
+            return buffer.toString();
+        }
+    }
+    
+    /**
+     * Adds a service property.
+     * @param ps the service property to add
+     * @return the current service object.
+     */
+    public Service addProperty(ServiceProperty ps) {
+        m_properties.add(ps);
+        return this;
+    }
+
+    /**
+     * Sets the provided service specification.
+     * @param spec the service specification
+     * @return the current service object.
+     */
+    public Service setSpecification(String spec) {
+        m_specifications = new ArrayList(1);
+        m_specifications.add(spec);
+        return this;
+    }
+    
+    /**
+     * Sets the provided service specifications.
+     * @param specs the service specifications
+     * @return the current service object.
+     */
+    public Service setSpecifications(List specs) {
+        m_specifications  = specs;
+        return this;
+    }
+    
+    /**
+     * Sets the creation strategy.
+     * @param strategy the service strategy.
+     * @return the current service object
+     */
+    public Service setCreationStrategy(int strategy) {
+        m_strategy = strategy;
+        return this;
+    }
+    
+    /**
+     * Sets the creation strategy.
+     * This method allows using a customized
+     * service strategy.
+     * @param strategy the service strategy
+     * @return the current service object
+     */
+    public Service setCreationStrategy(String strategy) {
+        m_strategy = -1; // Custom
+        m_customStrategy = strategy;
+        return this;
+    }
+    
+    /**
+     * Gets the string-form of the creation strategy.
+     * @return the creation strategy string form
+     */
+    private String getStringStrategy() {
+        switch (m_strategy) {
+            case -1: // Custom policies
+                return m_customStrategy;
+            case ProvidedService.SINGLETON_STRATEGY:
+                return "singleton";
+            case ProvidedService.STATIC_STRATEGY:
+                return "method";
+            case ProvidedService.SERVICE_STRATEGY:
+                return "service";
+            case ProvidedService.INSTANCE_STRATEGY:
+                return "instance";
+            default:
+                throw new IllegalStateException("Unknown creation strategy :  "
+                        + m_strategy);
+        }
+    }
+
+}
diff --git a/ipojo/api/src/main/java/org/apache/felix/ipojo/api/ServiceProperty.java b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/ServiceProperty.java
new file mode 100644
index 0000000..7fed046
--- /dev/null
+++ b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/ServiceProperty.java
@@ -0,0 +1,192 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.PrimitiveInstanceDescription;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Allows configuring a service property.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceProperty {
+    
+    /**
+     * The property name.
+     */
+    private String m_name;
+    
+    /**
+     * The property field. 
+     */
+    private String m_field;
+    
+    /**
+     * The property type. 
+     */
+    private String m_type;
+    
+    /**
+     * The property value. 
+     */
+    private String m_value;
+    
+    /**
+     * Is the property mandatory. 
+     */
+    private boolean m_mandatory;
+    
+    /**
+     * Is the property immutable. 
+     */
+    private boolean m_immutable;
+    
+    /**
+     * Sets the property name.
+     * @param name the property name
+     * @return the current property object
+     */
+    public ServiceProperty setName(String name) {
+        m_name = name;
+        return this;
+    }
+    
+    /**
+     * Sets the property field.
+     * @param name the property field
+     * @return the current property object
+     */
+    public ServiceProperty setField(String name) {
+        m_field = name;
+        return this;
+    }
+    
+    /**
+     * Sets the property type.
+     * @param name the property type
+     * @return the current property object
+     */
+    public ServiceProperty setType(String name) {
+        m_type = name;
+        return this;
+    }
+    
+    /**
+     * Sets the property value.
+     * @param name the property value
+     * @return the current property object
+     */
+    public ServiceProperty setValue(String name) {
+        m_value = name;
+        return this;
+    }
+    
+    /**
+     * Sets if the property is immutable.
+     * @param immutable <code>true</code> if the dependency is immutable.
+     * @return the current property object
+     */
+    public ServiceProperty setImmutable(boolean immutable) {
+        m_immutable = immutable;
+        return this;
+    }
+    
+    /**
+     * Sets if the property is mandatory.
+     * @param mandatory <code>true</code> if the dependency is mandatory.
+     * @return the current property object
+     */
+    public ServiceProperty setMandatory(boolean mandatory) {
+        m_mandatory = mandatory;
+        return this;
+    }
+    
+    
+    /**
+     * Gets the 'property' element.
+     * @return the element describing the current property.
+     */
+    public Element getElement() {
+        ensureValidity();
+        Element element = new Element("property", "");
+        if (m_name != null) {
+            element.addAttribute(new Attribute("name", m_name));
+        }
+        if (m_type != null) {
+            element.addAttribute(new Attribute("type", m_type));
+        }
+        if (m_value != null) {
+            element.addAttribute(new Attribute("value", m_value));
+        }
+        if (m_field != null) {
+            element.addAttribute(new Attribute("field", m_field));
+        }
+        if (m_mandatory) {
+            element.addAttribute(new Attribute("mandatory", Boolean.toString(m_mandatory)));
+        }
+        if (m_immutable) {
+            element.addAttribute(new Attribute("immutable", Boolean.toString(m_immutable)));
+        }
+        return element;
+    }
+
+    /**
+     * Checks the configuration validity.
+     */
+    private void ensureValidity() {
+        // Two cases
+        // Field or type
+        if (m_field == null && m_type == null) {
+            throw new IllegalStateException("A service property must have either a field or a type");
+        }
+        if (m_immutable && m_value == null) {
+            throw new IllegalStateException("A immutable service property must have a value");
+        }
+    }
+    
+    /**
+     * Gets the property value of the current property
+     * on the given instance.
+     * @param instance the instance on which looking for 
+     * the property value
+     * @return the property value or <code>null</code>
+     * if not found.
+     */
+    public Object getPropertyValue(ComponentInstance instance) {
+        PrimitiveInstanceDescription desc = (PrimitiveInstanceDescription) instance.getInstanceDescription();
+        ProvidedServiceDescription[] pss = desc.getProvidedServices();
+        for (int i = 0; i < pss.length; i++) {
+            // Check with the name
+            if (m_name != null && pss[i].getProperties().containsKey(m_name)) {
+                return pss[i].getProperties().get(m_name);
+            }
+            // Check with the field
+            if (m_field != null && pss[i].getProperties().containsKey(m_field)) {
+                return pss[i].getProperties().get(m_field);
+            }
+        }
+        // Not found.
+        return null;
+    }
+
+
+}
diff --git a/ipojo/api/src/main/java/org/apache/felix/ipojo/api/TemporalDependency.java b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/TemporalDependency.java
new file mode 100644
index 0000000..9344016
--- /dev/null
+++ b/ipojo/api/src/main/java/org/apache/felix/ipojo/api/TemporalDependency.java
@@ -0,0 +1,169 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.api;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Allows configuring a service dependencies.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class TemporalDependency {
+
+    /**
+     * The required specification.
+     */
+    private String m_specification;
+    
+    /**
+     * The LDAP filter of the dependency. 
+     */
+    private String m_filter;
+    
+    /**
+     * The field of the implementation class attached to
+     * this dependency. 
+     */
+    private String m_field;
+    
+    /**
+     * OnTimeout policy.
+     */
+    private String m_onTimeout;
+    
+    /**
+     * Timeout. 
+     */
+    private String m_timeout;
+    
+    /**
+     * Proxy. 
+     */
+    private boolean m_proxy = false;
+
+    /**
+     * Gets the dependency metadata.
+     * @return the 'requires' element describing
+     * the current dependency.
+     */
+    public Element getElement() {
+        ensureValidity();
+        
+        Element dep = new Element("requires", "org.apache.felix.ipojo.handler.temporal");
+        if (m_specification != null) {
+            dep.addAttribute(new Attribute("specification", m_specification));
+        }
+        if (m_filter != null) {
+            dep.addAttribute(new Attribute("filter", m_filter));
+        }
+        if (m_field != null) {
+            dep.addAttribute(new Attribute("field", m_field));
+        }
+        if (m_onTimeout != null) {
+            dep.addAttribute(new Attribute("omTimeout", m_onTimeout));
+        }
+        if (m_timeout != null) {
+            dep.addAttribute(new Attribute("timeout", m_timeout));
+        }
+        if (m_proxy) {
+            dep.addAttribute(new Attribute("proxy", "true"));
+        }
+        
+        return dep;
+    }
+    
+    /**
+     * Sets the required service specification.
+     * @param spec the specification
+     * @return the current dependency object.
+     */
+    public TemporalDependency setSpecification(String spec) {
+        m_specification = spec;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency filter.
+     * @param filter the LDAP filter
+     * @return the current dependency object
+     */
+    public TemporalDependency setFilter(String filter) {
+        m_filter = filter;
+        return this;
+    }
+    
+    /**
+     * Sets the field attached to the dependency.
+     * @param field the implementation class field name.
+     * @return the current dependency object
+     */
+    public TemporalDependency setField(String field) {
+        m_field = field;
+        return this;
+    }
+    
+    /**
+     * Sets if the dependency is injected as a proxy.
+     * @param proxy <code>true</code> to inject proxies.
+     * @return the current dependency object.
+     */
+    public TemporalDependency setProxy(boolean proxy) {
+        m_proxy = proxy;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency timeout.
+     * @param time the dependency timeout in ms
+     * 'infinite' for infinite.
+     * @return the current dependency object
+     */
+    public TemporalDependency setTimeout(String time) {
+        m_timeout = time;
+        return this;
+    }
+    
+    /**
+     * Sets the dependency ontimeout policy.
+     * Supports null, nullable, empty, and default-implementation.
+     * In this latter case, you must specify the qualified class name
+     * of the default-implementation (instead of default-implementation).
+     * Default: no action (i.e throws a runtime exception)
+     * @param tip the ontimeout policy
+     * @return the current dependency object
+     */
+    public TemporalDependency setOnTimeoutPolicy(String tip) {
+        m_onTimeout = tip;
+        return this;
+    }
+    
+   
+    /**
+     * Checks dependency configuration validity.
+     */
+    private void ensureValidity() {
+        // At least a field or methods.
+        if (m_field == null) {
+            throw new IllegalStateException("A temporal dependency must have a field");
+        }
+    }
+    
+    
+}