diff --git a/ipojo/runtime/DEPENDENCIES b/ipojo/runtime/DEPENDENCIES
new file mode 100644
index 0000000..8675421
--- /dev/null
+++ b/ipojo/runtime/DEPENDENCIES
@@ -0,0 +1,15 @@
+Apache Felix iPOJO Runtime Project
+Copyright 2008-2012 The Apache Software Foundation
+
+This software was developed at the Apache Software Foundation
+(http://www.apache.org) and may have dependencies on other
+Apache software licensed under Apache License 2.0.
+
+I. Included Third-Party Software
+
+
+II. Used Third-Party Software
+
+
+III. Overall License Summary
+- Apache License 2.0
diff --git a/ipojo/runtime/LICENSE b/ipojo/runtime/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/ipojo/runtime/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/runtime/NOTICE b/ipojo/runtime/NOTICE
new file mode 100644
index 0000000..3325754
--- /dev/null
+++ b/ipojo/runtime/NOTICE
@@ -0,0 +1,10 @@
+Apache Felix iPOJO Runtime Project
+Copyright 2008-2012 The Apache Software Foundation
+
+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.
diff --git a/ipojo/runtime/annotations/DEPENDENCIES b/ipojo/runtime/annotations/DEPENDENCIES
new file mode 100644
index 0000000..f759d7a
--- /dev/null
+++ b/ipojo/runtime/annotations/DEPENDENCIES
@@ -0,0 +1,13 @@
+Apache Felix iPOJO Annotations
+Copyright 2008-2011 The Apache Software Foundation
+
+This software was developed at the Apache Software Foundation
+(http://www.apache.org) and may have dependencies on other
+Apache software licensed under Apache License 2.0.
+
+I. Included Third-Party Software
+
+II. Used Third-Party Software
+
+III. Overall License Summary
+- Apache License 2.0
diff --git a/ipojo/runtime/annotations/LICENSE b/ipojo/runtime/annotations/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/ipojo/runtime/annotations/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/runtime/annotations/NOTICE b/ipojo/runtime/annotations/NOTICE
new file mode 100644
index 0000000..b1ed786
--- /dev/null
+++ b/ipojo/runtime/annotations/NOTICE
@@ -0,0 +1,7 @@
+Apache Felix iPOJO Annotations
+Copyright 2008-2011 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
diff --git a/ipojo/runtime/annotations/doc/changelog.txt b/ipojo/runtime/annotations/doc/changelog.txt
new file mode 100644
index 0000000..e2c9f16
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/changelog.txt
@@ -0,0 +1,74 @@
+Changes from the 1.6.4 to 1.8.0
+-------------------------------
+** Bug
+    * [FELIX-2568] - Rename Transactionnal to Transactional
+
+** Improvement
+    * [FELIX-1428] - Constructor injection of Configuration properties
+    * [FELIX-2620] - Change iPojo annotation parameters to follow java naming conventions
+    * [FELIX-2621] - Rename annotations to remove collisions
+    * [FELIX-2622] - Support static service properties that are not mirrored into fields
+    * [FELIX-2624] - Support multiple whiteboards using annotations
+    * [FELIX-2630] - Rename @Component attributes to follow the java naming conventions
+    * [FELIX-2631] - Rename @Publisher and @Subscriber attributes to follow the java naming conventions
+    * [FELIX-2633] - Rename JMX annotations
+    * [FELIX-2634] - Rename the @Publisher annotation into @Publishes annotation to avoid collision
+    * [FELIX-2666] - Rename the temporal handler annotation to avoid collision
+    * [FELIX-2742] - Constructor injection of service dependencies
+
+Changes from the 1.6.2 to 1.6.4
+-------------------------------
+** Improvement
+    * [FELIX-2420] - Enum support for @Property annotation
+    * [FELIX-2461] - Allow specifying the targeted service interface in the @ServiceController
+
+Changes from the 1.6.0 to 1.6.2
+-------------------------------
+** Improvement
+    * [FELIX-2296] - Access to ServiceReference in iPOJO service.
+
+Changes from the 1.4.0 to 1.6.0
+-------------------------------
+** Bug
+    * [FELIX-1557] - Cosmetic change of the Bundle-Name and Bundle-SymbolicName in iPOJO annotations.
+
+** Improvement
+    * [FELIX-1426] - Service injection with Dynamic Proxies
+    * [FELIX-1427] - Service injection with Smart Proxies
+    * [FELIX-1906] - Allow calling a method when service properties of an already injected service are modified
+
+** New Feature
+    * [FELIX-2132] - Provides a way to control service exposition from the implementation class
+
+** Wish
+    * [FELIX-1940] - Add @Instance annotation to declare instances without metadata.xml
+
+Changes from 1.2.0 to 1.4.0
+---------------------------
+** Bug
+    * [FELIX-1319] - Issue in the metadata overriding analysis in iPOJO annotations
+
+** Improvement
+    * Update parent pom
+
+
+Changes from 1.0.0 to 1.2.0
+---------------------------
+** Improvement
+    * [FELIX-825] - Provide annotation for iPojo JMX Handler
+    * [FELIX-834] - Provide Annotations for the extender, whiteboard and event admin handlers
+
+** Bug
+    * [FELIX-867] - iPOJO @ServiceProperty can target method
+    * [FELIX-868] - iPOJO @Component don't support factory methods
+
+
+Changes from 0.8.0 to 1.0.0
+---------------------------
+** Improvement
+    * [FELIX-627] - Temporal dependency annotation
+
+
+Version 0.8.0
+-------------
+    * Initial release
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations.html b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations.html
new file mode 100644
index 0000000..1ce24ba
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations.html
@@ -0,0 +1,744 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head>
+
+
+  
+    <title>Apache Felix - How to use iPOJO Annotations</title>
+    <link rel="stylesheet" href="how-to-use-ipojo-annotations_files/site.css" type="text/css" media="all">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+  </head><body>
+    <div class="title"><div class="logo"><a href="http://felix.apache.org/site/index.html"><img alt="Apache Felix" src="how-to-use-ipojo-annotations_files/logo.png" border="0"></a></div><div class="header"><a href="http://www.apache.org/"><img alt="Apache" src="how-to-use-ipojo-annotations_files/apache.png" border="0"></a></div></div>
+    <div class="menu">
+<ul>
+	<li><a href="http://felix.apache.org/site/news.html" title="news">news</a></li>
+	<li><a href="http://felix.apache.org/site/license.html" title="license">license</a></li>
+	<li><a href="http://felix.apache.org/site/downloads.cgi" rel="nofollow">downloads</a></li>
+	<li><a href="http://felix.apache.org/site/documentation.html" title="documentation">documentation</a></li>
+	<li><a href="http://felix.apache.org/site/mailinglists.html" title="mailinglists">mailing lists</a></li>
+	<li><a href="http://felix.apache.org/site/contributing.html" title="Contributing">contributing</a></li>
+	<li><a href="http://www.apache.org/" rel="nofollow">asf</a></li>
+	<li><a href="http://www.apache.org/foundation/sponsorship.html" rel="nofollow">sponsorship</a></li>
+	<li><a href="http://www.apache.org/foundation/thanks.html" rel="nofollow">sponsors</a>
+<!-- ApacheCon Ad -->
+<iframe src="how-to-use-ipojo-annotations_files/button.html" style="border-width: 0pt; float: left;" scrolling="no" frameborder="0" height="135" width="135"></iframe>
+<p style="height: 100px;">
+<!-- ApacheCon Ad -->
+</p></li></ul> </div>
+    <div class="main">
+<style type="text/css">
+ @import url(http://people.apache.org/~clement/ipojo/site/superfish.css); 
+</style>
+
+<style type="text/css">
+ @import url(http://people.apache.org/~clement/ipojo/site/style.css); 
+</style>
+
+<p>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shCore.js"></script>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shBrushCSharp.js"></script>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shBrushPhp.js"></script>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shBrushJScript.js"></script>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shBrushVb.js"></script>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shBrushSql.js"></script>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shBrushXml.js"></script>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shBrushShell.js"></script>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shBrushDelphi.js"></script>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shBrushPython.js"></script>
+<script class="javascript" src="how-to-use-ipojo-annotations_files/shBrushJava.js"></script>
+
+<script type="text/javascript" src="how-to-use-ipojo-annotations_files/jquery-1.js"></script>
+<script type="text/javascript" src="how-to-use-ipojo-annotations_files/hoverIntent.js"></script> 
+<script type="text/javascript" src="how-to-use-ipojo-annotations_files/superfish.js"></script> 
+<script type="text/javascript" src="how-to-use-ipojo-annotations_files/supersubs.js"></script> 
+
+<script type="text/javascript"> 
+ 
+    $(document).ready(function(){ 
+        $("ul.sf-menu").supersubs({ 
+            minWidth:    14,   // minimum width of sub-menus in em units 
+            maxWidth:    30,   // maximum width of sub-menus in em units 
+            extraWidth:  1     // extra width can ensure lines don't sometimes turn over 
+                               // due to slight rounding differences and font-family 
+        }).superfish();  // call supersubs first, then superfish, so that subs are 
+                         // not display:none when measuring. Call before initialising 
+                         // containing tabs for same reason. 
+    }); 
+ 
+</script>
+</p><div class="main">
+<div class="page-header">
+<img src="how-to-use-ipojo-annotations_files/header.png" class="header">
+<a href="http://ipojo.org/"><img src="how-to-use-ipojo-annotations_files/ipojo.png" class="header-logo" width="225"></a>
+<ul class="sf-menu sf-js-enabled sf-shadow" id="ipojo-menu">
+<li class="current">
+<!-- Menu Overview -->
+<a href="" class="sf-with-ul">Overview<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+<ul style="float: none; width: 14em; display: none; visibility: hidden;">
+	<li style="white-space: normal; float: left; width: 100%;">
+	<a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo.html" title="Apache Felix iPOJO">Home</a>							
+	</li>
+	<li style="white-space: normal; float: left; width: 100%;">
+	<a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-why-choose-ipojo.html" title="apache-felix-ipojo-why-choose-ipojo">Why choose iPOJO</a>
+	</li>
+	<li style="white-space: normal; float: left; width: 100%;">
+	<a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-successstories.html" title="apache-felix-ipojo-successstories">Success stories</a>
+	</li>
+	<li style="white-space: normal; float: left; width: 100%;">
+	<a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-feature-overview.html" title="Apache Felix iPOJO Feature Overview">Features</a>
+	</li>
+</ul>
+</li>	
+
+<li class="">			
+<!-- Menu download -->
+</li><li>
+<a href="http://felix.apache.org/site/download.html" title="Download">Download </a>
+</li>
+
+<li class="">					
+<!-- Menu Documentation -->
+<a href="" class="sf-with-ul">Documentation<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+<ul style="float: none; width: 14em; display: none; visibility: hidden;">
+    <!-- sub- menu : getting started -->
+    <li style="white-space: normal; float: left; width: 100%;" class="">
+    <a style="float: none; width: auto;" href="" class="sf-with-ul">Getting Started<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+    <ul style="left: 14em; float: none; width: 14em; display: none; visibility: hidden;">
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-in-10-minutes.html" title="iPOJO in 10 minutes">iPOJO in 10 minutes</a></li>
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="" title="How to use iPOJO Annotations">Using Annotations</a></li>
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-hello-word-maven-based-tutorial.html" title="iPOJO Hello Word (Maven-Based) tutorial">Maven tutorial</a></li>
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-advanced-tutorial.html" title="iPOJO Advanced Tutorial">Advanced tutorial</a></li>
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-dosgi.html" title="apache-felix-ipojo-dosgi">Using Distributed OSGi</a></li>
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-composition-tutorial.html" title="iPOJO Composition Tutorial">Application Composition</a></li>
+    </ul>
+    </li> <!-- end of getting started -->
+    <!-- sub menu : Describing Components -->
+     <li style="white-space: normal; float: left; width: 100%;" class="">
+        <a style="float: none; width: auto;" href="http://felix.apache.org/site/describing-components.html" class="sf-with-ul">Describing components<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+        <ul style="left: 14em; float: none; width: 14em; display: none; visibility: hidden;">
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/service-requirement-handler.html" title="Service Requirement Handler">Requiring a service</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/providing-osgi-services.html" title="Providing OSGi services">Providing a service</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/lifecycle-callback-handler.html" title="Lifecycle Callback Handler">Lifecycle management</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/configuration-handler.html" title="Configuration Handler">Configuration</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/architecture-handler.html" title="Architecture Handler">Introspection</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/controller-lifecycle-handler.html" title="Controller Lifecycle Handler">Impacting the lifecycle</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/event-admin-handlers.html" title="Event Admin Handlers">Asynchronous communication</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-jmx-handler.html" title="iPOJO JMX Handler">JMX management</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/extender-pattern-handler.html" title="Extender Pattern Handler">Extender pattern</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/white-board-pattern-handler.html" title="White Board Pattern Handler">Whiteboard pattern</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/temporal-service-dependency.html" title="Temporal Service Dependency">Temporal dependencies</a></li>
+        </ul>
+     </li> <!-- End of describing components -->
+    <!-- sub- menu : User Guide -->
+    <li style="white-space: normal; float: left; width: 100%;" class="">
+    <a style="float: none; width: auto;" href="" class="sf-with-ul">User Guide<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+        <ul style="left: 14em; float: none; width: 14em; display: none; visibility: hidden;">
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/using-xml-schemas.html" title="Using XML Schemas">XML Schemas</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-api.html" title="apache-felix-ipojo-api">API</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-testing-components.html" title="apache-felix-ipojo-testing-components">Testing components</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-eclipse-integration.html" title="apache-felix-ipojo-eclipse-integration">Eclipse Integration</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-faq.html" title="iPOJO FAQ">FAQ</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-reference-card.html" title="iPOJO-Reference-Card">Reference Card</a></li>
+        </ul>
+    </li> <!-- end of user guide -->
+    <!-- sub- menu : Dev Guide -->
+    <li class="" style="white-space: normal; float: left; width: 100%;"> 
+    <a style="float: none; width: auto;" href="" class="sf-with-ul">Advanced Topics<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+       <ul style="left: 14em; float: none; width: 14em; display: none; visibility: hidden;">
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/ipojo/api/1.2.0" rel="nofollow">Javadoc</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/how-to-write-your-own-handler.html" title="How to write your own handler">Handler guide</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/how-to-use-ipojo-manipulation-metadata.html" title="How to use iPOJO Manipulation Metadata">Manipulation Metadata </a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/dive-into-the-ipojo-manipulation-depths.html" title="Dive into the iPOJO Manipulation depths">Dive into the iPOJO Manipulation depths</a></li>
+       </ul>
+    </li> <!-- End of Dev guide -->
+</ul> 
+</li> <!-- End of doc -->
+<!-- Menu 4 : Tools -->
+<li class="">
+<a href="" class="sf-with-ul">Tools<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+<ul style="float: none; width: 14em; display: none; visibility: hidden;">
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-ant-task.html" title="iPOJO Ant Task">Ant Task</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-eclipse-plug-in.html" title="iPOJO Eclipse Plug-in">Eclipse Plugin</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-maven-plug-in.html" title="iPOJO Maven Plug-in">Maven Plugin</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-online-manipulator.html" title="apache-felix-ipojo-online-manipulator">Online Manipulator</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-webconsole-plugin.html" title="iPOJO Webconsole Plugin">Webconsole plugin</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html" title="apache-felix-ipojo-junit4osgi">Junit4OSGi</a></li>
+</ul>   
+</li><!-- End of tools -->					
+<!-- Menu 5 : Misc -->
+<li class="">
+<a href="" class="sf-with-ul">Misc<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+<ul style="float: none; width: 14em; display: none; visibility: hidden;">
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-issuestracker.html" title="apache-felix-ipojo-issuestracker">Issues Tracker</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-supportedvms.html" title="apache-felix-ipojo-supportedVMs">Supported JVMs</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-supportedosgi.html" title="apache-felix-ipojo-supportedOSGi">Supported OSGi Implementations</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://ipojo-dark-side.blogspot.com/" rel="nofollow">iPOJO's Dark Side Blog</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/article-presentations.html" title="Article &amp; Presentations">Article &amp; Presentations</a></li>
+</ul>
+</li><!-- End of misc -->
+</ul> <!-- End of the menu -->
+</div> <!-- Page header -->
+
+
+<div class="content">
+
+<h1><a name="HowtouseiPOJOAnnotations-HowtouseiPOJOannotations"></a>How to use iPOJO annotations</h1>
+
+<p><em>You can use annotations to define your component types. This page presents supported iPOJO annotations.</em></p>
+
+<div class="toc">
+<ul>
+    <li><a href="#HowtouseiPOJOAnnotations-GettingiPOJOAnnotations%253A">Getting iPOJO Annotations:</a></li>
+<ul>
+    <li><a href="#HowtouseiPOJOAnnotations-InEclipse">In Eclipse</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-InMaven">In Maven</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-InAnt">In Ant</a></li>
+</ul>
+    <li><a href="#HowtouseiPOJOAnnotations-Anexampleofusage">An example of usage</a></li>
+<ul>
+    <li><a href="#HowtouseiPOJOAnnotations-HelloServiceProvider">Hello Service Provider</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-HelloServiceConsumer">Hello Service Consumer</a></li>
+</ul>
+    <li><a href="#HowtouseiPOJOAnnotations-DefinedAnnotations">Defined Annotations</a></li>
+<ul>
+    <li><a href="#HowtouseiPOJOAnnotations-@Component">@Component</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-@Provides">@Provides</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-@Requires">@Requires</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-@ServiceProperty">@ServiceProperty</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-@Property">@Property</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-@Updated%255CNewsinthe1.3.0SNAPSHOTversion%255C">@Updated <b>[ News in the 1.3.0-SNAPSHOT version ]</b></a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-@Bind">@Bind</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-@Unbind">@Unbind</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-@Validate">@Validate</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-@Invalidate">@Invalidate</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-TemporalDependencies%2528externalhandler%2529">Temporal Dependencies (external handler)</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-ExposinginstancesasaJMXMBean%2528externalhandler%2529">Exposing instances as a JMX MBean (external handler)</a></li>
+</ul>
+    <li><a href="#HowtouseiPOJOAnnotations-AdvancedtopicsandFAQ">Advanced topics and FAQ</a></li>
+<ul>
+    <li><a href="#HowtouseiPOJOAnnotations-Metadatafileandannotationmerge">Metadata file and annotation merge</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-Instancecreation">Instance creation</a></li>
+    <li><a href="#HowtouseiPOJOAnnotations-UsingCustomAnnotations">Using Custom Annotations</a></li>
+</ul>
+</ul></div>
+
+<h2><a name="HowtouseiPOJOAnnotations-GettingiPOJOAnnotations:"></a>Getting iPOJO Annotations:</h2>
+
+<p>iPOJO Annotations are defines inside the
+org.apache.felix.ipojo.annotations project. You can download the Jar
+file of this project from the <a href="http://felix.apache.org/site/download.html" title="Download">download</a> page. Sources are available on the <a href="http://felix.apache.org/site/sourcecode.html" rel="nofollow">Felix trunk</a>.<br>
+Once added to your class path / build path / dependencies, you can use
+the annotations as normal annotations. These annotations are
+automatically processed by the iPOJO manipulator.</p>
+
+<h3><a name="HowtouseiPOJOAnnotations-InEclipse"></a>In Eclipse</h3>
+
+<p>Add the org.apache.felix.ipojo.annotations jar file in your build
+path. Do not forget to use a Java compiler accepting annotations (1.5
+or higher).</p>
+
+<h3><a name="HowtouseiPOJOAnnotations-InMaven"></a>In Maven</h3>
+
+<p>Add the following dependency:</p>
+<div class="code">
+<div class="dp-highlighter"><table class="dp-xml" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="line1"><span></span><span class="tag">&lt;</span><span>dependency</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span>groupId</span><span class="tag">&gt;</span><span>org.apache.felix</span><span class="tag">&lt;/</span><span>groupId</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span>artifactId</span><span class="tag">&gt;</span><span>org.apache.felix.ipojo.annotations</span><span class="tag">&lt;/</span><span>artifactId</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span>version</span><span class="tag">&gt;</span><span>1.2.0</span><span class="tag">&lt;/</span><span>version</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line1"><span class="tag">&lt;/</span><span>dependency</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr></tbody></table></div><textarea style="display: none;" name="newcodemacro" class="xml:nocontrols:nogutter" rows="10" readonly="readonly">&lt;dependency&gt;
+      &lt;groupId&gt;org.apache.felix&lt;/groupId&gt;
+      &lt;artifactId&gt;org.apache.felix.ipojo.annotations&lt;/artifactId&gt;
+      &lt;version&gt;1.2.0&lt;/version&gt;
+&lt;/dependency&gt;</textarea>
+<script class="javascript">
+    if(!window.newcodemacro_initialised)
+    {
+        window.newcodemacro_initialised = true;
+        window.oldonloadmethod = window.onload;
+        window.onload = function(){
+            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
+            if(window.oldonloadmethod)
+            {
+                window.oldonloadmethod();
+            }
+        }
+    }
+
+</script>
+</div>
+
+<p>Moreover, you need to set that the source code and the target code
+are Java 1.5 code. To achieve this, just add the following plugin in
+your plugins section:</p>
+<div class="code">
+<div class="dp-highlighter"><table class="dp-xml" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="line1"><span></span><span class="tag">&lt;</span><span>plugin</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span>groupId</span><span class="tag">&gt;</span><span>org.apache.maven.plugins</span><span class="tag">&lt;/</span><span>groupId</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span>artifactId</span><span class="tag">&gt;</span><span>maven-compiler-plugin</span><span class="tag">&lt;/</span><span>artifactId</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span>configuration</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span>source</span><span class="tag">&gt;</span><span>1.5</span><span class="tag">&lt;/</span><span>source</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span>target</span><span class="tag">&gt;</span><span>1.5</span><span class="tag">&lt;/</span><span>target</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span>configuration</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr><tr><td class="line2"><span class="tag">&lt;/</span><span>plugin</span><span class="tag">&gt;</span><span>&nbsp;</span></td></tr></tbody></table></div><textarea style="display: none;" name="newcodemacro" class="xml:nocontrols:nogutter" rows="10" readonly="readonly">&lt;plugin&gt;
+        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
+	&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
+	&lt;configuration&gt;
+	  &lt;source&gt;1.5&lt;/source&gt;
+	  &lt;target&gt;1.5&lt;/target&gt;
+	&lt;/configuration&gt;
+&lt;/plugin&gt;</textarea>
+<script class="javascript">
+    if(!window.newcodemacro_initialised)
+    {
+        window.newcodemacro_initialised = true;
+        window.oldonloadmethod = window.onload;
+        window.onload = function(){
+            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
+            if(window.oldonloadmethod)
+            {
+                window.oldonloadmethod();
+            }
+        }
+    }
+
+</script>
+</div>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-InAnt"></a>In Ant</h3>
+
+<p>Just add the org.apache.felix.ipojo.annotations jar file  in your class path.</p>
+
+<h2><a name="HowtouseiPOJOAnnotations-Anexampleofusage"></a>An example of usage</h2>
+
+<p>To illustrate annotations usage, let taking the tutorial example. In this tutorial, there are two components:</p>
+<ul>
+	<li>The first one provides the hello service</li>
+	<li>The second one uses the provided hello service<br>
+You can download the archive containing the examples and a preconfigured version of Felix <a href="http://people.apache.org/%7Eclement/ipojo/tutorials/annotations/annotation-tutorial.zip" rel="nofollow">here</a>.</li>
+</ul>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-HelloServiceProvider"></a>Hello Service Provider</h3>
+
+<p>The provider uses two annotations. The "component" annotation is
+mandatory and defines that the class defines a component type. Then the
+"provides" annotation just declare that the defined component type
+provides a service.</p>
+<div class="code">
+<div class="dp-highlighter"><table class="dp-c" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="line1"><span></span><span class="keyword">package</span><span>&nbsp;ipojo.example.hello.impl;&nbsp;</span></td></tr><tr><td class="line2">&nbsp;</td></tr><tr><td class="line1"><span class="keyword">import</span><span>&nbsp;ipojo.example.hello.Hello;&nbsp;</span></td></tr><tr><td class="line2">&nbsp;</td></tr><tr><td class="line1"><span class="keyword">import</span><span>&nbsp;org.apache.felix.ipojo.annotations.Component;&nbsp;</span></td></tr><tr><td class="line2"><span class="keyword">import</span><span>&nbsp;org.apache.felix.ipojo.annotations.Provides;&nbsp;</span></td></tr><tr><td class="line1">&nbsp;</td></tr><tr><td class="line2"><span class="comment">/**</span></td></tr><tr><td class="line1"><span class="comment">&nbsp;&nbsp;*&nbsp;Component&nbsp;implementing&nbsp;the&nbsp;Hello&nbsp;service.</span></td></tr><tr><td class="line2"><span class="comment">&nbsp;**/</span><span>&nbsp;</span></td></tr><tr><td class="line1"><span class="preprocessor">@Component</span><span>&nbsp;</span></td></tr><tr><td class="line2"><span class="preprocessor">@Provides</span><span>&nbsp;</span></td></tr><tr><td class="line1"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HelloImpl&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Hello&nbsp;{&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;sayHello(String&nbsp;name)&nbsp;{&nbsp;&nbsp;</span></td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;</span><span class="string">"hello&nbsp;"</span><span>&nbsp;+&nbsp;name;&nbsp;&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</td></tr><tr><td class="line1">}&nbsp;</td></tr></tbody></table></div><textarea style="display: none;" name="newcodemacro" class="java:nocontrols:nogutter" rows="10" readonly="readonly">package ipojo.example.hello.impl;
+
+import ipojo.example.hello.Hello;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Provides;
+
+/**
+  * Component implementing the Hello service.
+ **/
+@Component
+@Provides
+public class HelloImpl implements Hello {
+    public String sayHello(String name) { 
+     return "hello " + name; 
+    }
+}</textarea>
+<script class="javascript">
+    if(!window.newcodemacro_initialised)
+    {
+        window.newcodemacro_initialised = true;
+        window.oldonloadmethod = window.onload;
+        window.onload = function(){
+            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
+            if(window.oldonloadmethod)
+            {
+                window.oldonloadmethod();
+            }
+        }
+    }
+
+</script>
+</div>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-HelloServiceConsumer"></a>Hello Service Consumer</h3>
+
+<p>The Hello Service Consumer use more annotations. First it used the
+component annotation. To defines its "immediate" behavior, it add the
+'immediate' attribute.<br>
+Then, it uses the requires annotation to define a service dependency.
+Finally, it uses the validate and invalidate annotations to define
+lifecycle callbacks.</p>
+<div class="code">
+<div class="dp-highlighter"><table class="dp-c" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="line1"><span></span><span class="keyword">package</span><span>&nbsp;ipojo.example.hello.client;&nbsp;</span></td></tr><tr><td class="line2">&nbsp;</td></tr><tr><td class="line1"><span class="keyword">import</span><span>&nbsp;org.apache.felix.ipojo.annotations.Component;&nbsp;</span></td></tr><tr><td class="line2"><span class="keyword">import</span><span>&nbsp;org.apache.felix.ipojo.annotations.Invalidate;&nbsp;</span></td></tr><tr><td class="line1"><span class="keyword">import</span><span>&nbsp;org.apache.felix.ipojo.annotations.Requires;&nbsp;</span></td></tr><tr><td class="line2"><span class="keyword">import</span><span>&nbsp;org.apache.felix.ipojo.annotations.Validate;&nbsp;</span></td></tr><tr><td class="line1">&nbsp;</td></tr><tr><td class="line2"><span class="keyword">import</span><span>&nbsp;ipojo.example.hello.Hello;&nbsp;</span></td></tr><tr><td class="line1"><span class="preprocessor"></span></td></tr><tr><td class="line2"><span class="preprocessor">@Component(name="AnnotedHelloClient",&nbsp;immediate=true)</span><span>&nbsp;</span></td></tr><tr><td class="line1"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HelloClient&nbsp;</span><span class="keyword">implements</span><span>&nbsp;Runnable&nbsp;{&nbsp;</span></td></tr><tr><td class="line2"><span class="preprocessor"></span></td></tr><tr><td class="line1"><span class="preprocessor">@Requires</span><span>&nbsp;</span></td></tr><tr><td class="line2"><span class="keyword">private</span><span>&nbsp;Hello[]&nbsp;m_hello;&nbsp;</span><span class="comment">//&nbsp;Service&nbsp;Dependency</span><span>&nbsp;</span></td></tr><tr><td class="line1">&nbsp;</td></tr><tr><td class="line2"><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">final</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;int&nbsp;DELAY=10000;&nbsp;</span></td></tr><tr><td class="line1"><span class="keyword">private</span><span>&nbsp;</span><span class="keyword">boolean</span><span>&nbsp;end;&nbsp;</span></td></tr><tr><td class="line2">&nbsp;</td></tr><tr><td class="line1">&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;run()&nbsp;{&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">while</span><span>&nbsp;(!end)&nbsp;{&nbsp;</span></td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">try</span><span>&nbsp;{&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;invoke();&nbsp;</td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.sleep(DELAY);&nbsp;</td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span class="keyword">catch</span><span>&nbsp;(InterruptedException&nbsp;ie)&nbsp;{&nbsp;}&nbsp;</span></td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">/*&nbsp;will&nbsp;recheck&nbsp;end&nbsp;*/</span><span>&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</td></tr><tr><td class="line1">}&nbsp;</td></tr><tr><td class="line2">&nbsp;</td></tr><tr><td class="line1"><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;invoke()&nbsp;{&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;m_hello.length;&nbsp;i++)&nbsp;{&nbsp;&nbsp;</td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(m_hello[i].&nbsp;</td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sayHello(<span class="string">"Clement"</span><span>));&nbsp;&nbsp;</span></td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</td></tr><tr><td class="line2">}&nbsp;</td></tr><tr><td class="line1"><span class="preprocessor"></span></td></tr><tr><td class="line2"><span class="preprocessor">&nbsp;@Validate</span><span>&nbsp;</span></td></tr><tr><td class="line1">&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;starting()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;T&nbsp;=&nbsp;new&nbsp;Thread(<span class="keyword">this</span><span>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;=&nbsp;<span class="keyword">false</span><span>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr><tr><td class="line2">&nbsp;&nbsp;&nbsp;&nbsp;T.start();&nbsp;&nbsp;</td></tr><tr><td class="line1">&nbsp;}&nbsp;</td></tr><tr><td class="line2"><span class="preprocessor"></span></td></tr><tr><td class="line1"><span class="preprocessor">&nbsp;@Invalidate</span><span>&nbsp;</span></td></tr><tr><td class="line2">&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;stopping()&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></td></tr><tr><td class="line1">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;=&nbsp;<span class="keyword">true</span><span>;&nbsp;&nbsp;</span></td></tr><tr><td class="line2">&nbsp;}&nbsp;</td></tr><tr><td class="line1">}&nbsp;</td></tr></tbody></table></div><textarea style="display: none;" name="newcodemacro" class="java:nocontrols:nogutter" rows="10" readonly="readonly">package ipojo.example.hello.client;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Invalidate;
+import org.apache.felix.ipojo.annotations.Requires;
+import org.apache.felix.ipojo.annotations.Validate;
+
+import ipojo.example.hello.Hello;
+
+@Component(name="AnnotedHelloClient", immediate=true)
+public class HelloClient implements Runnable {
+
+@Requires
+private Hello[] m_hello; // Service Dependency
+
+private final static int DELAY=10000;
+private boolean end;
+
+ public void run() {
+    while (!end) {
+               try {
+		invoke();
+                Thread.sleep(DELAY);
+              } catch (InterruptedException ie) { }
+              /* will recheck end */
+     }
+}
+
+public void invoke() {
+	for (int i = 0; i &lt; m_hello.length; i++) { 
+          System.out.println(m_hello[i].
+             sayHello("Clement")); 
+        }
+}
+
+ @Validate
+ public void starting() {    
+    Thread T = new Thread(this);     
+    end = false;     
+    T.start(); 
+ }
+
+ @Invalidate
+ public void stopping() {    
+     end = true; 
+ }
+}</textarea>
+<script class="javascript">
+    if(!window.newcodemacro_initialised)
+    {
+        window.newcodemacro_initialised = true;
+        window.oldonloadmethod = window.onload;
+        window.onload = function(){
+            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
+            if(window.oldonloadmethod)
+            {
+                window.oldonloadmethod();
+            }
+        }
+    }
+
+</script>
+</div>
+
+
+<h2><a name="HowtouseiPOJOAnnotations-DefinedAnnotations"></a>Defined Annotations</h2>
+
+<p>This section lists defined annotations and how to use them.</p>
+
+<h3><a name="HowtouseiPOJOAnnotations-@Component"></a>@Component</h3>
+
+<p><b>Goal:</b> Defines a component type<br>
+<b>Target:</b> The component implementation class<br>
+<b>Attributes:</b></p>
+<ul>
+	<li>name : defines the component type name (optional, default = the class name)</li>
+	<li>immediate: defines the component type as immediate (optional, default = "false")</li>
+	<li>architecture: enable the architecture exposition (optional, default = "false")</li>
+	<li>propagation: enable configuration property propagation (on provided services) (optional, default = "false")</li>
+	<li>managedservice : set the Managed Service PID. (optional, default = no PID (i.e. the managed service will not be exposed)).</li>
+	<li>factory_method
+: set the factory-method. The specified method must be a static method
+and return a pojo object.(optional, default = iPOJO uses the 'regular'
+constructor).</li>
+	<li>public_factory : set if the component type is public. (optional, default = true).</li>
+</ul>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-@Provides"></a>@Provides</h3>
+
+<p><b>Goal:</b> Defines that the component type provide services<br>
+<b>Target:</b> The component implementation class<br>
+<b>Attributes:</b></p>
+<ul>
+	<li>specifications: defines the provided interface (optional, default = all implemented interfaces)</li>
+	<li>strategy
+: the service object creation strategy. Possible values : SINGLETON,
+SERVICE, METHOD, INSTANCE or the strategy class name. With SINGLETON
+there is only one POJO per component instance, SERVICE means OSGi
+Service factory, METHOD delegates the creation to the factory-method of
+the component, INSTANCE creates one service object per requiring
+instance. For other strategies, specify the qualified name of the
+CreationStrategy class. (optional, default = SINGLETON)</li>
+</ul>
+
+
+
+<div class="box">
+	<div class="box-blue-header">
+	<div class="box-blue-title">
+		<img src="how-to-use-ipojo-annotations_files/information.gif"> <b>OSGi Service Factory</b>
+	</div>
+	</div>
+	<div class="box-blue-content">
+The <tt>SERVICE</tt> strategy means OSGi service factory. So, one service object per asking bundle will be created.
+	</div>
+	<div class="box-blue-footer"></div>
+</div>
+
+
+
+
+<div class="box">
+	<div class="box-blue-header">
+	<div class="box-blue-title">
+		<img src="how-to-use-ipojo-annotations_files/information.gif"> <b>Changes between the 1.0.0 and the 1.2.0</b>
+	</div>
+	</div>
+	<div class="box-blue-content">
+The <tt>factory</tt> attribute became <tt>strategy</tt>. A third policy is now available (<tt>instance</tt>) allowing to create one service object per asking instance. Moreover, it is also possible to indicates the <tt>CreationStrategy</tt> class name. 
+	</div>
+	<div class="box-blue-footer"></div>
+</div>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-@Requires"></a>@Requires</h3>
+
+<p><b>Goal:</b> Defines a service dependency<br>
+<b>Target:</b> Field<br>
+<b>Attributes:</b></p>
+<ul>
+	<li>Filter: defines the LDAP filter (optional)</li>
+	<li>Optional: defines if the dependency is optional (optional, default = "false")</li>
+	<li>Id:
+defines the dependency Id (useful to identify bind &amp; unbind
+methods) (optional, default = field name) (if a dependency with the
+same id is already created (by a @bind or @unbind annotation), it
+merges the dependencies).</li>
+	<li>Nullable: enable or disable the
+Null Object injection when the dependency is optional and no providers
+are available (optional, default = "true")</li>
+	<li>Default-Implementation: set the Default-Implmentation (optional, by default iPOJO uses a Null object)</li>
+	<li>Policy: defines the binding policy (accepted value : dynamic, static, dynamic-priority) (optional, default = "dynamic")</li>
+	<li>Comparator: defines the comparator to use to sort service references (optional, default = OSGi Service Reference Comparator)</li>
+	<li>From : defines the specific provider to use</li>
+	<li>Specification
+: the required service specification. This attribute is required for
+Collection field. (optional, default = annotated field type).</li>
+</ul>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-@ServiceProperty"></a>@ServiceProperty</h3>
+
+<p><b>Goal:</b> Defines a service property<br>
+<b>Target:</b> Field<br>
+<b>Attributes:</b></p>
+<ul>
+	<li>name: property name (optional, default=field name</li>
+	<li>value: property value (optional, default=no value)</li>
+	<li>mandatory : is the property mandatory? (optional, default=false)</li>
+</ul>
+
+
+
+<div class="box">
+	<div class="box-blue-header">
+	<div class="box-blue-title">
+		<img src="how-to-use-ipojo-annotations_files/information.gif"> <b>Mandatory property</b>
+	</div>
+	</div>
+	<div class="box-blue-content">
+A mandatory property must receive a value either from the component type description (<tt>value</tt> attribute, or the instance configuration.
+	</div>
+	<div class="box-blue-footer"></div>
+</div>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-@Property"></a>@Property</h3>
+
+<p><b>Goal:</b> Defines a property<br>
+<b>Target:</b> Field or Method<br>
+<b>Attributes:</b></p>
+<ul>
+	<li>name: property name (optional, default=field name computed by
+removing "set" from the method name (for instance setFoo(String ff)
+will get the Foo name))</li>
+	<li>value: property value (optional, default=no value)</li>
+	<li>mandatory : is the property mandatory? (optional, default=false)</li>
+</ul>
+
+
+
+<div class="box">
+	<div class="box-blue-header">
+	<div class="box-blue-title">
+		<img src="how-to-use-ipojo-annotations_files/information.gif"> <b>Field and Method</b>
+	</div>
+	</div>
+	<div class="box-blue-content">
+If another property with the same name is defined the method or the field is added to the existing property.
+	</div>
+	<div class="box-blue-footer"></div>
+</div>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-@Updated\Newsinthe1.3.0SNAPSHOTversion\"></a>@Updated <b>[ News in the 1.3.0-SNAPSHOT version ]</b></h3>
+<p><b>Goal:</b> Defines method called when a reconfiguration is completed.<br>
+<b>Target:</b> a method (receiving a dictionary in argument)</p>
+
+<h3><a name="HowtouseiPOJOAnnotations-@Bind"></a>@Bind</h3>
+
+<p><b>Goal:</b> Defines a bind method<br>
+<b>Target:</b> Method<br>
+<b>Attributes:</b></p>
+<ul>
+	<li>Id: Dependency Id, if the id is already defines in a
+"@requires " or "@unbind" annotation, it adds this method as a bind
+method of the already created dependency. (optional, default= no id,
+compute an id if the method name begin by "bind" (for instance
+"bindFoo" will have the "Foo" id))</li>
+	<li>Specification : required dependency (optional)</li>
+	<li>Aggregate : is the dependency an aggregate dependency (optional, default= "false")</li>
+	<li>Optional: is the dependency an optional dependency (optional, default= "false")</li>
+	<li>Filter: dependency LDAP filter (optional)</li>
+	<li>Policy: defines the binding policy (accepted value : dynamic, static, dynamic-priority) (optional, default = "dynamic")</li>
+	<li>Comparator: defines the comparator to use to sort service references (optional, default = OSGi Service Reference Comparator)</li>
+	<li>From : defines the specific provider to use</li>
+</ul>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-@Unbind"></a>@Unbind</h3>
+
+<p><b>Goal:</b> Defines an unbind method<br>
+<b>Target:</b> Method<br>
+<b>Attributes:</b></p>
+<ul>
+	<li>Id: Dependency Id, if the id is already defines in a
+"@requires" or "@bind" annotation, it adds this method as an unbind
+method of the already created dependency. (optional, default= no id,
+compute an id if the method name begin by "unbind" (for instance
+"unbindFoo" will have the "Foo" id))</li>
+	<li>Specification : required dependency (optional)</li>
+	<li>Aggregate : is the dependency an aggregate dependency (optional, default= "false")</li>
+	<li>Optional: is the dependency an optional dependency (optional, default= "false")</li>
+	<li>Filter: dependency LDAP filter (optional)</li>
+	<li>Policy: defines the binding policy (accepted value : dynamic, static, dynamic-priority) (optional, default = "dynamic")</li>
+	<li>Comparator: defines the comparator to use to sort service references (optional, default = OSGi Service Reference Comparator)</li>
+	<li>From : defines the specific provider to use</li>
+</ul>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-@Validate"></a>@Validate</h3>
+
+<p><b>Goal:</b> defines a validate lifecycle callback<br>
+<b>Target:</b> method</p>
+
+<h3><a name="HowtouseiPOJOAnnotations-@Invalidate"></a>@Invalidate</h3>
+
+<p><b>Goal:</b> defines a validate lifecycle callback<br>
+<b>Target:</b> method</p>
+
+<h3><a name="HowtouseiPOJOAnnotations-TemporalDependencies(externalhandler)"></a>Temporal Dependencies (external handler)</h3>
+
+<p>The temporal dependency handler is an external handler. However, it
+can be used with an annotation defined in the iPOJO annotations jar
+file. <br>
+The annotation is org.apache.felix.ipojo.handler.temporal.Requires and targets a field. <br>
+<b>Attributes:</b></p>
+<ul>
+	<li>filter : specify the dependency filter</li>
+	<li>timeout : specify the dependency timeout (optional)</li>
+	<li>onTimeout
+: specify the onTimeout action (null, nullable, empty-array,
+default-implementation (specify the class name in this case) (optional).</li>
+	<li>specification
+: the required service specification. This attribute is required for
+Collection field. (optional, default = annotated field type).</li>
+	<li>Proxy :  Inject a proxy instead of the real object. This allows passing this reference to collaborators. (Default = false)</li>
+</ul>
+
+
+
+
+<h3><a name="HowtouseiPOJOAnnotations-ExposinginstancesasaJMXMBean(externalhandler)"></a>Exposing instances as a JMX MBean (external handler)</h3>
+
+<p>The JMX Handler allows exposing an instance as a JMX MBean. To
+configure the JMX handler directly from your code, three annotations
+are provided. They are in the <tt>org.apache.felix.ipojo.handlers.jmx</tt> package</p>
+
+<p>The <tt>@org.apache.felix.ipojo.handlers.jmx.Config</tt> (<tt>@Config</tt> if the package it correctly imported) annotation is a type annotation (so placed on the <tt>class</tt> element. This annotation indicates that the instance will be exposed as an MBean. This annotation supports:</p>
+<ul>
+	<li>usesMOSGi: set to <tt>true</tt> to use MOSGi. Otherwise, the MBean will be exposed in the MBean Platform Server (default: <tt>false</tt>).</li>
+	<li>objectname: set the MBean objectname. The objectname must follow JMX specification. (default: <tt>package-name:factory-name:instance-name</tt>)</li>
+	<li>domain: set the MBean domain. (default: <tt>package-name</tt>)</li>
+	<li>name: set the MBean name. (default: <tt>instance-name</tt>).</li>
+</ul>
+
+
+<p>The <tt>@org.apache.felix.ipojo.handlers.jmx.Property</tt> (<tt>@Property</tt>) annotation is a field annotation indicating that the field is exposed in the MBean. The supported attributes are:</p>
+<ul>
+	<li>name: set the property name</li>
+	<li>rights: set the access permission. Possible values are <tt>r</tt> (read only) and <tt>w</tt> (read and write). By default, properties are in read-only mode.</li>
+	<li>notification: enables notification on this property. By default notifications are disabled.</li>
+</ul>
+
+
+<p>The <tt>@org.apache.felix.ipojo.handlers.jmx.Method</tt> (<tt>@Method</tt>) annotation is a method annotation indicating that the method is exposed in the MBean. Only one attribute can be customized:</p>
+<ul>
+	<li>description: set the method description.</li>
+</ul>
+
+
+
+<h2><a name="HowtouseiPOJOAnnotations-AdvancedtopicsandFAQ"></a>Advanced topics and FAQ</h2>
+
+<h3><a name="HowtouseiPOJOAnnotations-Metadatafileandannotationmerge"></a>Metadata file and annotation merge</h3>
+
+<p>It is possible to defines component type both in the metadata file
+(in XML) and by using annotation. However, if a component type defined
+by using annotations has the same name than a type define in the XML
+file, the XML descriptor override the annotation defined type. However,
+a warning message is launched during the manipulation.</p>
+
+<h3><a name="HowtouseiPOJOAnnotations-Instancecreation"></a>Instance creation</h3>
+
+<p>Annotation can only be used to define component type. To define
+instances, you need to use the XML descriptor. Instance can refer to
+annotated types by referring to their names.</p>
+<div class="code">
+<div class="dp-highlighter"><table class="dp-xml" border="0" cellpadding="0" cellspacing="0"><tbody><tr><td class="line1"><span></span><span class="tag">&lt;</span><span>instance&nbsp;</span><span class="attribute">component</span><span>=</span><span class="attribute-value">"ipojo.example.hello.impl.HelloImpl"</span><span>/&gt;&nbsp;</span></td></tr><tr><td class="line2"><span class="tag">&lt;</span><span>instance&nbsp;</span><span class="attribute">component</span><span>=</span><span class="attribute-value">"AnnotedHelloClient"</span><span>/&gt;&nbsp;</span></td></tr></tbody></table></div><textarea style="display: none;" name="newcodemacro" class="xml:nocontrols:nogutter" rows="10" readonly="readonly">&lt;instance component="ipojo.example.hello.impl.HelloImpl"/&gt;
+&lt;instance component="AnnotedHelloClient"/&gt;</textarea>
+<script class="javascript">
+    if(!window.newcodemacro_initialised)
+    {
+        window.newcodemacro_initialised = true;
+        window.oldonloadmethod = window.onload;
+        window.onload = function(){
+            dp.SyntaxHighlighter.HighlightAll('newcodemacro');
+            if(window.oldonloadmethod)
+            {
+                window.oldonloadmethod();
+            }
+        }
+    }
+
+</script>
+</div>
+
+
+<h3><a name="HowtouseiPOJOAnnotations-UsingCustomAnnotations"></a>Using Custom Annotations</h3>
+
+<p>External handlers can provides their own annotations. Using these
+annotations just requires to add them to your build path. To external
+handlers annotations, please refer to the external handler
+documentation.
+<br clear="all">
+<br clear="all"></p>
+
+ </div>
+        <img src="how-to-use-ipojo-annotations_files/footer.png" class="footer">
+</div>
+
+<script type="text/javascript">
+var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+</script><script src="how-to-use-ipojo-annotations_files/ga.js" type="text/javascript"></script>
+<script type="text/javascript">
+try{
+var pageTracker = _gat._getTracker("UA-1518442-4");
+pageTracker._trackPageview();
+} catch(err) {}
+</script>
+
+    </div>
+  </body><div FirebugVersion="1.4.0" style="display: none;" id="_firebugConsole"></div></html>
\ No newline at end of file
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/apache.png b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/apache.png
new file mode 100644
index 0000000..5132f65
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/apache.png
Binary files differ
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/button.html b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/button.html
new file mode 100644
index 0000000..1721083
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/button.html
@@ -0,0 +1,2 @@
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body></body></html>
\ No newline at end of file
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/button_data/2009-europe-125x125.png b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/button_data/2009-europe-125x125.png
new file mode 100644
index 0000000..654a99c
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/button_data/2009-europe-125x125.png
Binary files differ
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/feed-icon-32x32.png b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/feed-icon-32x32.png
new file mode 100644
index 0000000..ea50b84
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/feed-icon-32x32.png
Binary files differ
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/footer.png b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/footer.png
new file mode 100644
index 0000000..15be425
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/footer.png
Binary files differ
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/ga.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/ga.js
new file mode 100644
index 0000000..0501070
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/ga.js
@@ -0,0 +1,41 @@
+var _gat=new Object({c:"length",lb:"4.3.1",m:"cookie",b:undefined,cb:function(d,a){this.zb=d;this.Nb=a},r:"__utma=",W:"__utmb=",ma:"__utmc=",Ta:"__utmk=",na:"__utmv=",oa:"__utmx=",Sa:"GASO=",X:"__utmz=",lc:"http://www.google-analytics.com/__utm.gif",mc:"https://ssl.google-analytics.com/__utm.gif",Wa:"utmcid=",Ya:"utmcsr=",$a:"utmgclid=",Ua:"utmccn=",Xa:"utmcmd=",Za:"utmctr=",Va:"utmcct=",Hb:false,_gasoDomain:undefined,_gasoCPath:undefined,e:window,a:document,k:navigator,t:function(d){var a=1,c=0,h,
+o;if(!_gat.q(d)){a=0;for(h=d[_gat.c]-1;h>=0;h--){o=d.charCodeAt(h);a=(a<<6&268435455)+o+(o<<14);c=a&266338304;a=c!=0?a^c>>21:a}}return a},C:function(d,a,c){var h=_gat,o="-",k,l,s=h.q;if(!s(d)&&!s(a)&&!s(c)){k=h.w(d,a);if(k>-1){l=d.indexOf(c,k);if(l<0)l=d[h.c];o=h.F(d,k+h.w(a,"=")+1,l)}}return o},Ea:function(d){var a=false,c=0,h,o;if(!_gat.q(d)){a=true;for(h=0;h<d[_gat.c];h++){o=d.charAt(h);c+="."==o?1:0;a=a&&c<=1&&(0==h&&"-"==o||_gat.P(".0123456789",o))}}return a},d:function(d,a){var c=encodeURIComponent;
+return c instanceof Function?(a?encodeURI(d):c(d)):escape(d)},J:function(d,a){var c=decodeURIComponent,h;d=d.split("+").join(" ");if(c instanceof Function)try{h=a?decodeURI(d):c(d)}catch(o){h=unescape(d)}else h=unescape(d);return h},Db:function(d){return d&&d.hash?_gat.F(d.href,_gat.w(d.href,"#")):""},q:function(d){return _gat.b==d||"-"==d||""==d},Lb:function(d){return d[_gat.c]>0&&_gat.P(" \n\r\t",d)},P:function(d,a){return _gat.w(d,a)>-1},h:function(d,a){d[d[_gat.c]]=a},T:function(d){return d.toLowerCase()},
+z:function(d,a){return d.split(a)},w:function(d,a){return d.indexOf(a)},F:function(d,a,c){c=_gat.b==c?d[_gat.c]:c;return d.substring(a,c)},uc:function(){var d=_gat.b,a=window;if(a&&a.gaGlobal&&a.gaGlobal.hid)d=a.gaGlobal.hid;else{d=Math.round(Math.random()*2147483647);a.gaGlobal=a.gaGlobal?a.gaGlobal:{};a.gaGlobal.hid=d}return d},wa:function(){return Math.round(Math.random()*2147483647)},Gc:function(){return(_gat.wa()^_gat.vc())*2147483647},vc:function(){var d=_gat.k,a=_gat.a,c=_gat.e,h=a[_gat.m]?
+a[_gat.m]:"",o=c.history[_gat.c],k,l,s=[d.appName,d.version,d.language?d.language:d.browserLanguage,d.platform,d.userAgent,d.javaEnabled()?1:0].join("");if(c.screen)s+=c.screen.width+"x"+c.screen.height+c.screen.colorDepth;else if(c.java){l=java.awt.Toolkit.getDefaultToolkit().getScreenSize();s+=l.screen.width+"x"+l.screen.height}s+=h;s+=a.referrer?a.referrer:"";k=s[_gat.c];while(o>0)s+=o--^k++;return _gat.t(s)}});_gat.hc=function(){var d=this,a=_gat.cb;function c(h,o){return new a(h,o)}d.db="utm_campaign";d.eb="utm_content";d.fb="utm_id";d.gb="utm_medium";d.hb="utm_nooverride";d.ib="utm_source";d.jb="utm_term";d.kb="gclid";d.pa=0;d.I=0;d.wb="15768000";d.Tb="1800";d.ea=[];d.ga=[];d.Ic="cse";d.Gb="q";d.ab="google";d.fa=[c(d.ab,d.Gb),c("yahoo","p"),c("msn","q"),c("bing","q"),c("aol","query"),c("aol","encquery"),c("lycos","query"),c("ask","q"),c("altavista","q"),c("netscape","query"),c("cnn","query"),c("looksmart","qt"),c("about",
+"terms"),c("mamma","query"),c("alltheweb","q"),c("gigablast","q"),c("voila","rdata"),c("virgilio","qs"),c("live","q"),c("baidu","wd"),c("alice","qs"),c("yandex","text"),c("najdi","q"),c("aol","q"),c("club-internet","query"),c("mama","query"),c("seznam","q"),c("search","q"),c("wp","szukaj"),c("onet","qt"),c("netsprint","q"),c("google.interia","q"),c("szukacz","q"),c("yam","k"),c("pchome","q"),c("kvasir","searchExpr"),c("sesam","q"),c("ozu","q"),c("terra","query"),c("nostrum","query"),c("mynet","q"),
+c("ekolay","q"),c("search.ilse","search_for")];d.B=undefined;d.Kb=false;d.p="/";d.ha=100;d.Da="/__utm.gif";d.ta=1;d.ua=1;d.G="|";d.sa=1;d.qa=1;d.pb=1;d.g="auto";d.D=1;d.Ga=1000;d.Yc=10;d.nc=10;d.Zc=0.2};_gat.Y=function(d,a){var c,h,o,k,l,s,q,f=this,n=_gat,w=n.q,x=n.c,g,z=a;f.a=d;function B(i){var b=i instanceof Array?i.join("."):"";return w(b)?"-":b}function A(i,b){var e=[],j;if(!w(i)){e=n.z(i,".");if(b)for(j=0;j<e[x];j++)if(!n.Ea(e[j]))e[j]="-"}return e}function p(){return u(63072000000)}function u(i){var b=new Date,e=new Date(b.getTime()+i);return"expires="+e.toGMTString()+"; "}function m(i,b){f.a[n.m]=i+"; path="+z.p+"; "+b+f.Cc()}function r(i,b,e){var j=f.V,t,v;for(t=0;t<j[x];t++){v=j[t][0];
+v+=w(b)?b:b+j[t][4];j[t][2](n.C(i,v,e))}}f.Jb=function(){return n.b==g||g==f.t()};f.Ba=function(){return l?l:"-"};f.Wb=function(i){l=i};f.Ma=function(i){g=n.Ea(i)?i*1:"-"};f.Aa=function(){return B(s)};f.Na=function(i){s=A(i)};f.Hc=function(){return g?g:"-"};f.Cc=function(){return w(z.g)?"":"domain="+z.g+";"};f.ya=function(){return B(c)};f.Ub=function(i){c=A(i,1)};f.K=function(){return B(h)};f.La=function(i){h=A(i,1)};f.za=function(){return B(o)};f.Vb=function(i){o=A(i,1)};f.Ca=function(){return B(k)};
+f.Xb=function(i){k=A(i);for(var b=0;b<k[x];b++)if(b<4&&!n.Ea(k[b]))k[b]="-"};f.Dc=function(){return q};f.Uc=function(i){q=i};f.pc=function(){c=[];h=[];o=[];k=[];l=n.b;s=[];g=n.b};f.t=function(){var i="",b;for(b=0;b<f.V[x];b++)i+=f.V[b][1]();return n.t(i)};f.Ha=function(i){var b=f.a[n.m],e=false;if(b){r(b,i,";");f.Ma(f.t());e=true}return e};f.Rc=function(i){r(i,"","&");f.Ma(n.C(i,n.Ta,"&"))};f.Wc=function(){var i=f.V,b=[],e;for(e=0;e<i[x];e++)n.h(b,i[e][0]+i[e][1]());n.h(b,n.Ta+f.t());return b.join("&")};
+f.bd=function(i,b){var e=f.V,j=z.p,t;f.Ha(i);z.p=b;for(t=0;t<e[x];t++)if(!w(e[t][1]()))e[t][3]();z.p=j};f.dc=function(){m(n.r+f.ya(),p())};f.Pa=function(){m(n.W+f.K(),u(z.Tb*1000))};f.ec=function(){m(n.ma+f.za(),"")};f.Ra=function(){m(n.X+f.Ca(),u(z.wb*1000))};f.fc=function(){m(n.oa+f.Ba(),p())};f.Qa=function(){m(n.na+f.Aa(),p())};f.cd=function(){m(n.Sa+f.Dc(),"")};f.V=[[n.r,f.ya,f.Ub,f.dc,"."],[n.W,f.K,f.La,f.Pa,""],[n.ma,f.za,f.Vb,f.ec,""],[n.oa,f.Ba,f.Wb,f.fc,""],[n.X,f.Ca,f.Xb,f.Ra,"."],[n.na,
+f.Aa,f.Na,f.Qa,"."]]};_gat.jc=function(d){var a=this,c=_gat,h=d,o,k=function(l){var s=(new Date).getTime(),q;q=(s-l[3])*(h.Zc/1000);if(q>=1){l[2]=Math.min(Math.floor(l[2]*1+q),h.nc);l[3]=s}return l};a.O=function(l,s,q,f,n,w,x){var g,z=h.D,B=q.location;if(!o)o=new c.Y(q,h);o.Ha(f);g=c.z(o.K(),".");if(g[1]<500||n){if(w)g=k(g);if(n||!w||g[2]>=1){if(!n&&w)g[2]=g[2]*1-1;g[1]=g[1]*1+1;l="?utmwv="+_gat.lb+"&utmn="+c.wa()+(c.q(B.hostname)?"":"&utmhn="+c.d(B.hostname))+(h.ha==100?"":"&utmsp="+c.d(h.ha))+l;if(0==z||2==z){var A=
+new Image(1,1);A.src=h.Da+l;var p=2==z?function(){}:x||function(){};A.onload=p}if(1==z||2==z){var u=new Image(1,1);u.src=("https:"==B.protocol?c.mc:c.lc)+l+"&utmac="+s+"&utmcc="+a.wc(q,f);u.onload=x||function(){}}}}o.La(g.join("."));o.Pa()};a.wc=function(l,s){var q=[],f=[c.r,c.X,c.na,c.oa],n,w=l[c.m],x;for(n=0;n<f[c.c];n++){x=c.C(w,f[n]+s,";");if(!c.q(x))c.h(q,f[n]+x+";")}return c.d(q.join("+"))}};_gat.i=function(){this.la=[]};_gat.i.bb=function(d,a,c,h,o,k){var l=this;l.cc=d;l.Oa=a;l.L=c;l.sb=h;l.Pb=o;l.Qb=k};_gat.i.bb.prototype.S=function(){var d=this,a=_gat.d;return"&"+["utmt=item","utmtid="+a(d.cc),"utmipc="+a(d.Oa),"utmipn="+a(d.L),"utmiva="+a(d.sb),"utmipr="+a(d.Pb),"utmiqt="+a(d.Qb)].join("&")};_gat.i.$=function(d,a,c,h,o,k,l,s){var q=this;q.v=d;q.ob=a;q.bc=c;q.ac=h;q.Yb=o;q.ub=k;q.$b=l;q.xb=s;q.ca=[]};_gat.i.$.prototype.mb=function(d,a,c,h,o){var k=this,l=k.Eb(d),s=k.v,q=_gat;if(q.b==
+l)q.h(k.ca,new q.i.bb(s,d,a,c,h,o));else{l.cc=s;l.Oa=d;l.L=a;l.sb=c;l.Pb=h;l.Qb=o}};_gat.i.$.prototype.Eb=function(d){var a,c=this.ca,h;for(h=0;h<c[_gat.c];h++)a=d==c[h].Oa?c[h]:a;return a};_gat.i.$.prototype.S=function(){var d=this,a=_gat.d;return"&"+["utmt=tran","utmtid="+a(d.v),"utmtst="+a(d.ob),"utmtto="+a(d.bc),"utmttx="+a(d.ac),"utmtsp="+a(d.Yb),"utmtci="+a(d.ub),"utmtrg="+a(d.$b),"utmtco="+a(d.xb)].join("&")};_gat.i.prototype.nb=function(d,a,c,h,o,k,l,s){var q=this,f=_gat,n=q.xa(d);if(f.b==
+n){n=new f.i.$(d,a,c,h,o,k,l,s);f.h(q.la,n)}else{n.ob=a;n.bc=c;n.ac=h;n.Yb=o;n.ub=k;n.$b=l;n.xb=s}return n};_gat.i.prototype.xa=function(d){var a,c=this.la,h;for(h=0;h<c[_gat.c];h++)a=d==c[h].v?c[h]:a;return a};_gat.gc=function(d){var a=this,c="-",h=_gat,o=d;a.Ja=screen;a.qb=!self.screen&&self.java?java.awt.Toolkit.getDefaultToolkit():h.b;a.a=document;a.e=window;a.k=navigator;a.Ka=c;a.Sb=c;a.tb=c;a.Ob=c;a.Mb=1;a.Bb=c;function k(){var l,s,q,f,n="ShockwaveFlash",w="$version",x=a.k?a.k.plugins:h.b;if(x&&x[h.c]>0)for(l=0;l<x[h.c]&&!q;l++){s=x[l];if(h.P(s.name,"Shockwave Flash"))q=h.z(s.description,"Shockwave Flash ")[1]}else{n=n+"."+n;try{f=new ActiveXObject(n+".7");q=f.GetVariable(w)}catch(g){}if(!q)try{f=
+new ActiveXObject(n+".6");q="WIN 6,0,21,0";f.AllowScriptAccess="always";q=f.GetVariable(w)}catch(z){}if(!q)try{f=new ActiveXObject(n);q=f.GetVariable(w)}catch(z){}if(q){q=h.z(h.z(q," ")[1],",");q=q[0]+"."+q[1]+" r"+q[2]}}return q?q:c}a.xc=function(){var l;if(self.screen){a.Ka=a.Ja.width+"x"+a.Ja.height;a.Sb=a.Ja.colorDepth+"-bit"}else if(a.qb)try{l=a.qb.getScreenSize();a.Ka=l.width+"x"+l.height}catch(s){}a.Ob=h.T(a.k&&a.k.language?a.k.language:(a.k&&a.k.browserLanguage?a.k.browserLanguage:c));a.Mb=
+a.k&&a.k.javaEnabled()?1:0;a.Bb=o?k():c;a.tb=h.d(a.a.characterSet?a.a.characterSet:(a.a.charset?a.a.charset:c))};a.Xc=function(){return"&"+["utmcs="+h.d(a.tb),"utmsr="+a.Ka,"utmsc="+a.Sb,"utmul="+a.Ob,"utmje="+a.Mb,"utmfl="+h.d(a.Bb)].join("&")}};_gat.n=function(d,a,c,h,o){var k=this,l=_gat,s=l.q,q=l.b,f=l.P,n=l.C,w=l.T,x=l.z,g=l.c;k.a=a;k.f=d;k.Rb=c;k.ja=h;k.o=o;function z(p){return s(p)||"0"==p||!f(p,"://")}function B(p){var u="";p=w(x(p,"://")[1]);if(f(p,"/")){p=x(p,"/")[1];if(f(p,"?"))u=x(p,"?")[0]}return u}function A(p){var u="";u=w(x(p,"://")[1]);if(f(u,"/"))u=x(u,"/")[0];return u}k.Fc=function(p){var u=k.Fb(),m=k.o;return new l.n.s(n(p,m.fb+"=","&"),n(p,m.ib+"=","&"),n(p,m.kb+"=","&"),k.ba(p,m.db,"(not set)"),k.ba(p,m.gb,"(not set)"),
+k.ba(p,m.jb,u&&!s(u.R)?l.J(u.R):q),k.ba(p,m.eb,q))};k.Ib=function(p){var u=A(p),m=B(p);if(f(u,k.o.ab)){p=x(p,"?").join("&");if(f(p,"&"+k.o.Gb+"="))if(m==k.o.Ic)return true}return false};k.Fb=function(){var p,u,m=k.Rb,r,i,b=k.o.fa;if(z(m)||k.Ib(m))return;p=A(m);for(r=0;r<b[g];r++){i=b[r];if(f(p,w(i.zb))){m=x(m,"?").join("&");if(f(m,"&"+i.Nb+"=")){u=x(m,"&"+i.Nb+"=")[1];if(f(u,"&"))u=x(u,"&")[0];return new l.n.s(q,i.zb,q,"(organic)","organic",u,q)}}}};k.ba=function(p,u,m){var r=n(p,u+"=","&"),i=!s(r)?
+l.J(r):(!s(m)?m:"-");return i};k.Nc=function(p){var u=k.o.ea,m=false,r,i;if(p&&"organic"==p.da){r=w(l.J(p.R));for(i=0;i<u[g];i++)m=m||w(u[i])==r}return m};k.Ec=function(){var p="",u="",m=k.Rb;if(z(m)||k.Ib(m))return;p=w(x(m,"://")[1]);if(f(p,"/")){u=l.F(p,l.w(p,"/"));if(f(u,"?"))u=x(u,"?")[0];p=x(p,"/")[0]}if(0==l.w(p,"www."))p=l.F(p,4);return new l.n.s(q,p,q,"(referral)","referral",q,u)};k.sc=function(p){var u="";if(k.o.pa){u=l.Db(p);u=""!=u?u+"&":u}u+=p.search;return u};k.zc=function(){return new l.n.s(q,
+"(direct)",q,"(direct)","(none)",q,q)};k.Oc=function(p){var u=false,m,r,i=k.o.ga;if(p&&"referral"==p.da){m=w(l.d(p.ia));for(r=0;r<i[g];r++)u=u||f(m,w(i[r]))}return u};k.U=function(p){return q!=p&&p.Fa()};k.yc=function(p,u){var m="",r="-",i,b,e=0,j,t,v=k.f;if(!p)return"";t=k.a[l.m]?k.a[l.m]:"";m=k.sc(k.a.location);if(k.o.I&&p.Jb()){r=p.Ca();if(!s(r)&&!f(r,";")){p.Ra();return""}}r=n(t,l.X+v+".",";");i=k.Fc(m);if(k.U(i)){b=n(m,k.o.hb+"=","&");if("1"==b&&!s(r))return""}if(!k.U(i)){i=k.Fb();if(!s(r)&&
+k.Nc(i))return""}if(!k.U(i)&&u){i=k.Ec();if(!s(r)&&k.Oc(i))return""}if(!k.U(i))if(s(r)&&u)i=k.zc();if(!k.U(i))return"";if(!s(r)){var y=x(r,"."),E=new l.n.s;E.Cb(y.slice(4).join("."));j=w(E.ka())==w(i.ka());e=y[3]*1}if(!j||u){var F=n(t,l.r+v+".",";"),I=F.lastIndexOf("."),G=I>9?l.F(F,I+1)*1:0;e++;G=0==G?1:G;p.Xb([v,k.ja,G,e,i.ka()].join("."));p.Ra();return"&utmcn=1"}else return"&utmcr=1"}};_gat.n.s=function(d,a,c,h,o,k,l){var s=this;s.v=d;s.ia=a;s.ra=c;s.L=h;s.da=o;s.R=k;s.vb=l};_gat.n.s.prototype.ka=
+function(){var d=this,a=_gat,c=[],h=[[a.Wa,d.v],[a.Ya,d.ia],[a.$a,d.ra],[a.Ua,d.L],[a.Xa,d.da],[a.Za,d.R],[a.Va,d.vb]],o,k;if(d.Fa())for(o=0;o<h[a.c];o++)if(!a.q(h[o][1])){k=h[o][1].split("+").join("%20");k=k.split(" ").join("%20");a.h(c,h[o][0]+k)}return c.join("|")};_gat.n.s.prototype.Fa=function(){var d=this,a=_gat.q;return!(a(d.v)&&a(d.ia)&&a(d.ra))};_gat.n.s.prototype.Cb=function(d){var a=this,c=_gat,h=function(o){return c.J(c.C(d,o,"|"))};a.v=h(c.Wa);a.ia=h(c.Ya);a.ra=h(c.$a);a.L=h(c.Ua);a.da=
+h(c.Xa);a.R=h(c.Za);a.vb=h(c.Va)};_gat.Z=function(){var d=this,a=_gat,c={},h="k",o="v",k=[h,o],l="(",s=")",q="*",f="!",n="'",w={};w[n]="'0";w[s]="'1";w[q]="'2";w[f]="'3";var x=1;function g(m,r,i,b){if(a.b==c[m])c[m]={};if(a.b==c[m][r])c[m][r]=[];c[m][r][i]=b}function z(m,r,i){return a.b!=c[m]&&a.b!=c[m][r]?c[m][r][i]:a.b}function B(m,r){if(a.b!=c[m]&&a.b!=c[m][r]){c[m][r]=a.b;var i=true,b;for(b=0;b<k[a.c];b++)if(a.b!=c[m][k[b]]){i=false;break}if(i)c[m]=a.b}}function A(m){var r="",i=false,b,e;for(b=0;b<k[a.c];b++){e=m[k[b]];if(a.b!=
+e){if(i)r+=k[b];r+=p(e);i=false}else i=true}return r}function p(m){var r=[],i,b;for(b=0;b<m[a.c];b++)if(a.b!=m[b]){i="";if(b!=x&&a.b==m[b-1]){i+=b.toString();i+=f}i+=u(m[b]);a.h(r,i)}return l+r.join(q)+s}function u(m){var r="",i,b,e;for(i=0;i<m[a.c];i++){b=m.charAt(i);e=w[b];r+=a.b!=e?e:b}return r}d.Kc=function(m){return a.b!=c[m]};d.N=function(){var m=[],r;for(r in c)if(a.b!=c[r])a.h(m,r.toString()+A(c[r]));return m.join("")};d.Sc=function(m){if(m==a.b)return d.N();var r=[m.N()],i;for(i in c)if(a.b!=
+c[i]&&!m.Kc(i))a.h(r,i.toString()+A(c[i]));return r.join("")};d._setKey=function(m,r,i){if(typeof i!="string")return false;g(m,h,r,i);return true};d._setValue=function(m,r,i){if(typeof i!="number"&&(a.b==Number||!(i instanceof Number)))return false;if(Math.round(i)!=i||i==NaN||i==Infinity)return false;g(m,o,r,i.toString());return true};d._getKey=function(m,r){return z(m,h,r)};d._getValue=function(m,r){return z(m,o,r)};d._clearKey=function(m){B(m,h)};d._clearValue=function(m){B(m,o)}};_gat.ic=function(d,a){var c=this;c.jd=a;c.Pc=d;c._trackEvent=function(h,o,k){return a._trackEvent(c.Pc,h,o,k)}};_gat.kc=function(d){var a=this,c=_gat,h=c.b,o=c.q,k=c.w,l=c.F,s=c.C,q=c.P,f=c.z,n="location",w=c.c,x=h,g=new c.hc,z=false;a.a=document;a.e=window;a.ja=Math.round((new Date).getTime()/1000);a.H=d;a.yb=a.a.referrer;a.va=h;a.j=h;a.A=h;a.M=false;a.aa=h;a.rb="";a.l=h;a.Ab=h;a.f=h;a.u=h;function B(){if("auto"==g.g){var b=a.a.domain;if("www."==l(b,0,4))b=l(b,4);g.g=b}g.g=c.T(g.g)}function A(){var b=g.g,e=k(b,"www.google.")*k(b,".google.")*k(b,"google.");return e||"/"!=g.p||k(b,"google.org")>-1}function p(b,
+e,j){if(o(b)||o(e)||o(j))return"-";var t=s(b,c.r+a.f+".",e),v;if(!o(t)){v=f(t,".");v[5]=v[5]?v[5]*1+1:1;v[3]=v[4];v[4]=j;t=v.join(".")}return t}function u(){return"file:"!=a.a[n].protocol&&A()}function m(b){if(!b||""==b)return"";while(c.Lb(b.charAt(0)))b=l(b,1);while(c.Lb(b.charAt(b[w]-1)))b=l(b,0,b[w]-1);return b}function r(b,e,j){if(!o(b())){e(c.J(b()));if(!q(b(),";"))j()}}function i(b){var e,j=""!=b&&a.a[n].host!=b;if(j)for(e=0;e<g.B[w];e++)j=j&&k(c.T(b),c.T(g.B[e]))==-1;return j}a.Bc=function(){if(!g.g||
+""==g.g||"none"==g.g){g.g="";return 1}B();return g.pb?c.t(g.g):1};a.tc=function(b,e){if(o(b))b="-";else{e+=g.p&&"/"!=g.p?g.p:"";var j=k(b,e);b=j>=0&&j<=8?"0":("["==b.charAt(0)&&"]"==b.charAt(b[w]-1)?"-":b)}return b};a.Ia=function(b){var e="",j=a.a;e+=a.aa?a.aa.Xc():"";e+=g.qa?a.rb:"";e+=g.ta&&!o(j.title)?"&utmdt="+c.d(j.title):"";e+="&utmhid="+c.uc()+"&utmr="+a.va+"&utmp="+a.Tc(b);return e};a.Tc=function(b){var e=a.a[n];b=h!=b&&""!=b?c.d(b,true):c.d(e.pathname+unescape(e.search),true);return b};a.$c=
+function(b){if(a.Q()){var e="";if(a.l!=h&&a.l.N().length>0)e+="&utme="+c.d(a.l.N());e+=a.Ia(b);x.O(e,a.H,a.a,a.f)}};a.qc=function(){var b=new c.Y(a.a,g);return b.Ha(a.f)?b.Wc():h};a._getLinkerUrl=function(b,e){var j=f(b,"#"),t=b,v=a.qc();if(v)if(e&&1>=j[w])t+="#"+v;else if(!e||1>=j[w])if(1>=j[w])t+=(q(b,"?")?"&":"?")+v;else t=j[0]+(q(b,"?")?"&":"?")+v+"#"+j[1];return t};a.Zb=function(){var b;if(a.A&&a.A[w]>=10&&!q(a.A,"=")){a.u.Uc(a.A);a.u.cd();c._gasoDomain=g.g;c._gasoCPath=g.p;b=a.a.createElement("script");
+b.type="text/javascript";b.id="_gasojs";b.src="https://www.google.com/analytics/reporting/overlay_js?gaso="+a.A+"&"+c.wa();a.a.getElementsByTagName("head")[0].appendChild(b)}};a.Jc=function(){var b=a.a[c.m],e=a.ja,j=a.u,t=a.f+"",v=a.e,y=v?v.gaGlobal:h,E,F=q(b,c.r+t+"."),I=q(b,c.W+t),G=q(b,c.ma+t),C,D=[],H="",K=false,J;b=o(b)?"":b;if(g.I){E=c.Db(a.a[n]);if(g.pa&&!o(E))H=E+"&";H+=a.a[n].search;if(!o(H)&&q(H,c.r)){j.Rc(H);if(!j.Jb())j.pc();C=j.ya()}r(j.Ba,j.Wb,j.fc);r(j.Aa,j.Na,j.Qa)}if(!o(C))if(o(j.K())||
+o(j.za())){C=p(H,"&",e);a.M=true}else{D=f(j.K(),".");t=D[0]}else if(F)if(!I||!G){C=p(b,";",e);a.M=true}else{C=s(b,c.r+t+".",";");D=f(s(b,c.W+t,";"),".")}else{C=[t,c.Gc(),e,e,e,1].join(".");a.M=true;K=true}C=f(C,".");if(v&&y&&y.dh==t){C[4]=y.sid?y.sid:C[4];if(K){C[3]=y.sid?y.sid:C[4];if(y.vid){J=f(y.vid,".");C[1]=J[0];C[2]=J[1]}}}j.Ub(C.join("."));D[0]=t;D[1]=D[1]?D[1]:0;D[2]=undefined!=D[2]?D[2]:g.Yc;D[3]=D[3]?D[3]:C[4];j.La(D.join("."));j.Vb(t);if(!o(j.Hc()))j.Ma(j.t());j.dc();j.Pa();j.ec()};a.Lc=
+function(){x=new c.jc(g)};a._initData=function(){var b;if(!z){a.Lc();a.f=a.Bc();a.u=new c.Y(a.a,g)}if(u())a.Jc();if(!z){if(u()){a.va=a.tc(a.Ac(),a.a.domain);if(g.sa){a.aa=new c.gc(g.ua);a.aa.xc()}if(g.qa){b=new c.n(a.f,a.a,a.va,a.ja,g);a.rb=b.yc(a.u,a.M)}}a.l=new c.Z;a.Ab=new c.Z;z=true}if(!c.Hb)a.Mc()};a._visitCode=function(){a._initData();var b=s(a.a[c.m],c.r+a.f+".",";"),e=f(b,".");return e[w]<4?"":e[1]};a._cookiePathCopy=function(b){a._initData();if(a.u)a.u.bd(a.f,b)};a.Mc=function(){var b=a.a[n].hash,
+e;e=b&&""!=b&&0==k(b,"#gaso=")?s(b,"gaso=","&"):s(a.a[c.m],c.Sa,";");if(e[w]>=10){a.A=e;if(a.e.addEventListener)a.e.addEventListener("load",a.Zb,false);else a.e.attachEvent("onload",a.Zb)}c.Hb=true};a.Q=function(){return a._visitCode()%10000<g.ha*100};a.Vc=function(){var b,e,j=a.a.links;if(!g.Kb){var t=a.a.domain;if("www."==l(t,0,4))t=l(t,4);g.B.push("."+t)}for(b=0;b<j[w]&&(g.Ga==-1||b<g.Ga);b++){e=j[b];if(i(e.host))if(!e.gatcOnclick){e.gatcOnclick=e.onclick?e.onclick:a.Qc;e.onclick=function(v){var y=
+!this.target||this.target=="_self"||this.target=="_top"||this.target=="_parent";y=y&&!a.oc(v);a.ad(v,this,y);return y?false:(this.gatcOnclick?this.gatcOnclick(v):true)}}}};a.Qc=function(){};a._trackPageview=function(b){if(u()){a._initData();if(g.B)a.Vc();a.$c(b);a.M=false}};a._trackTrans=function(){var b=a.f,e=[],j,t,v,y;a._initData();if(a.j&&a.Q()){for(j=0;j<a.j.la[w];j++){t=a.j.la[j];c.h(e,t.S());for(v=0;v<t.ca[w];v++)c.h(e,t.ca[v].S())}for(y=0;y<e[w];y++)x.O(e[y],a.H,a.a,b,true)}};a._setTrans=
+function(){var b=a.a,e,j,t,v,y=b.getElementById?b.getElementById("utmtrans"):(b.utmform&&b.utmform.utmtrans?b.utmform.utmtrans:h);a._initData();if(y&&y.value){a.j=new c.i;v=f(y.value,"UTM:");g.G=!g.G||""==g.G?"|":g.G;for(e=0;e<v[w];e++){v[e]=m(v[e]);j=f(v[e],g.G);for(t=0;t<j[w];t++)j[t]=m(j[t]);if("T"==j[0])a._addTrans(j[1],j[2],j[3],j[4],j[5],j[6],j[7],j[8]);else if("I"==j[0])a._addItem(j[1],j[2],j[3],j[4],j[5],j[6])}}};a._addTrans=function(b,e,j,t,v,y,E,F){a.j=a.j?a.j:new c.i;return a.j.nb(b,e,
+j,t,v,y,E,F)};a._addItem=function(b,e,j,t,v,y){var E;a.j=a.j?a.j:new c.i;E=a.j.xa(b);if(!E)E=a._addTrans(b,"","","","","","","");E.mb(e,j,t,v,y)};a._setVar=function(b){if(b&&""!=b&&A()){a._initData();var e=new c.Y(a.a,g),j=a.f;e.Na(j+"."+c.d(b));e.Qa();if(a.Q())x.O("&utmt=var",a.H,a.a,a.f)}};a._link=function(b,e){if(g.I&&b){a._initData();a.a[n].href=a._getLinkerUrl(b,e)}};a._linkByPost=function(b,e){if(g.I&&b&&b.action){a._initData();b.action=a._getLinkerUrl(b.action,e)}};a._setXKey=function(b,e,
+j){a.l._setKey(b,e,j)};a._setXValue=function(b,e,j){a.l._setValue(b,e,j)};a._getXKey=function(b,e){return a.l._getKey(b,e)};a._getXValue=function(b,e){return a.l.getValue(b,e)};a._clearXKey=function(b){a.l._clearKey(b)};a._clearXValue=function(b){a.l._clearValue(b)};a._createXObj=function(){a._initData();return new c.Z};a._sendXEvent=function(b){var e="";a._initData();if(a.Q()){e+="&utmt=event&utme="+c.d(a.l.Sc(b))+a.Ia();x.O(e,a.H,a.a,a.f,false,true)}};a._createEventTracker=function(b){a._initData();
+return new c.ic(b,a)};a._trackEvent=function(b,e,j,t){var v=true,y=a.Ab;if(h!=b&&h!=e&&""!=b&&""!=e){y._clearKey(5);y._clearValue(5);v=y._setKey(5,1,b)?v:false;v=y._setKey(5,2,e)?v:false;v=h==j||y._setKey(5,3,j)?v:false;v=h==t||y._setValue(5,1,t)?v:false;if(v)a._sendXEvent(y)}else v=false;return v};a.ad=function(b,e,j){a._initData();if(a.Q()){var t=new c.Z;t._setKey(6,1,e.href);var v=j?function(){a.rc(b,e)}:undefined;x.O("&utmt=event&utme="+c.d(t.N())+a.Ia(),a.H,a.a,a.f,false,true,v)}};a.rc=function(b,
+e){if(!b)b=a.e.event;var j=true;if(e.gatcOnclick)j=e.gatcOnclick(b);if(j||typeof j=="undefined")if(!e.target||e.target=="_self")a.e.location=e.href;else if(e.target=="_top")a.e.top.document.location=e.href;else if(e.target=="_parent")a.e.parent.document.location=e.href};a.oc=function(b){if(!b)b=a.e.event;var e=b.shiftKey||b.ctrlKey||b.altKey;if(!e)if(b.modifiers&&a.e.Event)e=b.modifiers&a.e.Event.CONTROL_MASK||b.modifiers&a.e.Event.SHIFT_MASK||b.modifiers&a.e.Event.ALT_MASK;return e};a._setDomainName=
+function(b){g.g=b};a.dd=function(){return g.g};a._addOrganic=function(b,e){c.h(g.fa,new c.cb(b,e))};a._clearOrganic=function(){g.fa=[]};a.hd=function(){return g.fa};a._addIgnoredOrganic=function(b){c.h(g.ea,b)};a._clearIgnoredOrganic=function(){g.ea=[]};a.ed=function(){return g.ea};a._addIgnoredRef=function(b){c.h(g.ga,b)};a._clearIgnoredRef=function(){g.ga=[]};a.fd=function(){return g.ga};a._setAllowHash=function(b){g.pb=b?1:0};a._setCampaignTrack=function(b){g.qa=b?1:0};a._setClientInfo=function(b){g.sa=
+b?1:0};a._getClientInfo=function(){return g.sa};a._setCookiePath=function(b){g.p=b};a._setTransactionDelim=function(b){g.G=b};a._setCookieTimeout=function(b){g.wb=b};a._setDetectFlash=function(b){g.ua=b?1:0};a._getDetectFlash=function(){return g.ua};a._setDetectTitle=function(b){g.ta=b?1:0};a._getDetectTitle=function(){return g.ta};a._setLocalGifPath=function(b){g.Da=b};a._getLocalGifPath=function(){return g.Da};a._setLocalServerMode=function(){g.D=0};a._setRemoteServerMode=function(){g.D=1};a._setLocalRemoteServerMode=
+function(){g.D=2};a.gd=function(){return g.D};a._getServiceMode=function(){return g.D};a._setSampleRate=function(b){g.ha=b};a._setSessionTimeout=function(b){g.Tb=b};a._setAllowLinker=function(b){g.I=b?1:0};a._setAllowAnchor=function(b){g.pa=b?1:0};a._setCampNameKey=function(b){g.db=b};a._setCampContentKey=function(b){g.eb=b};a._setCampIdKey=function(b){g.fb=b};a._setCampMediumKey=function(b){g.gb=b};a._setCampNOKey=function(b){g.hb=b};a._setCampSourceKey=function(b){g.ib=b};a._setCampTermKey=function(b){g.jb=
+b};a._setCampCIdKey=function(b){g.kb=b};a._getAccount=function(){return a.H};a._getVersion=function(){return _gat.lb};a.kd=function(b){g.B=[];if(b)g.B=b};a.md=function(b){g.Kb=b};a.ld=function(b){g.Ga=b};a._setReferrerOverride=function(b){a.yb=b};a.Ac=function(){return a.yb}};_gat._getTracker=function(d){var a=new _gat.kc(d);return a};
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/header.png b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/header.png
new file mode 100644
index 0000000..977712b
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/header.png
Binary files differ
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/hoverIntent.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/hoverIntent.js
new file mode 100644
index 0000000..91da57b
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/hoverIntent.js
@@ -0,0 +1,84 @@
+(function($){
+	/* hoverIntent by Brian Cherne */
+	$.fn.hoverIntent = function(f,g) {
+		// default configuration options
+		var cfg = {
+			sensitivity: 7,
+			interval: 100,
+			timeout: 0
+		};
+		// override configuration options with user supplied object
+		cfg = $.extend(cfg, g ? { over: f, out: g } : f );
+
+		// instantiate variables
+		// cX, cY = current X and Y position of mouse, updated by mousemove event
+		// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
+		var cX, cY, pX, pY;
+
+		// A private function for getting mouse position
+		var track = function(ev) {
+			cX = ev.pageX;
+			cY = ev.pageY;
+		};
+
+		// A private function for comparing current and previous mouse position
+		var compare = function(ev,ob) {
+			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
+			// compare mouse positions to see if they've crossed the threshold
+			if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
+				$(ob).unbind("mousemove",track);
+				// set hoverIntent state to true (so mouseOut can be called)
+				ob.hoverIntent_s = 1;
+				return cfg.over.apply(ob,[ev]);
+			} else {
+				// set previous coordinates for next time
+				pX = cX; pY = cY;
+				// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
+				ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
+			}
+		};
+
+		// A private function for delaying the mouseOut function
+		var delay = function(ev,ob) {
+			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
+			ob.hoverIntent_s = 0;
+			return cfg.out.apply(ob,[ev]);
+		};
+
+		// A private function for handling mouse 'hovering'
+		var handleHover = function(e) {
+			// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
+			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
+			while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
+			if ( p == this ) { return false; }
+
+			// copy objects to be passed into t (required for event object to be passed in IE)
+			var ev = jQuery.extend({},e);
+			var ob = this;
+
+			// cancel hoverIntent timer if it exists
+			if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
+
+			// else e.type == "onmouseover"
+			if (e.type == "mouseover") {
+				// set "previous" X and Y position based on initial entry point
+				pX = ev.pageX; pY = ev.pageY;
+				// update "current" X and Y position based on mousemove
+				$(ob).bind("mousemove",track);
+				// start polling interval (self-calling timeout) to compare mouse coordinates over time
+				if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
+
+			// else e.type == "onmouseout"
+			} else {
+				// unbind expensive mousemove event
+				$(ob).unbind("mousemove",track);
+				// if hoverIntent state is true, then call the mouseOut function after the specified delay
+				if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
+			}
+		};
+
+		// bind the function to the two event listeners
+		return this.mouseover(handleHover).mouseout(handleHover);
+	};
+	
+})(jQuery);
\ No newline at end of file
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/information.gif b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/information.gif
new file mode 100644
index 0000000..072ab66
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/information.gif
Binary files differ
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/ipojo.png b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/ipojo.png
new file mode 100644
index 0000000..8f8d89e
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/ipojo.png
Binary files differ
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/jquery-1.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/jquery-1.js
new file mode 100644
index 0000000..b1ae21d
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/jquery-1.js
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML='   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();
\ No newline at end of file
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/linkext7.gif b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/linkext7.gif
new file mode 100644
index 0000000..f2dd2dc
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/linkext7.gif
Binary files differ
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/logo.png b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/logo.png
new file mode 100644
index 0000000..dccbddc
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/logo.png
Binary files differ
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushCSharp.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushCSharp.js
new file mode 100644
index 0000000..f45540f
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushCSharp.js
@@ -0,0 +1,30 @@
+dp.sh.Brushes.CSharp = function()
+{
+	var keywords =	'abstract as base bool break byte case catch char checked class const ' +
+					'continue decimal default delegate do double else enum event explicit ' +
+					'extern false finally fixed float for foreach get goto if implicit in int ' +
+					'interface internal is lock long namespace new null object operator out ' +
+					'override params private protected public readonly ref return sbyte sealed set ' +
+					'short sizeof stackalloc static string struct switch this throw true try ' +
+					'typeof uint ulong unchecked unsafe ushort using virtual void while';
+
+	this.regexList = [
+		// There's a slight problem with matching single line comments and figuring out
+		// a difference between // and ///. Using lookahead and lookbehind solves the
+		// problem, unfortunately JavaScript doesn't support lookbehind. So I'm at a 
+		// loss how to translate that regular expression to JavaScript compatible one.
+//		{ regex: new RegExp('(?<!/)//(?!/).*$|(?<!/)////(?!/).*$|/\\*[^\\*]*(.)*?\\*/', 'gm'),	css: 'comment' },			// one line comments starting with anything BUT '///' and multiline comments
+//		{ regex: new RegExp('(?<!/)///(?!/).*$', 'gm'),											css: 'comments' },		// XML comments starting with ///
+
+		{ regex: new RegExp('//.*$', 'gm'),							css: 'comment' },			// one line comments
+		{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'),				css: 'comment' },			// multiline comments
+		{ regex: new RegExp('"(?:\\.|[^\\""])*"', 'g'),				css: 'string' },			// strings
+		{ regex: new RegExp('^\\s*#.*', 'gm'),						css: 'preprocessor' },		// preprocessor tags like #region and #endregion
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// c# keyword
+		];
+
+	this.CssClass = 'dp-c';
+}
+
+dp.sh.Brushes.CSharp.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.CSharp.Aliases	= ['c#', 'c-sharp', 'csharp'];
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushDelphi.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushDelphi.js
new file mode 100644
index 0000000..efeb2f7
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushDelphi.js
@@ -0,0 +1,31 @@
+/* Delphi brush is contributed by Eddie Shipman */
+dp.sh.Brushes.Delphi = function()
+{
+	var keywords =	'abs addr and ansichar ansistring array as asm begin boolean byte cardinal ' +
+					'case char class comp const constructor currency destructor div do double ' +
+					'downto else end except exports extended false file finalization finally ' +
+					'for function goto if implementation in inherited int64 initialization ' +
+					'integer interface is label library longint longword mod nil not object ' +
+					'of on or packed pansichar pansistring pchar pcurrency pdatetime pextended ' + 
+					'pint64 pointer private procedure program property pshortstring pstring ' + 
+					'pvariant pwidechar pwidestring protected public published raise real real48 ' +
+					'record repeat set shl shortint shortstring shr single smallint string then ' +
+					'threadvar to true try type unit until uses val var varirnt while widechar ' +
+					'widestring with word write writeln xor';
+
+	this.regexList = [
+		{ regex: new RegExp('\\(\\*[\\s\\S]*?\\*\\)', 'gm'),		css: 'comment' },  			// multiline comments (* *)
+		{ regex: new RegExp('{(?!\\$)[\\s\\S]*?}', 'gm'),			css: 'comment' },  			// multiline comments { }
+		{ regex: new RegExp('//.*$', 'gm'),							css: 'comment' },  			// one line
+		{ regex: new RegExp('\'(?:\\.|[^\\\'\'])*\'', 'g'),			css: 'string' },			// strings
+		{ regex: new RegExp('\\{\\$[a-zA-Z]+ .+\\}', 'g'),			css: 'directive' },			// Compiler Directives and Region tags
+		{ regex: new RegExp('\\b[\\d\\.]+\\b', 'g'),				css: 'number' },			// numbers 12345
+		{ regex: new RegExp('\\$[a-zA-Z0-9]+\\b', 'g'),				css: 'number' },			// numbers $F5D3
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// keyword
+		];
+
+	this.CssClass = 'dp-delphi';
+}
+
+dp.sh.Brushes.Delphi.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Delphi.Aliases	= ['delphi', 'pascal'];
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushJScript.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushJScript.js
new file mode 100644
index 0000000..4ef8b9b
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushJScript.js
@@ -0,0 +1,22 @@
+dp.sh.Brushes.JScript = function()
+{
+	var keywords =	'abstract boolean break byte case catch char class const continue debugger ' +
+					'default delete do double else enum export extends false final finally float ' +
+					'for function goto if implements import in instanceof int interface long native ' +
+					'new null package private protected public return short static super switch ' +
+					'synchronized this throw throws transient true try typeof var void volatile while with';
+
+	this.regexList = [
+		{ regex: new RegExp('//.*$', 'gm'),							css: 'comment' },			// one line comments
+		{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'),				css: 'comment' },			// multiline comments
+		{ regex: new RegExp('"(?:[^"\n]|[\"])*?"', 'g'),			css: 'string' },			// double quoted strings
+		{ regex: new RegExp("'(?:[^'\n]|[\'])*?'", 'g'),			css: 'string' },			// single quoted strings
+		{ regex: new RegExp('^\\s*#.*', 'gm'),						css: 'preprocessor' },		// preprocessor tags like #region and #endregion
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// keywords
+		];
+
+	this.CssClass = 'dp-c';
+}
+
+dp.sh.Brushes.JScript.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.JScript.Aliases	= ['js', 'jscript', 'javascript'];
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushJava.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushJava.js
new file mode 100644
index 0000000..b75d334
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushJava.js
@@ -0,0 +1,22 @@
+dp.sh.Brushes.Java = function()
+{
+	var keywords =	'abstract assert boolean break byte case catch char class const' +
+                    'continue default do double else enum extends false final finally float' +
+                    'for goto if implements import instanceof inst interface log native' +
+                    'new null package private protected public return short static strictfp super' +
+                    'switch synchronized this throw throws transient true try void volatile while';
+
+    this.regexList = [
+		{ regex: new RegExp('//.*$', 'gm'),							css: 'comment' },			// one line comments
+		{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'),				css: 'comment' },			// multiline comments
+		{ regex: new RegExp('"(?:[^"\n]|[\"])*?"', 'g'),			css: 'string' },			// double quoted strings
+		{ regex: new RegExp("'(?:[^'\n]|[\'])*?'", 'g'),			css: 'string' },			// single quoted strings
+		{ regex: new RegExp('^\\s*@.*', 'gm'),						css: 'preprocessor' },		// preprocessor tags like @see
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// keywords
+		];
+
+	this.CssClass = 'dp-c';
+}
+
+dp.sh.Brushes.Java.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Java.Aliases	    = ['java'];
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushPhp.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushPhp.js
new file mode 100644
index 0000000..57c85d4
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushPhp.js
@@ -0,0 +1,23 @@
+dp.sh.Brushes.Php = function()
+{
+	var keywords =	'and or xor __FILE__ __LINE__ array as break case ' +
+					'cfunction class const continue declare default die do echo else ' +
+					'elseif empty enddeclare endfor endforeach endif endswitch endwhile eval exit ' +
+					'extends for foreach function global if include include_once isset list ' +
+					'new old_function print require require_once return static switch unset use ' +
+					'var while __FUNCTION__ __CLASS__';
+
+	this.regexList = [
+		{ regex: new RegExp('//.*$', 'gm'),							css: 'comment' },			// one line comments
+		{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'),				css: 'comment' },			// multiline comments
+		{ regex: new RegExp('"(?:[^"\n]|[\"])*?"', 'g'),			css: 'string' },			// double quoted strings
+		{ regex: new RegExp("'(?:[^'\n]|[\'])*?'", 'g'),			css: 'string' },			// single quoted strings
+		{ regex: new RegExp('\\$\\w+', 'g'),						css: 'vars' },				// variables
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// keyword
+		];
+
+	this.CssClass = 'dp-c';
+}
+
+dp.sh.Brushes.Php.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Php.Aliases	= ['php'];
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushPython.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushPython.js
new file mode 100644
index 0000000..1d61339
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushPython.js
@@ -0,0 +1,71 @@
+/* Python 2.3 syntax contributed by Gheorghe Milas */
+dp.sh.Brushes.Python = function()
+{
+	var keywords =		'and assert break class continue def del elif else except exec ' +
+						'finally for from global if import in is lambda not or object pass print ' +
+						'raise return try yield while';
+	
+	var builtins =		'self __builtin__ __dict__ __future__ __methods__ __members__ __author__ __email__ __version__' +
+						'__class__ __bases__ __import__ __main__ __name__ __doc__ __self__ __debug__ __slots__ ' +
+						'abs append apply basestring bool buffer callable chr classmethod clear close cmp coerce compile complex ' +
+						'conjugate copy count delattr dict dir divmod enumerate Ellipsis eval execfile extend False file fileno filter float flush ' +
+						'get getattr globals has_key hasarttr hash hex id index input insert int intern isatty isinstance isubclass ' +
+						'items iter keys len list locals long map max min mode oct open ord pop pow property range ' +
+						'raw_input read readline readlines reduce reload remove repr reverse round seek setattr slice sum ' +
+						'staticmethod str super tell True truncate tuple type unichr unicode update values write writelines xrange zip';
+	
+	var magicmethods =	'__abs__ __add__ __and__ __call__ __cmp__ __coerce__ __complex__ __concat__ __contains__ __del__ __delattr__ __delitem__ ' +
+						'__delslice__ __div__ __divmod__ __float__ __getattr__ __getitem__ __getslice__ __hash__ __hex__ __eq__ __le__ __lt__ __gt__ __ge__ ' +
+						'__iadd__ __isub__ __imod__ __idiv__ __ipow__ __iand__ __ior__ __ixor__ __ilshift__ __irshift__ ' +
+						'__invert__ __init__ __int__ __inv__ __iter__ __len__ __long__ __lshift__ __mod__ __mul__ __new__ __neg__ __nonzero__ __oct__ __or__ ' +
+						'__pos__ __pow__ __radd__ __rand__ __rcmp__ __rdiv__ __rdivmod__ __repeat__ __repr__ __rlshift__ __rmod__ __rmul__ ' +
+						'__ror__ __rpow__ __rrshift__ __rshift__ __rsub__ __rxor__ __setattr__ __setitem__ __setslice__ __str__ __sub__ __xor__';
+	
+	var exceptions =	'Exception StandardError ArithmeticError LookupError EnvironmentError AssertionError AttributeError EOFError ' +
+						'FutureWarning IndentationError OverflowWarning PendingDeprecationWarning ReferenceError RuntimeWarning ' +
+						'SyntaxWarning TabError UnicodeDecodeError UnicodeEncodeError UnicodeTranslateError UserWarning Warning ' +
+						'IOError ImportError IndexError KeyError KeyboardInterrupt MemoryError NameError NotImplementedError OSError ' +
+						'RuntimeError StopIteration SyntaxError SystemError SystemExit TypeError UnboundLocalError UnicodeError ValueError ' +
+						'FloatingPointError OverflowError WindowsError ZeroDivisionError';
+	
+	var types =			'NoneType TypeType IntType LongType FloatType ComplexType StringType UnicodeType BufferType TupleType ListType ' +
+						'DictType FunctionType LambdaType CodeType ClassType UnboundMethodType InstanceType MethodType BuiltinFunctionType BuiltinMethodType ' +
+						'ModuleType FileType XRangeType TracebackType FrameType SliceType EllipsisType';
+	
+	var commonlibs =	'anydbm array asynchat asyncore AST base64 binascii binhex bisect bsddb buildtools bz2 ' +
+						'BaseHTTPServer Bastion calendar cgi cmath cmd codecs codeop commands compiler copy copy_reg ' +
+						'cPickle crypt cStringIO csv curses Carbon CGIHTTPServer ConfigParser Cookie datetime dbhash ' +
+						'dbm difflib dircache distutils doctest DocXMLRPCServer email encodings errno exceptions fcntl ' +
+						'filecmp fileinput ftplib gc gdbm getopt getpass glob gopherlib gzip heapq htmlentitydefs ' +
+						'htmllib httplib HTMLParser imageop imaplib imgfile imghdr imp inspect itertools jpeg keyword ' +
+						'linecache locale logging mailbox mailcap marshal math md5 mhlib mimetools mimetypes mimify mmap ' +
+						'mpz multifile mutex MimeWriter netrc new nis nntplib nsremote operator optparse os parser pickle pipes ' +
+						'popen2 poplib posix posixfile pprint preferences profile pstats pwd pydoc pythonprefs quietconsole ' +
+						'quopri Queue random re readline resource rexec rfc822 rgbimg sched select sets sgmllib sha shelve shutil ' +
+						'signal site smtplib socket stat statcache string struct symbol sys syslog SimpleHTTPServer ' +
+						'SimpleXMLRPCServer SocketServer StringIO tabnanny tarfile telnetlib tempfile termios textwrap ' +
+						'thread threading time timeit token tokenize traceback tty types Tkinter unicodedata unittest ' +
+						'urllib urllib2 urlparse user UserDict UserList UserString warnings weakref webbrowser whichdb ' +
+						'xml xmllib xmlrpclib xreadlines zipfile zlib';
+
+	this.regexList = [
+		{ regex: new RegExp('#.*$', 'gm'),								css: 'comment' },			// comments
+		{ regex: new RegExp('^\\s*"""(.|\n)*?"""\\s*$', 'gm'),			css: 'docstring' },			// documentation string "
+		{ regex: new RegExp('^\\s*\'\'\'(.|\n)*?\'\'\'\\s*$', 'gm'),	css: 'docstring' },			// documentation string '
+		{ regex: new RegExp('"""(.|\n)*?"""', 'g'),						css: 'string' },			// multi-line strings "
+		{ regex: new RegExp('\'\'\'(.|\n)*?\'\'\'', 'g'),				css: 'string' },			// multi-line strings '
+		{ regex: new RegExp('"(?:\\.|[^\\""])*"', 'g'),					css: 'string' },			// strings "
+		{ regex: new RegExp('\'(?:\\.|[^\\\'\'])*\'', 'g'),				css: 'string' },			// strings '
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),			css: 'keyword' },			// keywords
+		{ regex: new RegExp(this.GetKeywords(builtins), 'gm'),			css: 'builtins' },			// builtin objects, functions, methods, magic attributes
+		{ regex: new RegExp(this.GetKeywords(magicmethods), 'gm'),		css: 'magicmethods' },		// special methods
+		{ regex: new RegExp(this.GetKeywords(exceptions), 'gm'),		css: 'exceptions' },		// standard exception classes
+		{ regex: new RegExp(this.GetKeywords(types), 'gm'),				css: 'types' },				// types from types.py
+		{ regex: new RegExp(this.GetKeywords(commonlibs), 'gm'),		css: 'commonlibs' }			// common standard library modules
+		];
+
+	this.CssClass = 'dp-py';
+}
+
+dp.sh.Brushes.Python.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Python.Aliases	= ['py', 'python'];
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushShell.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushShell.js
new file mode 100644
index 0000000..5e7c2ef
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushShell.js
@@ -0,0 +1,27 @@
+dp.sh.Brushes.Shell = function()
+{
+	var keywords =	'alias array autor base basename break ' +
+                    'cat catv cd chdir cmpv continue conv copy ' +
+                    'crc ctime cut dirname echo env eval exec else if elif then ' +
+                    'export expr extern false fmode fork fprint ' +
+                    'fsize fstat fullname global goend goto grep ifdef ' +
+                    'ifset ifenv inv kill line link list ' +
+                    'local localset mkdirs mktemp move mtime nop print ' +
+                    'prints pwd read readc readl readonly rel ' +
+                    'remove return seek set shift sleep sortl ' +
+                    'static stime sum system systime tee test times ' +
+                    'tr trap true type typeset tz umask unalias ' +
+                    'unexport unset unsetenv ver wait wc whence ' +
+                    'sane exit prompt let';
+
+
+	this.regexList = [
+		{ regex: new RegExp('#.*$', 'gm'),							css: 'comment' },  			// one line
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// keyword
+		];
+
+	this.CssClass = 'dp-shell';
+}
+
+dp.sh.Brushes.Shell.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Shell.Aliases	= ['shell'];
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushSql.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushSql.js
new file mode 100644
index 0000000..4855d0c
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushSql.js
@@ -0,0 +1,40 @@
+dp.sh.Brushes.Sql = function()
+{
+	var funcs	=	'abs avg case cast coalesce convert count current_timestamp ' +
+					'current_user day isnull left lower month nullif replace right ' +
+					'session_user space substring sum system_user upper user year';
+
+	var keywords =	'absolute action add after alter as asc at authorization begin bigint ' +
+					'binary bit by cascade char character check checkpoint close collate ' +
+					'column commit committed connect connection constraint contains continue ' +
+					'create cube current current_date current_time cursor database date ' +
+					'deallocate dec decimal declare default delete desc distinct double drop ' +
+					'dynamic else end end-exec escape except exec execute false fetch first ' +
+					'float for force foreign forward free from full function global goto grant ' +
+					'group grouping having hour ignore index inner insensitive insert instead ' +
+					'int integer intersect into is isolation key last level load local max min ' +
+					'minute modify move name national nchar next no numeric of off on only ' +
+					'open option order out output partial password precision prepare primary ' +
+					'prior privileges procedure public read real references relative repeatable ' +
+					'restrict return returns revoke rollback rollup rows rule schema scroll ' +
+					'second section select sequence serializable set size smallint static ' +
+					'statistics table temp temporary then time timestamp to top transaction ' +
+					'translation trigger true truncate uncommitted union unique update values ' +
+					'varchar varying view when where with work';
+
+	var operators =	'all and any between cross in join like not null or outer some';
+
+	this.regexList = [
+		{ regex: new RegExp('--(.*)$', 'gm'),						css: 'comment' },			// one line and multiline comments
+		{ regex: new RegExp('"(?:\\.|[^\\""])*"', 'g'),				css: 'string' },			// strings
+		{ regex: new RegExp('\'(?:\\.|[^\\\'\'])*\'', 'g'),			css: 'string' },			// strings
+		{ regex: new RegExp(this.GetKeywords(funcs), 'gmi'),		css: 'func' },				// functions
+		{ regex: new RegExp(this.GetKeywords(operators), 'gmi'),	css: 'op' },				// operators and such
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gmi'),		css: 'keyword' }			// keyword
+		];
+
+	this.CssClass = 'dp-sql';
+}
+
+dp.sh.Brushes.Sql.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Sql.Aliases	= ['sql'];
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushVb.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushVb.js
new file mode 100644
index 0000000..431e16f
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushVb.js
@@ -0,0 +1,29 @@
+dp.sh.Brushes.Vb = function()
+{
+	var keywords =	'AddHandler AddressOf AndAlso Alias And Ansi As Assembly Auto ' +
+					'Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate ' +
+					'CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType ' +
+					'Date Decimal Declare Default Delegate Dim DirectCast Do Double Each ' +
+					'Else ElseIf End Enum Erase Error Event Exit False Finally For Friend ' +
+					'Function Get GetType GoSub GoTo Handles If Implements Imports In ' +
+					'Inherits Integer Interface Is Let Lib Like Long Loop Me Mod Module ' +
+					'MustInherit MustOverride MyBase MyClass Namespace New Next Not Nothing ' +
+					'NotInheritable NotOverridable Object On Option Optional Or OrElse ' +
+					'Overloads Overridable Overrides ParamArray Preserve Private Property ' +
+					'Protected Public RaiseEvent ReadOnly ReDim REM RemoveHandler Resume ' +
+					'Return Select Set Shadows Shared Short Single Static Step Stop String ' +
+					'Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until ' +
+					'Variant When While With WithEvents WriteOnly Xor';
+
+	this.regexList = [
+		{ regex: new RegExp('\'.*$', 'gm'),							css: 'comment' },			// one line comments
+		{ regex: new RegExp('"(?:\\.|[^\\""])*"', 'g'),				css: 'string' },			// strings
+		{ regex: new RegExp('^\\s*#.*', 'gm'),						css: 'preprocessor' },		// preprocessor tags like #region and #endregion
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// c# keyword
+		];
+
+	this.CssClass = 'dp-vb';
+}
+
+dp.sh.Brushes.Vb.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Vb.Aliases	= ['vb', 'vb.net'];
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushXml.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushXml.js
new file mode 100644
index 0000000..941ad57
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shBrushXml.js
@@ -0,0 +1,61 @@
+dp.sh.Brushes.Xml = function()
+{
+	this.CssClass = 'dp-xml';
+}
+
+dp.sh.Brushes.Xml.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Xml.Aliases	= ['xml', 'xhtml', 'xslt', 'html', 'xhtml'];
+
+dp.sh.Brushes.Xml.prototype.ProcessRegexList = function()
+{
+	function push(array, value)
+	{
+		array[array.length] = value;
+	}
+	
+	/* If only there was a way to get index of a group within a match, the whole XML
+	   could be matched with the expression looking something like that:
+	
+	   (<!\[CDATA\[\s*.*\s*\]\]>)
+	   | (<!--\s*.*\s*?-->)
+	   | (<)*(\w+)*\s*(\w+)\s*=\s*(".*?"|'.*?'|\w+)(/*>)*
+	   | (</?)(.*?)(/?>)
+	*/
+	var index	= 0;
+	var match	= null;
+	var regex	= null;
+
+	// Match CDATA in the following format <![ ... [ ... ]]>
+	// <\!\[[\w\s]*?\[(.|\s)*?\]\]>
+	this.GetMatches(new RegExp('<\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\]>', 'gm'), 'cdata');
+	
+	// Match comments
+	// <!--\s*.*\s*?-->
+	this.GetMatches(new RegExp('<!--\\s*.*\\s*?-->', 'gm'), 'comments');
+
+	// Match attributes and their values
+	// (\w+)\s*=\s*(".*?"|\'.*?\'|\w+)*
+	regex = new RegExp('([\\w-\.]+)\\s*=\\s*(".*?"|\'.*?\'|\\w+)*', 'gm');
+	while((match = regex.exec(this.code)) != null)
+	{
+		push(this.matches, new dp.sh.Match(match[1], match.index, 'attribute'));
+	
+		// if xml is invalid and attribute has no property value, ignore it	
+		if(match[2] != undefined)
+		{
+			push(this.matches, new dp.sh.Match(match[2], match.index + match[0].indexOf(match[2]), 'attribute-value'));
+		}
+	}
+
+	// Match opening and closing tag brackets
+	// </*\?*(?!\!)|/*\?*>
+	this.GetMatches(new RegExp('</*\\?*(?!\\!)|/*\\?*>', 'gm'), 'tag');
+
+	// Match tag names
+	// </*\?*\s*(\w+)
+	regex = new RegExp('</*\\?*\\s*([\\w-\.]+)', 'gm');
+	while((match = regex.exec(this.code)) != null)
+	{
+		push(this.matches, new dp.sh.Match(match[1], match.index + match[0].indexOf(match[1]), 'tag-name'));
+	}
+}
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shCore.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shCore.js
new file mode 100644
index 0000000..b27395e
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/shCore.js
@@ -0,0 +1,622 @@
+/**
+ * Code Syntax Highlighter.
+ * Version 1.3.0
+ * Copyright (C) 2004 Alex Gorbatchev.
+ * http://www.dreamprojections.com/syntaxhighlighter/
+ * 
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General 
+ * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) 
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to 
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
+ */
+
+//
+// create namespaces
+//
+var dp = {
+	sh :					// dp.sh
+	{
+		Utils	: {},		// dp.sh.Utils
+		Brushes	: {},		// dp.sh.Brushes
+		Strings : {},
+		Version : '1.3.0'
+	}
+};
+
+dp.sh.Strings = {
+	AboutDialog : '<html><head><title>About...</title></head><body class="dp-about"><table cellspacing="0"><tr><td class="copy"><p class="title">dp.SyntaxHighlighter</div><div class="para">Version: {V}</p><p><a href="http://www.dreamprojections.com/syntaxhighlighter/?ref=about" target="_blank">http://www.dreamprojections.com/SyntaxHighlighter</a></p>&copy;2004-2005 Alex Gorbatchev. All right reserved.</td></tr><tr><td class="footer"><input type="button" class="close" value="OK" onClick="window.close()"/></td></tr></table></body></html>',
+	
+	// tools
+	ExpandCode : '+ expand code',
+	ViewPlain : 'view plain',
+	Print : 'print',
+	CopyToClipboard : 'copy to clipboard',
+	About : '?',
+	
+	CopiedToClipboard : 'The code is in your clipboard now.'
+};
+
+dp.SyntaxHighlighter = dp.sh;
+
+//
+// Dialog and toolbar functions
+//
+
+dp.sh.Utils.Expand = function(sender)
+{
+	var table = sender;
+	var span = sender;
+
+	// find the span in which the text label and pipe contained so we can hide it
+	while(span != null && span.tagName != 'SPAN')
+		span = span.parentNode;
+
+	// find the table
+	while(table != null && table.tagName != 'TABLE')
+		table = table.parentNode;
+	
+	// remove the 'expand code' button
+	span.parentNode.removeChild(span);
+	
+	table.tBodies[0].className = 'show';
+	table.parentNode.style.height = '100%'; // containing div isn't getting updated properly when the TBODY is shown
+}
+
+// opens a new windows and puts the original unformatted source code inside.
+dp.sh.Utils.ViewSource = function(sender)
+{
+	var code = sender.parentNode.originalCode;
+	var wnd = window.open('', '_blank', 'width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=1');
+	
+	code = code.replace(/</g, '&lt;');
+	
+	wnd.document.write('<pre>' + code + '</pre>');
+	wnd.document.close();
+}
+
+// copies the original source code in to the clipboard (IE only)
+dp.sh.Utils.ToClipboard = function(sender)
+{
+	var code = sender.parentNode.originalCode;
+	
+	// This works only for IE. There's a way to make it work with Mozilla as well,
+	// but it requires security settings changed on the client, which isn't by
+	// default, so 99% of users won't have it working anyways.
+	if(window.clipboardData)
+	{
+		window.clipboardData.setData('text', code);
+		
+		alert(dp.sh.Strings.CopiedToClipboard);
+	}
+}
+
+// creates an invisible iframe, puts the original source code inside and prints it
+dp.sh.Utils.PrintSource = function(sender)
+{
+	var td		= sender.parentNode;
+	var code	= td.processedCode;
+	var iframe	= document.createElement('IFRAME');
+	var doc		= null;
+	var wnd		= 
+
+	// this hides the iframe
+	iframe.style.cssText = 'position:absolute; width:0px; height:0px; left:-5px; top:-5px;';
+	
+	td.appendChild(iframe);
+	
+	doc = iframe.contentWindow.document;
+	code = code.replace(/</g, '&lt;');
+	
+	doc.open();
+	doc.write('<pre>' + code + '</pre>');
+	doc.close();
+	
+	iframe.contentWindow.focus();
+	iframe.contentWindow.print();
+	
+	td.removeChild(iframe);
+}
+
+dp.sh.Utils.About = function()
+{
+	var wnd	= window.open('', '_blank', 'dialog,width=320,height=150,scrollbars=0');
+	var doc	= wnd.document;
+	
+	var styles = document.getElementsByTagName('style');
+	var links = document.getElementsByTagName('link');
+	
+	doc.write(dp.sh.Strings.AboutDialog.replace('{V}', dp.sh.Version));
+	
+	// copy over ALL the styles from the parent page
+	for(var i = 0; i < styles.length; i++)
+		doc.write('<style>' + styles[i].innerHTML + '</style>');
+
+	for(var i = 0; i < links.length; i++)
+		if(links[i].rel.toLowerCase() == 'stylesheet')
+			doc.write('<link type="text/css" rel="stylesheet" href="' + links[i].href + '"></link>');
+	
+	doc.close();
+	wnd.focus();
+}
+
+//
+// Match object
+//
+dp.sh.Match = function(value, index, css)
+{
+	this.value		= value;
+	this.index		= index;
+	this.length		= value.length;
+	this.css		= css;
+}
+
+//
+// Highlighter object
+//
+dp.sh.Highlighter = function()
+{
+	this.addGutter = true;
+	this.addControls = true;
+	this.collapse = false;
+	this.tabsToSpaces = true;
+}
+
+// static callback for the match sorting
+dp.sh.Highlighter.SortCallback = function(m1, m2)
+{
+	// sort matches by index first
+	if(m1.index < m2.index)
+		return -1;
+	else if(m1.index > m2.index)
+		return 1;
+	else
+	{
+		// if index is the same, sort by length
+		if(m1.length < m2.length)
+			return -1;
+		else if(m1.length > m2.length)
+			return 1;
+	}
+	return 0;
+}
+
+// gets a list of all matches for a given regular expression
+dp.sh.Highlighter.prototype.GetMatches = function(regex, css)
+{
+	var index = 0;
+	var match = null;
+
+	while((match = regex.exec(this.code)) != null)
+	{
+		this.matches[this.matches.length] = new dp.sh.Match(match[0], match.index, css);
+	}
+}
+
+dp.sh.Highlighter.prototype.AddBit = function(str, css)
+{
+	var span = document.createElement('span');
+	
+	str = str.replace(/&/g, '&amp;');
+	str = str.replace(/ /g, '&nbsp;');
+	str = str.replace(/</g, '&lt;');
+	str = str.replace(/\n/gm, '&nbsp;<br>');
+
+	// when adding a piece of code, check to see if it has line breaks in it 
+	// and if it does, wrap individual line breaks with span tags
+	if(css != null)
+	{
+		var regex = new RegExp('<br>', 'gi');
+		
+		if(regex.test(str))
+		{
+			var lines = str.split('&nbsp;<br>');
+			
+			str = '';
+			
+			for(var i = 0; i < lines.length; i++)
+			{
+				span			= document.createElement('SPAN');
+				span.className	= css;
+				span.innerHTML	= lines[i];
+				
+				this.div.appendChild(span);
+				
+				// don't add a <BR> for the last line
+				if(i + 1 < lines.length)
+					this.div.appendChild(document.createElement('BR'));
+			}
+		}
+		else
+		{
+			span.className = css;
+			span.innerHTML = str;
+			this.div.appendChild(span);
+		}
+	}
+	else
+	{
+		span.innerHTML = str;
+		this.div.appendChild(span);
+	}
+}
+
+// checks if one match is inside any other match
+dp.sh.Highlighter.prototype.IsInside = function(match)
+{
+	if(match == null || match.length == 0)
+		return;
+	
+	for(var i = 0; i < this.matches.length; i++)
+	{
+		var c = this.matches[i];
+		
+		if(c == null)
+			continue;
+		
+		if((match.index > c.index) && (match.index <= c.index + c.length))
+			return true;
+	}
+	
+	return false;
+}
+
+dp.sh.Highlighter.prototype.ProcessRegexList = function()
+{
+	for(var i = 0; i < this.regexList.length; i++)
+		this.GetMatches(this.regexList[i].regex, this.regexList[i].css);
+}
+
+dp.sh.Highlighter.prototype.ProcessSmartTabs = function(code)
+{
+	var lines	= code.split('\n');
+	var result	= '';
+	var tabSize	= 4;
+	var tab		= '\t';
+
+	// This function inserts specified amount of spaces in the string
+	// where a tab is while removing that given tab. 
+	function InsertSpaces(line, pos, count)
+	{
+		var left	= line.substr(0, pos);
+		var right	= line.substr(pos + 1, line.length);	// pos + 1 will get rid of the tab
+		var spaces	= '';
+		
+		for(var i = 0; i < count; i++)
+			spaces += ' ';
+		
+		return left + spaces + right;
+	}
+
+	// This function process one line for 'smart tabs'
+	function ProcessLine(line, tabSize)
+	{
+		if(line.indexOf(tab) == -1)
+			return line;
+
+		var pos = 0;
+
+		while((pos = line.indexOf(tab)) != -1)
+		{
+			// This is pretty much all there is to the 'smart tabs' logic.
+			// Based on the position within the line and size of a tab, 
+			// calculate the amount of spaces we need to insert.
+			var spaces = tabSize - pos % tabSize;
+			
+			line = InsertSpaces(line, pos, spaces);
+		}
+		
+		return line;
+	}
+
+	// Go through all the lines and do the 'smart tabs' magic.
+	for(var i = 0; i < lines.length; i++)
+		result += ProcessLine(lines[i], tabSize) + '\n';
+	
+	return result;
+}
+
+dp.sh.Highlighter.prototype.SwitchToTable = function()
+{
+	// thanks to Lachlan Donald from SitePoint.com for this <br/> tag fix.
+	var html	= this.div.innerHTML.replace(/<(br)\/?>/gi, '\n');
+	var lines	= html.split('\n');
+	var row		= null;
+	var cell	= null;
+	var tBody	= null;
+	var html	= '';
+	var pipe	= ' | ';
+
+	// creates an anchor to a utility
+	function UtilHref(util, text)
+	{
+		return '<a href="#" onclick="dp.sh.Utils.' + util + '(this); return false;">' + text + '</a>';
+	}
+	
+	tBody = document.createElement('TBODY');	// can be created and all others go to tBodies collection.
+
+	this.table.appendChild(tBody);
+		
+	if(this.addGutter == true)
+	{
+		row = tBody.insertRow(-1);
+		cell = row.insertCell(-1);
+		cell.className = 'tools-corner';
+	}
+
+	if(this.addControls == true)
+	{
+		var tHead = document.createElement('THEAD');	// controls will be placed in here
+		this.table.appendChild(tHead);
+
+		row = tHead.insertRow(-1);
+
+		// add corner if there's a gutter
+		if(this.addGutter == true)
+		{
+			cell = row.insertCell(-1);
+			cell.className = 'tools-corner';
+		}
+		
+		cell = row.insertCell(-1);
+		
+		// preserve some variables for the controls
+		cell.originalCode = this.originalCode;
+		cell.processedCode = this.code;
+		cell.className = 'tools';
+		
+		if(this.collapse == true)
+		{
+			tBody.className = 'hide';
+			cell.innerHTML += '<span><b>' + UtilHref('Expand', dp.sh.Strings.ExpandCode) + '</b>' + pipe + '</span>';
+		}
+
+		cell.innerHTML += UtilHref('ViewSource', dp.sh.Strings.ViewPlain) + pipe + UtilHref('PrintSource', dp.sh.Strings.Print);
+		
+		// IE has this clipboard object which is easy enough to use
+		if(window.clipboardData)
+			cell.innerHTML += pipe + UtilHref('ToClipboard', dp.sh.Strings.CopyToClipboard);
+		
+		cell.innerHTML += pipe + UtilHref('About', dp.sh.Strings.About);
+	}
+
+	for(var i = 0, lineIndex = this.firstLine; i < lines.length - 1; i++, lineIndex++)
+	{
+		row = tBody.insertRow(-1);
+		
+		if(this.addGutter == true)
+		{
+			cell = row.insertCell(-1);
+			cell.className = 'gutter';
+			cell.innerHTML = lineIndex;
+		}
+
+		cell = row.insertCell(-1);
+		cell.className = 'line' + (i % 2 + 1);		// uses .line1 and .line2 css styles for alternating lines
+		cell.innerHTML = lines[i];
+	}
+	
+	this.div.innerHTML	= '';
+}
+
+dp.sh.Highlighter.prototype.Highlight = function(code)
+{
+	function Trim(str)
+	{
+		return str.replace(/^\s*(.*?)[\s\n]*$/g, '$1');
+	}
+	
+	function Chop(str)
+	{
+		return str.replace(/\n*$/, '').replace(/^\n*/, '');
+	}
+
+	function Unindent(str)
+	{
+		var lines = str.split('\n');
+		var indents = new Array();
+		var regex = new RegExp('^\\s*', 'g');
+		var min = 1000;
+
+		// go through every line and check for common number of indents
+		for(var i = 0; i < lines.length && min > 0; i++)
+		{
+			if(Trim(lines[i]).length == 0)
+				continue;
+				
+			var matches = regex.exec(lines[i]);
+
+			if(matches != null && matches.length > 0)
+				min = Math.min(matches[0].length, min);
+		}
+
+		// trim minimum common number of white space from the begining of every line
+		if(min > 0)
+			for(var i = 0; i < lines.length; i++)
+				lines[i] = lines[i].substr(min);
+
+		return lines.join('\n');
+	}
+	
+	// This function returns a portions of the string from pos1 to pos2 inclusive
+	function Copy(string, pos1, pos2)
+	{
+		return string.substr(pos1, pos2 - pos1);
+	}
+
+	var pos	= 0;
+	
+	this.originalCode = code;
+	this.code = Chop(Unindent(code));
+	this.div = document.createElement('DIV');
+	this.table = document.createElement('TABLE');
+	this.matches = new Array();
+
+	if(this.CssClass != null)
+		this.table.className = this.CssClass;
+
+	// replace tabs with spaces
+	if(this.tabsToSpaces == true)
+		this.code = this.ProcessSmartTabs(this.code);
+
+	this.table.border = 0;
+	this.table.cellSpacing = 0;
+	this.table.cellPadding = 0;
+
+	this.ProcessRegexList();	
+
+	// if no matches found, add entire code as plain text
+	if(this.matches.length == 0)
+	{
+		this.AddBit(this.code, null);
+		this.SwitchToTable();
+		return;
+	}
+
+	// sort the matches
+	this.matches = this.matches.sort(dp.sh.Highlighter.SortCallback);
+
+	// The following loop checks to see if any of the matches are inside
+	// of other matches. This process would get rid of highligting strings
+	// inside comments, keywords inside strings and so on.
+	for(var i = 0; i < this.matches.length; i++)
+		if(this.IsInside(this.matches[i]))
+			this.matches[i] = null;
+
+	// Finally, go through the final list of matches and pull the all
+	// together adding everything in between that isn't a match.
+	for(var i = 0; i < this.matches.length; i++)
+	{
+		var match = this.matches[i];
+
+		if(match == null || match.length == 0)
+			continue;
+		
+		this.AddBit(Copy(this.code, pos, match.index), null);
+		this.AddBit(match.value, match.css);
+		
+		pos = match.index + match.length;
+	}
+	
+	this.AddBit(this.code.substr(pos), null);
+
+	this.SwitchToTable();
+}
+
+dp.sh.Highlighter.prototype.GetKeywords = function(str) 
+{
+	return '\\b' + str.replace(/ /g, '\\b|\\b') + '\\b';
+}
+
+// highlightes all elements identified by name and gets source code from specified property
+dp.sh.HighlightAll = function(name, showGutter /* optional */, showControls /* optional */, collapseAll /* optional */, firstLine /* optional */)
+{
+	function FindValue()
+	{
+		var a = arguments;
+		
+		for(var i = 0; i < a.length; i++)
+		{
+			if(a[i] == null)
+				continue;
+				
+			if(typeof(a[i]) == 'string' && a[i] != '')
+				return a[i] + '';
+		
+			if(typeof(a[i]) == 'object' && a[i].value != '')
+				return a[i].value + '';
+		}
+		
+		return null;
+	}
+	
+	function IsOptionSet(value, list)
+	{
+		for(var i = 0; i < list.length; i++)
+			if(list[i] == value)
+				return true;
+		
+		return false;
+	}
+	
+	function GetOptionValue(name, list, defaultValue)
+	{
+		var regex = new RegExp('^' + name + '\\[(\\w+)\\]$', 'gi');
+		var matches = null;
+
+		for(var i = 0; i < list.length; i++)
+			if((matches = regex.exec(list[i])) != null)
+				return matches[1];
+		
+		return defaultValue;
+	}
+
+	var elements = document.getElementsByName(name);
+	var highlighter = null;
+	var registered = new Object();
+	var propertyName = 'value';
+	
+	// if no code blocks found, leave
+	if(elements == null)
+		return;
+
+	// register all brushes
+	for(var brush in dp.sh.Brushes)
+	{
+		var aliases = dp.sh.Brushes[brush].Aliases;
+		
+		if(aliases == null)
+			continue;
+		
+		for(var i = 0; i < aliases.length; i++)
+			registered[aliases[i]] = brush;
+	}
+
+	for(var i = 0; i < elements.length; i++)
+	{
+		var element = elements[i];
+		var options = FindValue(
+				element.attributes['class'], element.className, 
+				element.attributes['language'], element.language
+				);
+		var language = '';
+		
+		if(options == null)
+			continue;
+		
+		options = options.split(':');
+		
+		language = options[0].toLowerCase();
+		
+		if(registered[language] == null)
+			continue;
+		
+		// instantiate a brush
+		highlighter = new dp.sh.Brushes[registered[language]]();
+		
+		// hide the original element
+		element.style.display = 'none';
+
+		highlighter.addGutter = (showGutter == null) ? !IsOptionSet('nogutter', options) : showGutter;
+		highlighter.addControls = (showControls == null) ? !IsOptionSet('nocontrols', options) : showControls;
+		highlighter.collapse = (collapseAll == null) ? IsOptionSet('collapse', options) : collapseAll;
+		
+		// first line idea comes from Andrew Collington, thanks!
+		highlighter.firstLine = (firstLine == null) ? parseInt(GetOptionValue('firstline', options, 1)) : firstLine;
+
+		highlighter.Highlight(element[propertyName]);
+
+		// place the result table inside a div
+		var div = document.createElement('DIV');
+		
+		div.className = 'dp-highlighter';
+		div.appendChild(highlighter.table);
+
+		element.parentNode.insertBefore(div, element);		
+	}	
+}
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/site.css b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/site.css
new file mode 100644
index 0000000..959ab0a
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/site.css
@@ -0,0 +1,25 @@
+/* @override http://felix.apache.org/site/media.data/site.css */
+
+body { background-color: #ffffff; color: #3b3b3b; font-family: Tahoma, Arial, sans-serif; font-size: 10pt; line-height: 140% }
+h1, h2, h3, h4, h5, h6 { font-weight: normal; color: #000000; line-height: 100%; margin-top: 0px}
+h1 { font-size: 200% }
+h2 { font-size: 175% }
+h3 { font-size: 150% }
+h4 { font-size: 140% }
+h5 { font-size: 130% }
+h6 { font-size: 120% }
+a { color: #1980af }
+a:visited { color: #1980af }
+a:hover { color: #1faae9 }
+.title { position: absolute; left: 1px; right: 1px; top:25px; height: 81px; background: url(http://felix.apache.org/site/media.data/gradient.png) repeat-x; background-position: bottom; }
+.logo { position: absolute; width: 15em; height: 81px; text-align: center; }
+.header { text-align: right; margin-right: 20pt; margin-top: 30pt;}
+.menu { border-top: 10px solid #f9bb00; position: absolute; top: 107px; left: 1px; width: 15em; bottom: 0px; padding: 0px; background-color: #fcfcfc }
+.menu ul { background-color: #fdf5d9; list-style: none; padding-left: 4em; margin-top: 0px; padding-top: 2em; padding-bottom: 2em; margin-left: 0px; color: #4a4a43}
+.menu a { text-decoration: none; color: #4a4a43 }
+.main { position: absolute; border-top: 10px solid #cde0ea; top: 107px; left: 15em; right: 1px; margin-left: 2px; padding-right: 4em; padding-left: 1em; padding-top: 1em;}
+.code { background-color: #eeeeee; border: solid 1px black; padding: 0.5em }
+.code-keyword { color: #880000 }
+.code-quote { color: #008800 }
+.code-object { color: #0000dd }
+.code-java { margin: 0em }
\ No newline at end of file
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/superfish.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/superfish.js
new file mode 100644
index 0000000..c6a9c7d
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/superfish.js
@@ -0,0 +1,121 @@
+
+/*
+ * Superfish v1.4.8 - jQuery menu widget
+ * Copyright (c) 2008 Joel Birch
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * 	http://www.opensource.org/licenses/mit-license.php
+ * 	http://www.gnu.org/licenses/gpl.html
+ *
+ * CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
+ */
+
+;(function($){
+	$.fn.superfish = function(op){
+
+		var sf = $.fn.superfish,
+			c = sf.c,
+			$arrow = $(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
+			over = function(){
+				var $$ = $(this), menu = getMenu($$);
+				clearTimeout(menu.sfTimer);
+				$$.showSuperfishUl().siblings().hideSuperfishUl();
+			},
+			out = function(){
+				var $$ = $(this), menu = getMenu($$), o = sf.op;
+				clearTimeout(menu.sfTimer);
+				menu.sfTimer=setTimeout(function(){
+					o.retainPath=($.inArray($$[0],o.$path)>-1);
+					$$.hideSuperfishUl();
+					if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
+				},o.delay);	
+			},
+			getMenu = function($menu){
+				var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
+				sf.op = sf.o[menu.serial];
+				return menu;
+			},
+			addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
+			
+		return this.each(function() {
+			var s = this.serial = sf.o.length;
+			var o = $.extend({},sf.defaults,op);
+			o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
+				$(this).addClass([o.hoverClass,c.bcClass].join(' '))
+					.filter('li:has(ul)').removeClass(o.pathClass);
+			});
+			sf.o[s] = sf.op = o;
+			
+			$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
+				if (o.autoArrows) addArrow( $('>a:first-child',this) );
+			})
+			.not('.'+c.bcClass)
+				.hideSuperfishUl();
+			
+			var $a = $('a',this);
+			$a.each(function(i){
+				var $li = $a.eq(i).parents('li');
+				$a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
+			});
+			o.onInit.call(this);
+			
+		}).each(function() {
+			var menuClasses = [c.menuClass];
+			if (sf.op.dropShadows  && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass);
+			$(this).addClass(menuClasses.join(' '));
+		});
+	};
+
+	var sf = $.fn.superfish;
+	sf.o = [];
+	sf.op = {};
+	sf.IE7fix = function(){
+		var o = sf.op;
+		if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined)
+			this.toggleClass(sf.c.shadowClass+'-off');
+		};
+	sf.c = {
+		bcClass     : 'sf-breadcrumb',
+		menuClass   : 'sf-js-enabled',
+		anchorClass : 'sf-with-ul',
+		arrowClass  : 'sf-sub-indicator',
+		shadowClass : 'sf-shadow'
+	};
+	sf.defaults = {
+		hoverClass	: 'sfHover',
+		pathClass	: 'overideThisToUse',
+		pathLevels	: 1,
+		delay		: 800,
+		animation	: {opacity:'show'},
+		speed		: 'normal',
+		autoArrows	: true,
+		dropShadows : true,
+		disableHI	: false,		// true disables hoverIntent detection
+		onInit		: function(){}, // callback functions
+		onBeforeShow: function(){},
+		onShow		: function(){},
+		onHide		: function(){}
+	};
+	$.fn.extend({
+		hideSuperfishUl : function(){
+			var o = sf.op,
+				not = (o.retainPath===true) ? o.$path : '';
+			o.retainPath = false;
+			var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
+					.find('>ul').hide().css('visibility','hidden');
+			o.onHide.call($ul);
+			return this;
+		},
+		showSuperfishUl : function(){
+			var o = sf.op,
+				sh = sf.c.shadowClass+'-off',
+				$ul = this.addClass(o.hoverClass)
+					.find('>ul:hidden').css('visibility','visible');
+			sf.IE7fix.call($ul);
+			o.onBeforeShow.call($ul);
+			$ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
+			return this;
+		}
+	});
+
+})(jQuery);
diff --git a/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/supersubs.js b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/supersubs.js
new file mode 100644
index 0000000..4522151
--- /dev/null
+++ b/ipojo/runtime/annotations/doc/how-to-use-ipojo-annotations_files/supersubs.js
@@ -0,0 +1,90 @@
+
+/*
+ * Supersubs v0.2b - jQuery plugin
+ * Copyright (c) 2008 Joel Birch
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * 	http://www.opensource.org/licenses/mit-license.php
+ * 	http://www.gnu.org/licenses/gpl.html
+ *
+ *
+ * This plugin automatically adjusts submenu widths of suckerfish-style menus to that of
+ * their longest list item children. If you use this, please expect bugs and report them
+ * to the jQuery Google Group with the word 'Superfish' in the subject line.
+ *
+ */
+
+;(function($){ // $ will refer to jQuery within this closure
+
+	$.fn.supersubs = function(options){
+		var opts = $.extend({}, $.fn.supersubs.defaults, options);
+		// return original object to support chaining
+		return this.each(function() {
+			// cache selections
+			var $$ = $(this);
+			// support metadata
+			var o = $.meta ? $.extend({}, opts, $$.data()) : opts;
+			// get the font size of menu.
+			// .css('fontSize') returns various results cross-browser, so measure an em dash instead
+			var fontsize = $('<li id="menu-fontsize">&#8212;</li>').css({
+				'padding' : 0,
+				'position' : 'absolute',
+				'top' : '-999em',
+				'width' : 'auto'
+			}).appendTo($$).width(); //clientWidth is faster, but was incorrect here
+			// remove em dash
+			$('#menu-fontsize').remove();
+			// cache all ul elements
+			$ULs = $$.find('ul');
+			// loop through each ul in menu
+			$ULs.each(function(i) {	
+				// cache this ul
+				var $ul = $ULs.eq(i);
+				// get all (li) children of this ul
+				var $LIs = $ul.children();
+				// get all anchor grand-children
+				var $As = $LIs.children('a');
+				// force content to one line and save current float property
+				var liFloat = $LIs.css('white-space','nowrap').css('float');
+				// remove width restrictions and floats so elements remain vertically stacked
+				var emWidth = $ul.add($LIs).add($As).css({
+					'float' : 'none',
+					'width'	: 'auto'
+				})
+				// this ul will now be shrink-wrapped to longest li due to position:absolute
+				// so save its width as ems. Clientwidth is 2 times faster than .width() - thanks Dan Switzer
+				.end().end()[0].clientWidth / fontsize;
+				// add more width to ensure lines don't turn over at certain sizes in various browsers
+				emWidth += o.extraWidth;
+				// restrict to at least minWidth and at most maxWidth
+				if (emWidth > o.maxWidth)		{ emWidth = o.maxWidth; }
+				else if (emWidth < o.minWidth)	{ emWidth = o.minWidth; }
+				emWidth += 'em';
+				// set ul to width in ems
+				$ul.css('width',emWidth);
+				// restore li floats to avoid IE bugs
+				// set li width to full width of this ul
+				// revert white-space to normal
+				$LIs.css({
+					'float' : liFloat,
+					'width' : '100%',
+					'white-space' : 'normal'
+				})
+				// update offset position of descendant ul to reflect new width of parent
+				.each(function(){
+					var $childUl = $('>ul',this);
+					var offsetDirection = $childUl.css('left')!==undefined ? 'left' : 'right';
+					$childUl.css(offsetDirection,emWidth);
+				});
+			});
+			
+		});
+	};
+	// expose defaults
+	$.fn.supersubs.defaults = {
+		minWidth		: 9,		// requires em unit.
+		maxWidth		: 25,		// requires em unit.
+		extraWidth		: 0			// extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values
+	};
+	
+})(jQuery); // plugin code ends
diff --git a/ipojo/runtime/annotations/pom.xml b/ipojo/runtime/annotations/pom.xml
new file mode 100644
index 0000000..9dbc71e
--- /dev/null
+++ b/ipojo/runtime/annotations/pom.xml
@@ -0,0 +1,122 @@
+<!--
+  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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix-parent</artifactId>
+    <version>1.2.1</version>
+    <relativePath>../../../pom/pom.xml</relativePath>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>org.apache.felix.ipojo.annotations</artifactId>
+  <groupId>org.apache.felix</groupId>
+  <version>1.9.0-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+  <name>Apache Felix iPOJO Annotations</name>
+
+  <description>
+  iPOJO Annotation pack. contained annotations are used to define iPOJO component type.
+  </description>
+  <url>
+  http://felix.apache.org/site/how-to-use-ipojo-annotations.html
+  </url>
+
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>1.4.3</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Name>Apache Felix iPOJO Annotations</Bundle-Name>
+            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+            <Bundle-Vendor> The Apache Software Foundation </Bundle-Vendor>
+            <Bundle-Description> iPOJO Annotations </Bundle-Description>
+            <Bundle-DocURL>http://felix.apache.org/site/how-to-use-ipojo-annotations.html</Bundle-DocURL>
+            <Export-Package> org.apache.felix.ipojo.annotations,
+              org.apache.felix.ipojo.handler.temporal,
+              org.apache.felix.ipojo.handlers.jmx,
+              org.apache.felix.ipojo.extender,
+              org.apache.felix.ipojo.whiteboard,
+              org.apache.felix.ipojo.handlers.event,
+              org.apache.felix.ipojo.transaction
+             </Export-Package>
+            <Include-Resource>
+              META-INF/LICENSE=LICENSE,
+              META-INF/NOTICE=NOTICE,
+              META-INF/DEPENDENCIES=DEPENDENCIES
+             </Include-Resource>
+          </instructions>
+          <obrRepository>NONE</obrRepository>
+        </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>DEPENDENCIES</param>
+          </excludes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+
+    <resources>
+		<resource>
+			<directory>src/main/resources</directory>
+		</resource>
+		<resource>
+			<directory>.</directory>
+			<targetPath>META-INF</targetPath>
+			<includes>
+				<include>LICENSE*</include>
+				<include>NOTICE*</include>
+				<include>DEPENDENCIES*</include>
+			</includes>
+		</resource>
+	</resources>
+
+  </build>
+</project>
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Bind.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Bind.java
new file mode 100644
index 0000000..d84c831
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Bind.java
@@ -0,0 +1,80 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.Comparator;
+
+/**
+ * This annotation declares a bind method.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface Bind {
+    
+    /**
+     * Set the dependency filter.
+     * Default : no filter
+     */
+    String filter() default "";
+    
+    /**
+     * Set if the dependency is an aggregate dependency.
+     * Default : false
+     */
+    boolean aggregate() default false;
+    
+    /**
+     * Set if the dependency is optional.
+     * Default : false
+     */
+    boolean optional() default false;
+    
+    /**
+     * Set the required specification.
+     * Default : empty (try to discover)
+     */
+    String specification() default "";
+    
+    /**
+     * Set the dependency id.
+     * Default : empty
+     */
+    String id() default "";
+    
+    /**
+     * Set the binding policy.
+     * Acceptable policy are dynamic, static and dynamic-priority.
+     * Default: dynamic.
+     */
+    String policy() default "dynamic";
+    
+    /**
+     * Set the comparator.
+     * The indicated class must implement {@link Comparator}
+     */
+    Class comparator() default Comparator.class;
+    
+    /**
+     * Set the from attribute.
+     */
+    String from() default "";
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java
new file mode 100644
index 0000000..28fbb2d
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Component.java
@@ -0,0 +1,96 @@
+/*
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation declares a component.
+ * This annotation is mandatory to declares an iPOJO component.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface Component {
+
+    /**
+     * Set if the component type is public.
+     * Default: true
+     * @deprecated renamed to publicFactory.
+     */
+    boolean public_factory() default true;
+
+    /**
+     * Set if the component type is public.
+     * Default: true
+     */
+    boolean publicFactory() default true;
+
+    /**
+     * Set the component type name.
+     * Default : implementation class name.
+     */
+    String name() default "";
+
+    /**
+     * Enable / Disable the architecture exposition.
+     * Default : false
+     */
+    boolean architecture() default false;
+
+    /**
+     * Set if the component is immediate.
+     * Default : false
+     */
+    boolean immediate() default false;
+
+    /**
+     * Set if the component must propagate received configuration to provided services.
+     * default: false
+     */
+    boolean propagation() default false;
+
+    /**
+     * Set the Managed Service PID.
+     * default no PID (i.e. the managed service will not be exposed).
+     */
+    String managedservice() default "";
+
+    /**
+     * Set the factory-method, if the pojo has to be created
+     * from a static method. The specified method must be a static
+     * method and return a pojo object.
+     * By default, iPOJO uses the 'regular' constructor.
+     * @deprecated now is called <tt>factoryMethod</tt>.
+     */
+    String factory_method() default "";
+
+    /**
+     * Set the factory-method, if the pojo has to be created
+     * from a static method. The specified method must be a static
+     * method and return a pojo object.
+     * By default, iPOJO uses the 'regular' constructor.
+     */
+    String factoryMethod() default "";
+
+    /**
+     * Set the version of the component type.
+     */
+    String version() default "";
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Controller.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Controller.java
new file mode 100644
index 0000000..e4bfaeb
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Controller.java
@@ -0,0 +1,32 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation declares a lifecycle controller.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.FIELD)
+public @interface Controller {
+    
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Handler.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Handler.java
new file mode 100644
index 0000000..7b8e4a4
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Handler.java
@@ -0,0 +1,53 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation declares a handler.
+ * This annotation is mandatory to declares an iPOJO handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface Handler {
+
+    /**
+     * Name of the handler (required).
+     */
+    String name();
+
+    /**
+     * Namespace of the handler (required).
+     */
+    String namespace();
+
+    /**
+     * Start-level of the handler.
+     * Default: 1.
+     */
+    int level() default 1;
+
+    /**
+     * Enable / Disable the architecture exposition.
+     * Default : false
+     */
+    boolean architecture() default false;
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerDeclaration.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerDeclaration.java
new file mode 100644
index 0000000..c4eaeaf
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/HandlerDeclaration.java
@@ -0,0 +1,36 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation is used to configure a handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface HandlerDeclaration {
+
+    /**
+     * The content of this attribute represents the XML 
+     * that would be used in the metadata.xml.
+     */
+    String value();
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Instantiate.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Instantiate.java
new file mode 100644
index 0000000..dba9d43
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Instantiate.java
@@ -0,0 +1,37 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation is used to create an 'empty' instance of the
+ * current component type.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface Instantiate {
+    
+    /**
+     * Optional attribute to set the instance name.
+     * Default: no name
+     */
+    String name() default ""; 
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Invalidate.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Invalidate.java
new file mode 100644
index 0000000..72a7c6c
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Invalidate.java
@@ -0,0 +1,31 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation declares an invalidate callback.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface Invalidate {
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java
new file mode 100644
index 0000000..ea18919
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Modified.java
@@ -0,0 +1,81 @@
+/*
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.Comparator;
+
+/**
+ * This annotation declares a modify method.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface Modified {
+
+    /**
+     * Set the dependency filter.
+     * Default : no filter
+     */
+    String filter() default "";
+
+    /**
+     * Set if the dependency is an aggregate dependency.
+     * Default : false
+     */
+    boolean aggregate() default false;
+
+
+    /**
+     * Set if the dependency is optional.
+     * Default : false
+     */
+    boolean optional() default false;
+
+    /**
+     * Set the required specification.
+     * Default : empty (try to discover).
+     */
+    String specification() default "";
+
+    /**
+     * Set the dependency id.
+     * Default : empty.
+     */
+    String id() default "";
+
+    /**
+     * Set the binding policy.
+     * Acceptable policy are dynamic, static and dynamic-priority.
+     * Default: dynamic.
+     */
+    String policy() default "dynamic";
+
+    /**
+     * Set the comparator.
+     * The indicated class must implement {@link Comparator}
+     */
+    Class comparator() default Comparator.class;
+
+    /**
+     * Set the from attribute.
+     */
+    String from() default "";
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java
new file mode 100644
index 0000000..2e6bac8
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostRegistration.java
@@ -0,0 +1,32 @@
+/*
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+
+/**
+ * This annotation declares a post-service-registration method.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface PostRegistration {
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java
new file mode 100644
index 0000000..428dff5
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/PostUnregistration.java
@@ -0,0 +1,32 @@
+/*
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+
+/**
+ * This annotation declares a post-service-unregistration method.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface PostUnregistration {
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java
new file mode 100644
index 0000000..2c80de5
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Property.java
@@ -0,0 +1,50 @@
+/*
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation declares a component property.
+ * It can target both fields and methods.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER })
+public @interface Property {
+
+    /**
+     * Set property name.
+     * Default : empty
+     */
+    String name() default "";
+
+    /**
+     * Set property value.
+     * Default : empty
+     */
+    String value() default "";
+
+    /**
+     * Is the property mandatory?
+     * Default: false
+     */
+    boolean mandatory() default false;
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Provides.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Provides.java
new file mode 100644
index 0000000..c58c3ef
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Provides.java
@@ -0,0 +1,57 @@
+/*
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+* This annotation declares that the component instances will provide a service.
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+@Target(ElementType.TYPE)
+public @interface Provides {
+
+    /**
+     * Set the provided specifications.
+     * Default : all implemented interfaces
+     */
+    Class[] specifications() default { };
+
+    /**
+     * Set the service object creation strategy.
+     * Two value are possible: SINGLETON, SERVICE, METHOD, INSTANCE or the strategy class name.
+     * SERVICE means OSGi Service Factory.
+     * METHOD delegates the creation to the factory-method of the component
+     * INSTANCE creates one service object per requiring instance
+     * for other strategies, specify the qualified name of the CreationStrategy class.
+     * Default : SINGLETON
+     */
+    String strategy() default "SINGLETON";
+
+    /**
+     * Allows adding static properties to the service.
+     * Nested properties are static service properties,
+     * so <b>must</b> contain the name and the value as
+     * they are not attached to a field.
+     * The array contains {@link StaticServiceProperty} elements.
+     * Default : No service properties
+     */
+    StaticServiceProperty[] properties() default {};
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java
new file mode 100644
index 0000000..4ea2408
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Requires.java
@@ -0,0 +1,96 @@
+/*
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Target;
+import java.util.Comparator;
+
+/**
+ * This annotation declares a service requirement.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target({ ElementType.FIELD, ElementType.PARAMETER })
+@Inherited
+public @interface Requires {
+
+    /**
+     * Set the LDAP filter of the dependency.
+     * Default : no filter
+     */
+    String filter() default "";
+
+    /**
+     * Set if the dependency is optional.
+     * Default : false
+     */
+    boolean optional() default false;
+
+    /**
+     * Set the dependency id.
+     * Default : empty
+     */
+    String id() default "";
+
+    /**
+     * Enable / Disable nullable pattern.
+     * Default : true
+     */
+    boolean nullable() default true;
+
+    /**
+     * Set the default-implementation to use if the dependency is optional,
+     * and no providers are available.
+     * The class must implement the required service interface.
+     * Default : no default-implementation
+     */
+    Class defaultimplementation() default Class.class;
+
+    /**
+     * Set the binding policy.
+     * Acceptable policy are dynamic, static and dynamic-priority.
+     * Default: dynamic.
+     */
+    String policy() default "dynamic";
+
+    /**
+     * Set the comparator.
+     * The indicated class must implement {@link Comparator}
+     */
+    Class comparator() default Comparator.class;
+
+    /**
+     * Set the from attribute.
+     */
+    String from() default "";
+
+    /**
+     * Set the required service specification.
+     * This attribute is required for Collection field.
+     */
+    String specification() default "";
+
+    /**
+     * Set to true if the service dependency is injected
+     * as a proxy.
+     * Default: true
+     */
+    boolean proxy() default true;
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceController.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceController.java
new file mode 100644
index 0000000..bd0dd5f
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceController.java
@@ -0,0 +1,43 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation declares a service controller.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.FIELD)
+public @interface ServiceController {
+    
+    /**
+     * Sets the initial value of the controller.
+     */
+    boolean value() default true;
+    
+    
+    /**
+     * Sets the targeted specification.
+     * If not set, target all specifications.
+     */
+    Class specification() default Object.class;
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceProperty.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceProperty.java
new file mode 100644
index 0000000..ceba75f
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/ServiceProperty.java
@@ -0,0 +1,50 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation declares a service property.
+ * It can target both fields and methods.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.FIELD)
+public @interface ServiceProperty {
+    
+    /**
+     * Set the property name.
+     * Default : empty
+     */
+    String name() default "";
+    
+    /**
+     * Set the property value.
+     * Default : empty
+     */
+    String value() default "";
+    
+    /**
+     * Is the property mandatory?
+     * Default: false
+     */
+    boolean mandatory() default false;
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/StaticServiceProperty.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/StaticServiceProperty.java
new file mode 100644
index 0000000..f9ac981
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/StaticServiceProperty.java
@@ -0,0 +1,51 @@
+/*
+ * 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.annotations;
+
+
+/**
+ * This annotation declares a static service property.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public @interface StaticServiceProperty {
+
+    /**
+     * Set the property name.
+     * This name is mandatory for static properties.
+     */
+    String name();
+
+    /**
+     * Set the property value.
+     * Default : empty
+     */
+    String value() default "";
+
+    /**
+     * Is the property mandatory?
+     * Default: false
+     */
+    boolean mandatory() default false;
+
+    /**
+     * Set the type.
+     * This value is required only for static properties.
+     */
+    String type();
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Unbind.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Unbind.java
new file mode 100644
index 0000000..b44ca3b
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Unbind.java
@@ -0,0 +1,81 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+import java.util.Comparator;
+
+/**
+ * This annotation declares an unbind method.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface Unbind {
+    
+    /**
+     * Set the dependency filter.
+     * Default : no filter
+     */
+    String filter() default "";
+    
+    /**
+     * Set if the dependency is an aggregate dependency.
+     * Default : false
+     */
+    boolean aggregate() default false;
+    
+    
+    /**
+     * Set if the dependency is optional.
+     * Default : false
+     */
+    boolean optional() default false;
+    
+    /**
+     * Set the required specification.
+     * Default : empty (try to discover).
+     */
+    String specification() default "";
+    
+    /**
+     * Set the dependency id.
+     * Default : empty.
+     */
+    String id() default "";
+    
+    /**
+     * Set the binding policy.
+     * Acceptable policy are dynamic, static and dynamic-priority.
+     * Default: dynamic.
+     */
+    String policy() default "dynamic";
+    
+    /**
+     * Set the comparator.
+     * The indicated class must implement {@link Comparator}
+     */
+    Class comparator() default Comparator.class;
+    
+    /**
+     * Set the from attribute.
+     */
+    String from() default "";
+    
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Updated.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Updated.java
new file mode 100644
index 0000000..285d236
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Updated.java
@@ -0,0 +1,32 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation declares an updated callback.
+ * Updated callback are called after a reconfiguration.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface Updated {
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Validate.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Validate.java
new file mode 100644
index 0000000..50e239f
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/annotations/Validate.java
@@ -0,0 +1,31 @@
+/* 
+ * 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.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * This annotation declares a validate callback.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface Validate {
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/extender/Extender.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/extender/Extender.java
new file mode 100644
index 0000000..6c1af00
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/extender/Extender.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.felix.ipojo.extender;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Extender pattern Handler annotation.
+ * Allows configuring an extender pattern.
+ * Be aware that despite is it provided in the annotations jar, 
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface Extender {
+    
+    /**
+     * Sets the looked Manifest entry.
+     */
+    String extension();
+    
+    /**
+     * Sets the on service arrival callback.
+     */
+    String onArrival();
+    
+    /**
+     * Sets the on service departure callback.
+     */
+    String onDeparture();
+    
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handler/temporal/Requires.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handler/temporal/Requires.java
new file mode 100644
index 0000000..3e9e03a
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handler/temporal/Requires.java
@@ -0,0 +1,70 @@
+/*
+ * 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.handler.temporal;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Temporal dependency annotation.
+ * Allows specifying a temporal dependency.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * @deprecated replaced by {@link Temporal}
+ */
+@Target(ElementType.FIELD)
+@Deprecated
+public @interface Requires {
+
+    /**
+     * Set the LDAP filter of the dependency.
+     * Default : no filter
+     */
+    String filter() default "";
+
+    /**
+     * Timeout of the dependency.
+     * Default : true
+     */
+    long timeout() default 3000;
+
+    /**
+     * Set the on timeout action.
+     * 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)
+     */
+    String onTimeout() default "";
+
+    /**
+     * Set the service specification (for Collection fields).
+     * This attribute is mandatory for Collections.
+     */
+    String specification() default "";
+
+    /**
+     * Inject a proxy instead of the real object.
+     * This allows passing this reference to collaborators.
+     * Default: false
+     */
+    boolean proxy() default false;
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handler/temporal/Temporal.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handler/temporal/Temporal.java
new file mode 100644
index 0000000..c123cda
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handler/temporal/Temporal.java
@@ -0,0 +1,75 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.handler.temporal;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Temporal dependency annotation.
+ * Allows specifying a temporal dependency.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.FIELD)
+public @interface Temporal {
+
+    /**
+     * Set the dependency id.
+     * Default: empty, will use the field name.
+     */
+    String id() default "";
+
+    /**
+     * Set the LDAP filter of the dependency.
+     * Default: no filter
+     */
+    String filter() default "";
+
+    /**
+     * Timeout of the dependency.
+     * Default: 3000 ms.
+     */
+    long timeout() default 3000;
+
+    /**
+     * Set the on timeout action.
+     * 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)
+     */
+    String onTimeout() default "";
+
+    /**
+     * Set the service specification (for Collection fields).
+     * This attribute is mandatory for Collections.
+     */
+    String specification() default "";
+
+    /**
+     * Inject a proxy instead of the real object.
+     * This allows passing this reference to collaborators.
+     * Default: false
+     */
+    boolean proxy() default false;
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Publisher.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Publisher.java
new file mode 100644
index 0000000..466d6f0
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Publisher.java
@@ -0,0 +1,69 @@
+/*
+ * 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.handlers.event;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+
+/**
+ * Event Admin Publisher handler.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * @deprecated replaced by Publishes
+ */
+@Target(ElementType.FIELD)
+public @interface Publisher {
+
+    /**
+     * Sets the publisher name.
+     */
+    String name();
+
+    /**
+     * Sets topics on which event are sent.
+     * The topics are separated by a ',' such as in
+     * "foo, bar".
+     * Default : no topics (configured in the instance configuration)
+     */
+    String topics() default "";
+
+    /**
+     * Enables/Disables synchronous sending.
+     * Default : false (asynchronous)
+     */
+    boolean synchronous() default false;
+
+    /**
+     * Sets the data key in which the data is
+     * put.
+     * Default : user.data
+     * @deprecated replaced by dataKey
+     */
+    String data_key() default "user.data";
+
+    /**
+     * Sets the data key in which the data is
+     * put.
+     * Default : user.data
+     */
+    String dataKey() default "user.data";
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Publishes.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Publishes.java
new file mode 100644
index 0000000..5102df4
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Publishes.java
@@ -0,0 +1,60 @@
+/*
+ * 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.handlers.event;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+
+/**
+ * Event Admin Publisher handler.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.FIELD)
+public @interface Publishes {
+
+    /**
+     * Sets the publisher name.
+     */
+    String name();
+
+    /**
+     * Sets topics on which event are sent.
+     * The topics are separated by a ',' such as in
+     * "foo, bar".
+     * Default : no topics (configured in the instance configuration)
+     */
+    String topics() default "";
+
+    /**
+     * Enables/Disables synchronous sending.
+     * Default : false (asynchronous)
+     */
+    boolean synchronous() default false;
+
+    /**
+     * Sets the data key in which the data is
+     * put.
+     * Default : user.data
+     */
+    String dataKey() default "user.data";
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Subscriber.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Subscriber.java
new file mode 100644
index 0000000..70cb7a8
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/event/Subscriber.java
@@ -0,0 +1,83 @@
+/*
+ * 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.handlers.event;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+
+/**
+ * Event Admin Subscriber handler.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface Subscriber {
+
+    /**
+     * Sets the subscriber name.
+     */
+    String name();
+
+    /**
+     * Sets topics on which event are received.
+     * The topics are separated by a ',' such as in
+     * "foo, bar".
+     * Default : no topics (configured in the instance configuration)
+     */
+    String topics() default "";
+
+    /**
+     * Sets the data key in which the data is
+     * stored.
+     * Default : no key
+     * @deprecated replaced by dataKey
+     */
+    String data_key() default "";
+
+    /**
+     * Sets the data type (type of the received data).
+     * Default : no type.
+     * @deprecated replaced by dataType
+     */
+    String data_type() default "";
+
+    /**
+     * Sets the data key in which the data is
+     * stored.
+     * Default : no key
+     */
+    String dataKey() default "";
+
+    /**
+     * Sets the data type (type of the received data).
+     * Default : no type.
+     */
+    String dataType() default "";
+
+
+    /**
+     * Sets the event filter. Only event matching with the
+     * specified LDAP filter are received.
+     * default : no filter;
+     */
+    String filter() default "";
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/Config.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/Config.java
new file mode 100644
index 0000000..9a0d5e9
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/Config.java
@@ -0,0 +1,62 @@
+/*
+ * 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.handlers.jmx;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * JMX Handler annotation.
+ * Allows exposing the instances as a JMX MBean.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * @deprecated replaced by {@link JMXBean}
+ */
+@Target(ElementType.TYPE)
+public @interface Config {
+
+    /**
+     * Enables or Disables MOSGi usage.
+     * If MOSGi is used, MBeans are exposed with the MOSGi mechanism.
+     * Otherwise the MBean Platform Server is used.
+     * Default : false
+     */
+    boolean usesMOSGi() default false;
+
+    /**
+     * Sets the MBean object name.
+     * Default : 'package-name:factory-name:instance-name'.
+     */
+    String objectname() default "";
+
+    /**
+     * Sets the MBean domain.
+     * Default : 'package-name'
+     */
+    String domain() default "";
+
+    /**
+     * Sets the MBean name.
+     * Default : 'instance-name'
+     */
+    String name() default "";
+
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXBean.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXBean.java
new file mode 100644
index 0000000..ca31185
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXBean.java
@@ -0,0 +1,61 @@
+/*
+ * 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.handlers.jmx;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * JMX Handler annotation.
+ * Allows exposing the instances as a JMX MBean.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface JMXBean {
+
+    /**
+     * Enables or Disables MOSGi usage.
+     * If MOSGi is used, MBeans are exposed with the MOSGi mechanism.
+     * Otherwise the MBean Platform Server is used.
+     * Default : false
+     */
+    boolean usesMOSGi() default false;
+
+    /**
+     * Sets the MBean object name.
+     * Default : 'package-name:factory-name:instance-name'.
+     */
+    String objectname() default "";
+
+    /**
+     * Sets the MBean domain.
+     * Default : 'package-name'
+     */
+    String domain() default "";
+
+    /**
+     * Sets the MBean name.
+     * Default : 'instance-name'
+     */
+    String name() default "";
+
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXMethod.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXMethod.java
new file mode 100644
index 0000000..27ca89a
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXMethod.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.felix.ipojo.handlers.jmx;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * JMX Method annotation.
+ * Allows exposing methods in the MBean.
+ * This annotation must be used only if the {@link Config} annotation
+ * is used.
+ * Be aware that despite is it provided in the annotations jar, 
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface JMXMethod {
+        
+    /**
+     * Gets the method description.
+     * Default : no description
+     */
+    String description() default "";
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXProperty.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXProperty.java
new file mode 100644
index 0000000..1b31c7c
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/JMXProperty.java
@@ -0,0 +1,55 @@
+/* 
+ * 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.handlers.jmx;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * JMX Property annotation.
+ * Allows exposing properties in the MBean.
+ * This annotation must be used only if the {@link Config} annotation
+ * is used.
+ * Be aware that despite is it provided in the annotations jar, 
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.FIELD)
+public @interface JMXProperty {
+        
+    /**
+     * Sets the property name.
+     */
+    String name();
+    
+    /**
+     * Sets the access permission.
+     * Possible values are 'r' (default) or 'w'.
+     * 'w' implies read and write access.
+     */
+    String rights() default "r";
+    
+    /**
+     * Enables notification on the current property.
+     * Notifications are disable by default.
+     */
+    boolean notification() default false;
+    
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/Method.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/Method.java
new file mode 100644
index 0000000..4fb0cd1
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/Method.java
@@ -0,0 +1,43 @@
+/*
+ * 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.handlers.jmx;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * JMX Method annotation.
+ * Allows exposing methods in the MBean.
+ * This annotation must be used only if the {@link Config} annotation
+ * is used.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * @deprecated replaced by {@link JMXMethod}
+ */
+@Target(ElementType.METHOD)
+public @interface Method {
+
+    /**
+     * Gets the method description.
+     * Default : no description
+     */
+    String description() default "";
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/Property.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/Property.java
new file mode 100644
index 0000000..6de9e83
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/handlers/jmx/Property.java
@@ -0,0 +1,56 @@
+/*
+ * 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.handlers.jmx;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * JMX Property annotation.
+ * Allows exposing properties in the MBean.
+ * This annotation must be used only if the {@link Config} annotation
+ * is used.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * @deprecated replaced by {@link JMXProperty}
+ */
+@Target(ElementType.FIELD)
+public @interface Property {
+
+    /**
+     * Sets the property name.
+     */
+    String name();
+
+    /**
+     * Sets the access permission.
+     * Possible values are 'r' (default) or 'w'.
+     * 'w' implies read and write access.
+     */
+    String rights() default "r";
+
+    /**
+     * Enables notification on the current property.
+     * Notifications are disable by default.
+     */
+    boolean notification() default false;
+
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transaction.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transaction.java
new file mode 100644
index 0000000..c70762c
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transaction.java
@@ -0,0 +1,51 @@
+/* 
+ * 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.transaction;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Transaction Handler annotation.
+ * Allows the declaration of transactionnal methods
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface Transaction {
+
+    /**
+     * Sets the Transaction field. The specified field must be of the type
+     * Transaction.
+     */
+    String field() default "";
+
+    /**
+     * Sets the method called when a transaction is committed.
+     */
+    String oncommit() default "";
+
+    /**
+     * Sets the method called when a transaction is rolled back.
+     */
+    String onrollback() default "";
+
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transactional.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transactional.java
new file mode 100644
index 0000000..ba41f5e
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/transaction/Transactional.java
@@ -0,0 +1,56 @@
+/* 
+ * 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.transaction;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Transactionnal Method annotation.
+ * Allows the declaration of transactionnal method.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.METHOD)
+public @interface Transactional {
+
+    /**
+     * Sets the transaction timeout.
+     */
+    long timeout() default 0;;
+
+    /**
+     * Sets the transaction propagation policy.
+     * Supported values are : requires mandatory, notsupported, never, requiresnew.
+     */
+    String propagation() default "requires";
+
+    /**
+     * Sets the exceptions that do not rollback the current transaction.
+     */
+    String[] norollbackfor() default { };
+
+    /**
+     * Sets if the transaction rollback throws an exception.
+     */
+    boolean exceptiononrollback() default false;
+
+
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Wbp.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Wbp.java
new file mode 100644
index 0000000..570ade1
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Wbp.java
@@ -0,0 +1,54 @@
+/* 
+ * 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.whiteboard;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Whiteboard pattern Handler annotation.
+ * Allows configuring a whiteboard pattern.
+ * Be aware that despite is it provided in the annotations jar, 
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface Wbp {
+    
+    /**
+     * Sets the whiteboard pattern filter.
+     */
+    String filter();
+    
+    /**
+     * Sets the on service arrival callback.
+     */
+    String onArrival();
+    
+    /**
+     * Sets the on service departure callback.
+     */
+    String onDeparture();
+    
+    /**
+     * Sets the on service modification callback.
+     * Default : no callback.
+     */
+    String onModification() default "";
+}
diff --git a/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Whiteboards.java b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Whiteboards.java
new file mode 100644
index 0000000..d00f1b5
--- /dev/null
+++ b/ipojo/runtime/annotations/src/main/java/org/apache/felix/ipojo/whiteboard/Whiteboards.java
@@ -0,0 +1,38 @@
+/*
+ * 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.whiteboard;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/**
+ * Whiteboard pattern Handler annotation.
+ * Allows configuring several whiteboard patterns.
+ * Be aware that despite is it provided in the annotations jar,
+ * it refers to an external handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Target(ElementType.TYPE)
+public @interface Whiteboards {
+
+    /**
+     * Whiteboards list.
+     */
+    Wbp[] whiteboards() default {};
+}
diff --git a/ipojo/runtime/composite/DEPENDENCIES b/ipojo/runtime/composite/DEPENDENCIES
new file mode 100644
index 0000000..d66cccd
--- /dev/null
+++ b/ipojo/runtime/composite/DEPENDENCIES
@@ -0,0 +1,23 @@
+Apache Felix iPOJO Composite
+Copyright 2008-2011 The Apache Software Foundation
+
+This software was developed at the Apache Software Foundation
+(http://www.apache.org) and may have dependencies on other
+Apache software licensed under Apache License 2.0.
+
+I. Included Third-Party Software
+
+This product includes software developed at
+Copyright (c) 2000-2005 INRIA, France Telecom
+Licensed under BSD License.
+
+II. Used Third-Party Software
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2009).
+Licensed under the Apache License 2.0.
+
+III. Overall License Summary
+- Apache License 2.0
+- BSD License
diff --git a/ipojo/runtime/composite/LICENSE b/ipojo/runtime/composite/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/ipojo/runtime/composite/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/runtime/composite/LICENSE.asm b/ipojo/runtime/composite/LICENSE.asm
new file mode 100644
index 0000000..cc529ed
--- /dev/null
+++ b/ipojo/runtime/composite/LICENSE.asm
@@ -0,0 +1,29 @@
+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/runtime/composite/NOTICE b/ipojo/runtime/composite/NOTICE
new file mode 100644
index 0000000..4c77df6
--- /dev/null
+++ b/ipojo/runtime/composite/NOTICE
@@ -0,0 +1,11 @@
+Apache Felix iPOJO Composite
+Copyright 2008-2011 The Apache Software Foundation
+
+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.
+
diff --git a/ipojo/runtime/composite/doc/changelog.txt b/ipojo/runtime/composite/doc/changelog.txt
new file mode 100644
index 0000000..36548c7
--- /dev/null
+++ b/ipojo/runtime/composite/doc/changelog.txt
@@ -0,0 +1,43 @@
+Changes from the 1.6.0 to 1.8.0
+-------------------------------
+** Improvement
+    * [FELIX-2746] - Composite should support instance configuration
+
+Changes from the 1.4.0 to 1.6.0
+-------------------------------
+** Improvement
+    * [FELIX-1427] - Service injection with Smart Proxies
+    * [FELIX-1906] - Allow calling a method when service properties of an already injected service are modified
+
+
+Changes from 1.2.0 to 1.4.0
+---------------------------
+** Bug
+    * [FELIX-994] - ClassCastException while Architecture on a composite with a provided service
+
+** Improvement
+    * Update parent pom
+
+
+Changes from 1.0.0 to 1.2.0
+---------------------------
+** Bug
+    * [FELIX-797] - Composite Architecture contains duplicate instances
+    * [FELIX-817] - iPOJO Service Exported throw an error when stopping
+
+Changes from 0.8.1 to 1.0.0
+---------------------------
+** Bug
+    * [FELIX-622] - iPOJO Composite Service Instance can use factories twice to create service instance
+    * [FELIX-628] - Architecture service should not publish the instance.name property
+    * [FELIX-637] - Composite service implementation does not support long argument
+
+** Improvement
+    * [FELIX-673] - Provide OBR description to iPOJO bundles
+    * [FELIX-688] - Better error reporting when an instance creation failed
+    * [FELIX-689] - Instance 'name' property should become 'instance.name'
+    * [FELIX-716] - Provide XML schemas for iPOJO descriptors
+
+Version 0.8.1
+-------------
+    * Initial release
diff --git a/ipojo/runtime/composite/obr.xml b/ipojo/runtime/composite/obr.xml
new file mode 100644
index 0000000..a39ed25
--- /dev/null
+++ b/ipojo/runtime/composite/obr.xml
@@ -0,0 +1,40 @@
+<!--
+	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.
+-->
+<obr>
+	<capability name="ipojo.handler">
+		<p n="name" v="instance"/>
+		<p n="namespace" v="org.apache.felix.ipojo"/>
+		<p n="type" v="composite"/>
+	</capability>
+	<capability name="ipojo.handler">
+		<p n="name" v="subservice"/>
+		<p n="namespace" v="org.apache.felix.ipojo"/>
+		<p n="type" v="composite"/>
+	</capability>
+	<capability name="ipojo.handler">
+		<p n="name" v="provides"/>
+		<p n="namespace" v="org.apache.felix.ipojo"/>
+		<p n="type" v="composite"/>
+	</capability>
+	<capability name="ipojo.handler">
+		<p n="name" v="architecture"/>
+		<p n="namespace" v="org.apache.felix.ipojo"/>
+		<p n="type" v="composite"/>
+	</capability>
+</obr>
\ No newline at end of file
diff --git a/ipojo/runtime/composite/pom.xml b/ipojo/runtime/composite/pom.xml
new file mode 100644
index 0000000..b4b7573
--- /dev/null
+++ b/ipojo/runtime/composite/pom.xml
@@ -0,0 +1,156 @@
+<!--
+  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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix-parent</artifactId>
+    <version>1.2.1</version>
+    <relativePath>../../../pom/pom.xml</relativePath>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>bundle</packaging>
+  <name>Apache Felix iPOJO Composite</name>
+  <artifactId>org.apache.felix.ipojo.composite</artifactId>
+  <groupId>org.apache.felix</groupId>
+  <version>1.9.0-SNAPSHOT</version>
+
+  <properties>
+    <ipojo.package.version>1.8.0</ipojo.package.version>
+  </properties>
+
+  <description>
+  iPOJO Composition Model. This is an iPOJO extension to execute service composition.
+  </description>
+  <url>http://felix.apache.org/site/ipojo-composition-tutorial.html</url>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>4.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.ipojo.manipulator</artifactId>
+      <version>1.8.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.ipojo</artifactId>
+      <version>1.8.0</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>1.4.3</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Name>Apache Felix iPOJO Composite</Bundle-Name>
+            <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+            <Bundle-Vendor> The Apache Software Foundation </Bundle-Vendor>
+            <Bundle-Description> iPOJO Composititon Framework
+            </Bundle-Description>
+            <Bundle-DocURL>
+             http://felix.apache.org/site/ipojo-composition-tutorial.html
+            </Bundle-DocURL>
+            <Import-Package>
+              org.apache.felix.ipojo,
+              org.apache.felix.ipojo.architecture,
+              org.apache.felix.ipojo.context,
+              org.apache.felix.ipojo.metadata,
+              org.apache.felix.ipojo.parser,
+              org.apache.felix.ipojo.util,
+              org.apache.felix.ipojo.manipulation,
+              org.osgi.framework;version=1.3,
+              !org.objectweb.asm.tree,
+            </Import-Package>
+            <Private-Package>
+              org.apache.felix.ipojo.composite.architecture,
+              org.apache.felix.ipojo.composite.service*,
+              org.apache.felix.ipojo.composite.instance,
+              org.apache.felix.ipojo.composite.util,
+                <!-- ASM (Manipulator dependencies) -->
+              org.objectweb.asm.commons,
+              org.objectweb.asm.signature,
+              org.objectweb.asm
+            </Private-Package>
+            <Export-Package>
+              org.apache.felix.ipojo.composite; version="${ipojo.package.version}"
+            </Export-Package>
+            <Include-Resource>
+              META-INF/LICENSE=LICENSE,
+              META-INF/NOTICE=NOTICE,
+              META-INF/LICENSE.asm=LICENSE.asm,
+              META-INF/DEPENDENCIES=DEPENDENCIES
+            </Include-Resource>
+            <IPOJO-Extension>
+              composite:org.apache.felix.ipojo.composite.CompositeFactory
+            </IPOJO-Extension>
+            <_donotcopy> (CVS|.svn|.+.bak|~.+|metadata.xml) </_donotcopy>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-ipojo-plugin</artifactId>
+        <version>1.8.0</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>ipojo-bundle</goal>
+            </goals>
+            <configuration>
+              <metadata>src/main/resources/metadata.xml</metadata>
+              <ignoreAnnotations>true</ignoreAnnotations>
+            </configuration>
+          </execution>
+        </executions>
+      </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>
+          </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>
+</project>
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java
new file mode 100644
index 0000000..d739de5
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeFactory.java
@@ -0,0 +1,181 @@
+/* 
+ * 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.composite;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.HandlerManager;
+import org.apache.felix.ipojo.IPojoContext;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * The component factory manages component instance objects. This management
+ * consist in creating and managing component instance build with the component
+ * factory. This class could export Factory and ManagedServiceFactory services.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CompositeFactory extends ComponentFactory implements TrackerCustomizer {
+
+    /**
+     * Tracker used to track required handler factories.
+     */
+    protected Tracker m_tracker;
+
+    /**
+     * Create a composite factory.
+     * @param context : bundle context
+     * @param metadata : metadata of the component to create
+     * @throws ConfigurationException occurs when the element describing the factory is malformed.
+     */
+    public CompositeFactory(BundleContext context, Element metadata) throws ConfigurationException {
+        super(context, metadata);
+    }
+    
+    /**
+     * Check if the metadata are well formed.
+     * @param metadata : metadata
+     * @throws ConfigurationException occurs when the element describing the factory is malformed.
+     * @see org.apache.felix.ipojo.ComponentFactory#check(org.apache.felix.ipojo.metadata.Element)
+     */
+    public void check(Element metadata) throws ConfigurationException {
+        String name = metadata.getAttribute("name");
+        if (name == null) {
+            throw new ConfigurationException("A composite needs a name : " + metadata);
+        }
+    }
+    
+    public String getClassName() { return "composite"; }
+        
+    
+    /**
+     * Compute required handlers.
+     * @return the list of required handler.
+     */
+    public List getRequiredHandlerList() {
+        List list = new ArrayList();
+        Element[] elems = m_componentMetadata.getElements();
+        for (int i = 0; i < elems.length; i++) {
+            Element current = elems[i]; 
+            RequiredHandler req = new RequiredHandler(current.getName(), current.getNameSpace());
+            if (! list.contains(req)) { list.add(req); }
+        }
+        
+        // Add architecture if architecture != 'false'
+        String arch = m_componentMetadata.getAttribute("architecture");
+        if (arch == null || arch.equalsIgnoreCase("true")) {
+            RequiredHandler req = new RequiredHandler("architecture", null);
+            if (! list.contains(req)) { list.add(req); }
+        }
+        
+        return list;
+    }
+    
+    /**
+     * Stop all the instance managers.
+     */
+    public synchronized void stopping() {
+        if (m_tracker != null) {
+            m_tracker.close();
+        }
+        m_tracker = null;
+    }
+
+    /**
+     * Start all the instance managers.
+     */
+    public synchronized void starting() {
+        if (m_requiredHandlers.size() != 0) {
+            try {
+                String filter = "(&(" + Constants.OBJECTCLASS + "=" + HandlerFactory.class.getName() + ")"
+                    + "(" + Handler.HANDLER_TYPE_PROPERTY + "=" + CompositeHandler.HANDLER_TYPE + ")" 
+                    + "(factory.state=1)"
+                    + ")";
+                m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);
+                m_tracker.open();
+            } catch (InvalidSyntaxException e) {
+                m_logger.log(Logger.ERROR, "A factory filter is not valid: " + e.getMessage());
+                stop();
+                return;
+            }
+        }
+    }
+    
+    /**
+     * Create an instance from the current factory.
+     * @param configuration : instance configuration
+     * @param context : bundle context to inject in the instance manager
+     * @param handlers : array of handler object to attached on the instance 
+     * @return the created instance
+     * @throws ConfigurationException either the instance configuration or the instance starting has failed 
+     * @see org.apache.felix.ipojo.ComponentFactory#createInstance(java.util.Dictionary, org.apache.felix.ipojo.IPojoContext, org.apache.felix.ipojo.HandlerManager[])
+     */
+    public ComponentInstance createInstance(Dictionary configuration, IPojoContext context, HandlerManager[] handlers) throws ConfigurationException {
+        CompositeManager inst = new CompositeManager(this, context, handlers);
+        inst.configure(m_componentMetadata, configuration);
+        inst.start();
+        return inst;
+    }
+
+    /**
+     * Reconfigure an existing instance.
+     * @param properties : the new configuration to push.
+     * @throws UnacceptableConfiguration : occurs if the new configuration is
+     * not consistent with the component type.
+     * @throws MissingHandlerException : occurs when an handler is unavailable when creating the instance.
+     * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
+     */
+    public synchronized void reconfigure(Dictionary properties) throws UnacceptableConfiguration, MissingHandlerException {
+        if (properties == null || (properties.get("instance.name") == null && properties.get("name") == null)) { // Support both instance.name and name
+            throw new UnacceptableConfiguration("The configuration does not contains the \"instance.name\" property");
+        }
+
+        String name = (String) properties.get("instance.name");
+        if (name == null) {
+            name = (String) properties.get("name");
+        }
+
+        ComponentInstance instance = (ComponentInstance) m_componentInstances.get(name);
+        if (instance == null) { // The instance does not exists.
+            return;
+        }
+
+        instance.reconfigure(properties); // re-configure the component
+    }
+
+    public String getFactoryName() {
+        return m_componentMetadata.getAttribute("name"); // Mandatory attribute.
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java
new file mode 100644
index 0000000..4194fed
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeHandler.java
@@ -0,0 +1,83 @@
+/* 
+ * 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.composite;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.util.Logger;
+
+
+/**
+ * Composite Handler Abstract Class. An composite handler need implements these
+ * method to be notified of lifecycle change...
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class CompositeHandler extends Handler {
+    
+    /**
+     * Composite Handler type.
+     */
+    public static final String HANDLER_TYPE = "composite";
+    
+    /**
+     * Reference on the composite manager.
+     */
+    private CompositeManager m_manager;
+    
+    /**
+     * Composite Factory.
+     */
+    private CompositeFactory m_factory;
+    
+    /**
+     * Set the manager.
+     * This method me be called only once time.
+     * @param instance : the composite manager.
+     */
+    protected final void attach(ComponentInstance instance) {
+        m_manager = (CompositeManager) instance;
+    }
+    
+    public final void setFactory(Factory factory) {
+        m_factory = (CompositeFactory) factory;
+    }
+    
+    public final Logger getLogger() {
+        return m_factory.getLogger();
+    }
+    
+    public final CompositeManager getCompositeManager() {
+        return m_manager;
+    }
+    
+    /**
+     * Get a plugged handler of the same container.
+     * This method must be call only in the start method (or after).
+     * In the configure method, this method can not return a consistent
+     * result as all handlers are not plugged. 
+     * @param name : name of the handler to find (class name). 
+     * @return the composite handler object or null if the handler is not found.
+     */
+    public final Handler getHandler(String name) {
+        return m_manager.getCompositeHandler(name);
+    }
+    
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java
new file mode 100644
index 0000000..f451686
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeInstanceDescription.java
@@ -0,0 +1,129 @@
+/* 
+ * 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.composite;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+
+/**
+ * Composite Instance Description.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CompositeInstanceDescription extends InstanceDescription {
+    
+    /**
+     * Creates a Primitive Instance Description.
+     * @param type the component type description
+     * @param instance the instance description
+     */
+    public CompositeInstanceDescription(ComponentTypeDescription type, CompositeManager instance) {
+        super(type, instance);
+    }
+
+
+    /**
+     * Gets the list of contained instance in the describe instance.
+     * This list contains only instances who exposed their architecture.
+     * @return the list of contained instances.
+     */
+    public InstanceDescription[] getContainedInstances() {
+        // Get instances description of internal instance
+        ServiceContext internal = ((CompositeManager) m_instance).getServiceContext();
+        try {
+            ServiceReference[]refs = internal.getServiceReferences(Architecture.class.getName(), null);
+            if (refs != null) {
+                InstanceDescription[] descs = new InstanceDescription[refs.length];
+                for (int i = 0; i < refs.length; i++) {
+                    Architecture arch = (Architecture) internal.getService(refs[i]);
+                    descs[i] = arch.getInstanceDescription();
+                    internal.ungetService(refs[i]);
+                }
+                return descs;
+            }
+        } catch (InvalidSyntaxException e) {
+            // Cannot happen
+        }
+        return new InstanceDescription[0];
+    }
+
+    /**
+     * Gets the list of internally published services.
+     * @return the list of published services.
+     */
+    public Element getInternalServices() {
+        Element services = new Element("services", "");
+        ServiceContext internal = ((CompositeManager) m_instance)
+                .getServiceContext();
+        try {
+            ServiceReference[] refs = internal.getServiceReferences(null, "(!(objectclass=" + Factory.class.getName() + "))");
+            for (int i = 0; refs != null && i < refs.length; i++) {
+                Element svc = new Element("service", "");
+                String[] keys = refs[i].getPropertyKeys();
+                for (int j = 0; j < keys.length; j++) {
+                    Object v = refs[i].getProperty(keys[j]);
+                    if (v instanceof String[]) {
+                        List l = Arrays.asList((String[]) v);
+                        svc.addAttribute(new Attribute(keys[j], l.toString()));
+                    } else {
+                        svc.addAttribute(new Attribute(keys[j], v.toString()));
+                    }
+                }
+                services.addElement(svc);
+            }
+
+        } catch (InvalidSyntaxException e) {
+            // Cannot happen
+        }
+        return services;
+    }
+    
+    /**
+     * Gets the instance description.
+     * Overridden to add created objects.
+     * @return the instance description
+     */
+    public Element getDescription() {
+        Element elem = super.getDescription();
+        elem.addElement(getInternalServices());
+
+        InstanceDescription[] descs = getContainedInstances();
+        if (descs.length > 0) {
+            Element inst = new Element("ContainedInstances", "");
+            for (int i = 0; i < descs.length; i++) {
+                inst.addElement(descs[i].getDescription());
+            }
+            elem.addElement(inst);
+        }
+        
+        return elem;
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeManager.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeManager.java
new file mode 100644
index 0000000..1fe3a10
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeManager.java
@@ -0,0 +1,442 @@
+/* 
+ * 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.composite;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.HandlerManager;
+import org.apache.felix.ipojo.IPojoContext;
+import org.apache.felix.ipojo.InstanceStateListener;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.BundleContext;
+
+/**
+ * iPOJO Composite manager. The composite manager class manages one instance of
+ * a component type which is a composition. It manages component lifecycle, and
+ * handlers...
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CompositeManager implements ComponentInstance, InstanceStateListener {
+
+    /**
+     * The context of the component.
+     */
+    private final BundleContext m_context;
+
+    /**
+     * Parent factory (ComponentFactory).
+     */
+    private final CompositeFactory m_factory;
+
+    /**
+     * Composite Handler list.
+     */
+    private HandlerManager[] m_handlers;
+
+    /**
+     * Instance State Listener List.
+     */
+    private List m_listeners = new ArrayList();
+
+    /**
+     * Internal service context of the composition.
+     */
+    private CompositeServiceContext m_internalContext;
+    
+    /**
+     * The instance description.
+     */
+    private final CompositeInstanceDescription m_description;
+    
+    /**
+     * Name of the component instance.
+     */
+    private String m_name;
+
+    /**
+     * Component state (STOPPED at the beginning).
+     */
+    private int m_state = STOPPED;
+
+    /**
+     * Logger.
+     */
+    private Logger m_logger;
+
+    /**
+     * Construct a new Component Manager.
+     * @param factory : the factory managing the instance manager
+     * @param context : the bundle context to give to the instance
+     * @param handlers : the handlers to plug
+     */
+    public CompositeManager(CompositeFactory factory, BundleContext context, HandlerManager[] handlers) {
+        m_factory = factory;
+        m_context = context;
+        // Initialize the service context.
+        m_internalContext = new CompositeServiceContext(m_context, this);
+        m_handlers = handlers;
+        m_description = new CompositeInstanceDescription(m_factory.getComponentDescription(), this);
+        m_logger = new Logger(m_context, this);
+
+    }
+
+    /**
+     * Plug the given handler to the current container.
+     * @param handler : the handler to plug.
+     */
+    public synchronized void addCompositeHandler(HandlerManager handler) {
+        if (m_handlers.length > 0) {
+            HandlerManager[] newInstances = new HandlerManager[m_handlers.length + 1];
+            System.arraycopy(m_handlers, 0, newInstances, 0, m_handlers.length);
+            newInstances[m_handlers.length] = handler;
+            m_handlers = newInstances;
+        } else {
+            m_handlers = new HandlerManager[] { handler };
+        }
+    }
+
+    /**
+     * Add an instance to the created instance list.
+     * @param listener : the instance state listener to add.
+     * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
+     */
+    public void addInstanceStateListener(InstanceStateListener listener) {
+        synchronized (m_listeners) {
+            m_listeners.add(listener);
+        }
+    }
+
+    /**
+     * Configure the instance manager. Stop the existing handler, clear the
+     * handler list, change the metadata, recreate the handler
+     * 
+     * @param metadata : the component type metadata
+     * @param configuration : the configuration of the instance
+     * @throws ConfigurationException : occurs when the component type are incorrect.
+     */
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {        
+        // Add the name
+        m_name = (String) configuration.get("instance.name");
+        
+        // Create the standard handlers and add these handlers to the list
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].init(this, metadata, configuration);
+        }
+    }
+    
+    /** 
+     * Dispose the instance.
+     * @see org.apache.felix.ipojo.ComponentInstance#dispose()
+     */
+    public void dispose() {
+        if (m_state > STOPPED) { stop(); }
+        
+        for (int i = 0; i < m_listeners.size(); i++) {
+            ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, DISPOSED);
+        }
+        
+        m_factory.disposed(this);
+
+        // Cleaning
+        m_state = DISPOSED;
+        for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].dispose();
+        }
+        m_handlers = new HandlerManager[0];
+        m_listeners.clear();
+    }
+
+    /**
+     * Return a specified handler.
+     * @param name : class name of the handler to find
+     * @return : the handler, or null if not found
+     */
+    public CompositeHandler getCompositeHandler(String name) {
+        for (int i = 0; i < m_handlers.length; i++) {
+            HandlerFactory fact = (HandlerFactory) m_handlers[i].getFactory();
+            if (fact.getHandlerName().equals(name) || fact.getComponentDescription().getClassName().equals(name)) {
+                return (CompositeHandler) m_handlers[i].getHandler();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get the bundle context used by this instance.
+     * @return the parent context of the instance.
+     * @see org.apache.felix.ipojo.ComponentInstance#getContext()
+     */
+    public BundleContext getContext() {
+        return m_context;
+    }
+
+    /**
+     * Get the factory which create this instance.
+     * @return the factory of the component
+     * @see org.apache.felix.ipojo.ComponentInstance#getFactory()
+     */
+    public ComponentFactory getFactory() {
+        return m_factory;
+    }
+    
+    /**
+     * Get the global bundle context.
+     * @return the global bundle context.
+     */
+    public BundleContext getGlobalContext() {
+        IPojoContext context = (IPojoContext) m_context;
+        return context.getGlobalContext();
+    }
+    
+    /**
+     * Return the instance description of this instance.
+     * @return the instance description.
+     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceDescription()
+     */
+    public InstanceDescription getInstanceDescription() {
+        return m_description;
+    }
+
+    /**
+     * Get the instance name.
+     * @return the instance name
+     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
+     */
+    public String getInstanceName() {
+        return m_name;
+    }
+
+    /**
+     * Get the parent service context.
+     * @return the parent service context.
+     */
+    public ServiceContext getParentServiceContext() {
+        IPojoContext context = (IPojoContext) m_context;
+        return context.getServiceContext();
+    }
+
+    /**
+     * REturn the list of handlers plugged on this instance.
+     * @return the list of the registered handlers.
+     */
+    public CompositeHandler[] getRegistredCompositeHandlers() {
+        CompositeHandler[] handler = new CompositeHandler[m_handlers.length];
+        for (int i = 0; i < m_handlers.length; i++) {
+            handler[i] = (CompositeHandler) m_handlers[i].getHandler();
+        }
+        return handler;
+    }
+    
+    /**
+     * Get the internal service context of this instance.
+     * @return the internal service context.
+     */
+    public ServiceContext getServiceContext() {
+        return m_internalContext;
+    }
+    
+    /**
+     * Get the actual state of the instance.
+     * @return the actual state of the instance
+     * @see org.apache.felix.ipojo.ComponentInstance#getState()
+     */
+    public int getState() {
+        return m_state;
+    }
+    
+    /**
+     * Check if the instance is started.
+     * @return true if the instance is started.
+     * @see org.apache.felix.ipojo.ComponentInstance#isStarted()
+     */
+    public boolean isStarted() {
+        return m_state > STOPPED;
+    }
+
+    /**
+     * Reconfigure the current instance.
+     * @param configuration : the new instance configuration.
+     * @see org.apache.felix.ipojo.ComponentInstance#reconfigure(java.util.Dictionary)
+     */
+    public void reconfigure(Dictionary configuration) {
+        m_logger.log(Logger.INFO, "Reconfiguring composite with " + configuration);
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_logger.log(Logger.INFO, "Delegating reconfiguration to " + m_handlers[i].getClassName());
+            m_handlers[i].getHandler().reconfigure(configuration);
+        }
+    }
+
+    /**
+     * Remove an instance state listener.
+     * @param listener : the listener to remove
+     * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
+     */
+    public void removeInstanceStateListener(InstanceStateListener listener) {
+        synchronized (m_listeners) {
+            m_listeners.remove(listener);
+        }
+    }
+
+    /**
+     * Set the state of the component. 
+     * if the state changed call the stateChanged(int) method on the handlers.
+     * @param state : new state
+     */
+    public void setState(int state) {
+        if (m_state != state) {
+            if (state > m_state) {
+                // The state increases (Stopped = > IV, IV => V) => invoke handlers from the higher priority to the lower
+                m_state = state;
+                for (int i = 0; i < m_handlers.length; i++) {
+                    m_handlers[i].getHandler().stateChanged(state);
+                }
+            } else {
+                // The state decreases (V => IV, IV = > Stopped, Stopped => Disposed)
+                m_state = state;
+                for (int i = m_handlers.length - 1; i > -1; i--) {
+                    m_handlers[i].getHandler().stateChanged(state);
+                }
+            }
+            
+            for (int i = 0; i < m_listeners.size(); i++) {
+                ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, state);
+            }
+        }
+    }
+
+    /**
+     * Start the instance manager.
+     */
+    public synchronized void start() {
+        if (m_state > STOPPED) {
+            return;
+        } // Instance already started
+
+
+        // The new state of the component is UNRESOLVED
+        m_state = INVALID;
+
+        m_internalContext.start(); // Turn on the factory tracking
+        
+        // Plug handler descriptions
+        Handler[] handlers = getRegistredCompositeHandlers();
+        for (int i = 0; i < handlers.length; i++) {
+            m_description.addHandler(handlers[i].getDescription());
+        }
+
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].start();
+            m_handlers[i].addInstanceStateListener(this);
+        }
+        
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i].getState() != VALID) {
+                setState(INVALID);
+                return;
+            }
+        }
+        setState(VALID);
+        
+    }
+
+    /**
+     * State Change listener callback.
+     * This method is notified at each time a plugged handler becomes invalid.
+     * @param instance : changing instance 
+     * @param newState : new state
+     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
+     */
+    public synchronized void stateChanged(ComponentInstance instance, int newState) {
+        if (m_state <= STOPPED) { return; }
+     
+        // Update the component state if necessary
+        if (newState == INVALID && m_state == VALID) {
+            // Need to update the state to UNRESOLVED
+            setState(INVALID);
+            return;
+        }
+        if (newState == VALID && m_state == INVALID) {
+            // An handler becomes valid => check if all handlers are valid
+            boolean isValid = true;
+            for (int i = 0; i < m_handlers.length; i++) {
+                isValid = isValid && m_handlers[i].getState() == VALID;
+            }
+            
+            if (isValid) { setState(VALID); }
+        }
+        if (newState == DISPOSED) {
+            kill();
+        }
+    }
+
+    /**
+     * Stop the instance manager.
+     */
+    public synchronized void stop() {
+        if (m_state <= STOPPED) {
+            return;
+        } // Instance already stopped
+
+        setState(INVALID);
+        // Stop all the handlers
+        for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].removeInstanceStateListener(this);
+            m_handlers[i].stop();
+        }
+
+        m_internalContext.stop(); // Turn off the factory tracking
+        m_state = STOPPED;
+        
+        for (int i = 0; i < m_listeners.size(); i++) {
+            ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, STOPPED);
+        }
+    }
+    
+    /**
+     * Kill the current instance.
+     * Only the factory of this instance can call this method.
+     */
+    protected synchronized void kill() {
+        if (m_state > STOPPED) { stop(); }
+        
+        for (int i = 0; i < m_listeners.size(); i++) {
+            ((InstanceStateListener) m_listeners.get(i)).stateChanged(this, DISPOSED);
+        }
+
+        // Cleaning
+        m_state = DISPOSED;
+        
+        for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].dispose();
+        }
+        m_handlers = new HandlerManager[0];
+        m_listeners.clear();
+    }
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
new file mode 100644
index 0000000..5bdc75e
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/CompositeServiceContext.java
@@ -0,0 +1,487 @@
+/* 
+ * 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.composite;
+
+import java.io.File;
+import java.io.InputStream;
+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.Factory;
+import org.apache.felix.ipojo.IPojoContext;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.context.ServiceReferenceImpl;
+import org.apache.felix.ipojo.context.ServiceRegistry;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * CompositeServiceContext Class. This class provides an implementation of the
+ * service context for composite.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CompositeServiceContext implements ServiceContext, TrackerCustomizer {
+
+    /**
+     * Structure storing the reference, the factory and the registration.
+     */
+    private class Record {
+        /**
+         * Reference of the represented factory from the external context.
+         */
+        private ServiceReference m_ref;
+        /**
+         * Registration of the factory in the internal context.
+         */
+        private ServiceRegistration m_reg;
+        /**
+         * Represented Factory. 
+         */
+        private FactoryProxy m_fact;
+    }
+
+    /**
+     * List of imported factories.
+     */
+    private List m_factories = new ArrayList();
+    /**
+     * Internal service registry.
+     */
+    private ServiceRegistry m_registry;
+
+    /**
+     * Component Instance who creates this registry.
+     */
+    private ComponentInstance m_instance;
+    
+    /**
+     * Global service context.
+     */
+    private BundleContext m_global;
+    
+    /**
+     * Tracker tracking Factories to import.
+     */
+    private Tracker m_tracker;
+
+    /**
+     * Constructor. This constructor instantiate a service registry with the
+     * given bundle context.
+     * 
+     * @param context : the bundle context
+     */
+    public CompositeServiceContext(BundleContext context) {
+        m_registry = new ServiceRegistry(context);
+        if (context instanceof IPojoContext) {
+            m_global = ((IPojoContext) context).getGlobalContext();
+        } else {
+            m_global = context; // the parent context is the global context
+        }
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param context : the bundle context
+     * @param instance : the component instance owning this context
+     */
+    public CompositeServiceContext(BundleContext context, ComponentInstance instance) {
+        this(context);
+        m_instance = instance;
+    }
+
+    /**
+     * Add a service listener.
+     * @param arg0 : The service listener to add
+     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener)
+     */
+    public void addServiceListener(ServiceListener arg0) {
+        m_registry.addServiceListener(arg0);
+    }
+
+    /**
+     * Add a filtered service listener.
+     * @param arg0 : the service listener object to add
+     * @param arg1 : the LDAP filter for this listener
+     * @throws InvalidSyntaxException : occurs if the LDAP filter is malformed
+     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener,
+     * java.lang.String)
+     */
+    public void addServiceListener(ServiceListener arg0, String arg1) throws InvalidSyntaxException {
+        m_registry.addServiceListener(arg0, arg1);
+    }
+
+    /**
+     * Get all service references.
+     * @param arg0 : The required service interface.
+     * @param arg1 : LDAP filter
+     * @return the list of all service reference matching with the query
+     * @throws InvalidSyntaxException : occurs when the given filter is malformed
+     * @see org.apache.felix.ipojo.ServiceContext#getAllServiceReferences(java.lang.String,
+     * java.lang.String)
+     */
+    public ServiceReference[] getAllServiceReferences(String arg0, String arg1) throws InvalidSyntaxException {
+        return m_registry.getAllServiceReferences(arg0, arg1);
+    }
+
+    /**
+     * Get a service object for the given service reference.
+     * @param arg0 : the service reference
+     * @return the service object or null if the reference is no more valid or if the object is not accessible
+     * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)
+     */
+    public Object getService(ServiceReference arg0) {
+        if (arg0 instanceof ServiceReferenceImpl) {
+            return m_registry.getService(m_instance, arg0);
+        } else {
+            throw new RuntimeException("Cannot get a global service from the local registry");
+        }
+    }
+
+    
+    /**
+     * Get a service reference for the required interface.
+     * @param arg0 : the required interface name
+     * @return the service reference or null if no available provider
+     * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
+     */
+    public ServiceReference getServiceReference(String arg0) {
+        return m_registry.getServiceReference(arg0);
+    }
+
+    /**
+     * Get all accessible service reference for the given query.
+     * @param clazz : required interface
+     * @param filter : LDAP filter
+     * @return the list (array) of service reference matching with the query.
+     * @throws InvalidSyntaxException : occurs when the LDAP filter is malformed
+     * @see org.apache.felix.ipojo.ServiceContext#getServiceReferences(java.lang.String, java.lang.String)
+     */
+    public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+        return m_registry.getServiceReferences(clazz, filter);
+    }
+
+
+    /**
+     * Register a service inside the composite context.
+     * @param arg0 : list of interfaces to register.
+     * @param arg1 : service object
+     * @param arg2 : properties list
+     * @return the service registration
+     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
+     */
+    public ServiceRegistration registerService(String[] arg0, Object arg1, Dictionary arg2) {
+        return m_registry.registerService(m_instance, arg0, arg1, arg2);
+    }
+
+    /**
+     * Register a service inside the composite context.
+     * @param arg0 : interface to register.
+     * @param arg1 : service object
+     * @param arg2 : properties list
+     * @return the service registration
+     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
+     */
+    public ServiceRegistration registerService(String arg0, Object arg1, Dictionary arg2) {
+        return m_registry.registerService(m_instance, arg0, arg1, arg2);
+    }
+
+    /**
+     * Remove a service listener.
+     * @param arg0 : the service listener to remove
+     * @see org.apache.felix.ipojo.ServiceContext#removeServiceListener(org.osgi.framework.ServiceListener)
+     */
+    public void removeServiceListener(ServiceListener arg0) {
+        m_registry.removeServiceListener(arg0);
+    }
+
+    /**
+     * Unget a service.
+     * @param arg0 the service reference to unget
+     * @return true
+     * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)
+     */
+    public boolean ungetService(ServiceReference arg0) {
+        return m_registry.ungetService(m_instance, arg0);
+    }
+
+    /**
+     * Import a factory form the parent to the internal registry.
+     * 
+     * @param ref : the reference of the factory to import.
+     */
+    private void importFactory(ServiceReference ref) {        
+        Record rec = new Record();
+        m_factories.add(rec);
+        Dictionary dict = new Properties();
+        for (int j = 0; j < ref.getPropertyKeys().length; j++) {
+            dict.put(ref.getPropertyKeys()[j], ref.getProperty(ref.getPropertyKeys()[j]));
+        }
+        rec.m_fact = new FactoryProxy((Factory) m_tracker.getService(ref), this);
+        rec.m_reg = registerService(Factory.class.getName(), rec.m_fact, dict);
+        rec.m_ref = ref;
+    }
+
+    /**
+     * Remove a factory of the available factory list.
+     * 
+     * @param ref : the reference on the factory to remove.
+     */
+    private void removeFactory(ServiceReference ref) {
+        for (int i = 0; i < m_factories.size(); i++) {
+            Record rec = (Record) m_factories.get(i);
+            if (rec.m_ref == ref) {
+                if (rec.m_reg != null) {
+                    rec.m_reg.unregister();
+                    rec.m_fact = null;
+                }
+                m_tracker.ungetService(rec.m_ref);
+                m_factories.remove(rec);
+                return;
+            }
+        }
+    }
+
+    /**
+     * Start the registry management.
+     */
+    public void start() {
+        m_tracker = new Tracker(m_global, Factory.class.getName(), this);
+        m_tracker.open();
+    }
+
+    /**
+     * Stop the registry management.
+     */
+    public synchronized void stop() {
+        m_tracker.close();
+        m_registry.reset();
+        for (int i = 0; i < m_factories.size(); i++) {
+            Record rec = (Record) m_factories.get(i);
+            removeFactory(rec.m_ref);
+        }
+        m_tracker = null;
+    }
+
+    /**
+     * Check if the factory list contain the given reference.
+     * 
+     * @param ref : the reference to find.
+     * @return true if the list contains the given reference.
+     */
+    private boolean containsRef(ServiceReference ref) {
+        for (int i = 0; i < m_factories.size(); i++) {
+            Record rec = (Record) m_factories.get(i);
+            if (rec.m_ref == ref) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Add a bundle listener.
+     * Delegate on the global bundle context.
+     * @param arg0 : bundle listener to add
+     * @see org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void addBundleListener(BundleListener arg0) {
+        m_global.addBundleListener(arg0);
+    }
+
+    /**
+     * Add a framework listener.
+     * Delegate on the global bundle context.
+     * @param arg0 : framework listener to add.
+     * @see org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void addFrameworkListener(FrameworkListener arg0) {
+        m_global.addFrameworkListener(arg0);
+    }
+
+    /**
+     * Create a LDAP filter.
+     * @param arg0 : String-form of the filter
+     * @return the created filter object
+     * @throws InvalidSyntaxException : if the given argument is not a valid against the LDAP grammar.
+     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
+     */
+    public Filter createFilter(String arg0) throws InvalidSyntaxException {
+        return m_global.createFilter(arg0);
+    }
+
+    /**
+     * Get the current bundle.
+     * @return the current bundle
+     * @see org.osgi.framework.BundleContext#getBundle()
+     */
+    public Bundle getBundle() {
+        return m_global.getBundle();
+    }
+
+    /**
+     * Get the bundle object with the given id.
+     * @param bundleId : bundle id
+     * @return the bundle object
+     * @see org.osgi.framework.BundleContext#getBundle(long)
+     */
+    public Bundle getBundle(long bundleId) {
+        return m_global.getBundle(bundleId);
+    }
+
+    /**
+     * Get installed bundles.
+     * @return the list of installed bundles
+     * @see org.osgi.framework.BundleContext#getBundles()
+     */
+    public Bundle[] getBundles() {
+        return m_global.getBundles();
+    }
+
+
+    /**
+     * Get a data file.
+     * @param filename : File name.
+     * @return the File object
+     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
+     */
+    public File getDataFile(String filename) {
+        return m_global.getDataFile(filename);
+    }
+
+    /**
+     * Get a property value.
+     * @param key : key of the asked property
+     * @return the property value (object) or null if no property are associated with the given key
+     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
+     */
+    public String getProperty(String key) {
+        return m_global.getProperty(key);
+    }
+
+    /**
+     * Install a bundle.
+     * @param location : URL of the bundle to install
+     * @return the installed bundle
+     * @throws BundleException : if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
+     */
+    public Bundle installBundle(String location) throws BundleException {
+        return m_global.installBundle(location);
+    }
+
+    /**
+     * Install a bundle.
+     * @param location : URL of the bundle to install
+     * @param input : 
+     * @return the installed bundle
+     * @throws BundleException : if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, java.io.InputStream)
+     */
+    public Bundle installBundle(String location, InputStream input) throws BundleException {
+        return m_global.installBundle(location, input);
+    }
+
+    /**
+     * Remove a bundle listener.
+     * @param listener : the listener to remove
+     * @see org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void removeBundleListener(BundleListener listener) {
+        m_global.removeBundleListener(listener);
+    }
+
+    /**
+     * Remove a framework listener.
+     * @param listener : the listener to remove
+     * @see org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void removeFrameworkListener(FrameworkListener listener) {
+        m_global.removeFrameworkListener(listener);
+    }
+
+    /**
+     * A new factory is detected.
+     * @param reference : service reference
+     * @return true if not already imported.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference reference) {
+        if (!containsRef(reference)) {
+            return true;
+        }
+        return false;
+    }
+    
+    /**
+     * A matching reference has been added. The import factory can now be imported.
+     * @param reference : the added reference.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public void addedService(ServiceReference reference) {
+        importFactory(reference);
+    }
+
+    /**
+     * An imported factory is modified.
+     * @param reference : modified reference
+     * @param service : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) {
+        for (int i = 0; i < m_factories.size(); i++) {
+            Record rec = (Record) m_factories.get(i);
+            if (rec.m_ref == reference) {
+                Dictionary dict = new Properties();
+                for (int j = 0; j < reference.getPropertyKeys().length; j++) {
+                    dict.put(reference.getPropertyKeys()[j], reference.getProperty(reference.getPropertyKeys()[j]));
+                }
+                rec.m_reg.setProperties(dict);
+                return;
+            }
+        }
+    }
+
+    /**
+     * An imported factory disappears.
+     * @param reference : reference
+     * @param service : factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        if (containsRef(reference)) {
+            removeFactory(reference);
+        }
+        
+    }
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
new file mode 100644
index 0000000..db3a053
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/FactoryProxy.java
@@ -0,0 +1,177 @@
+/* 
+ * 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.composite;
+
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.FactoryStateListener;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Bridge representing a Factory inside a composition.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FactoryProxy implements Factory {
+
+    /**
+     * Delegated factory.
+     */
+    private Factory m_delegate;
+
+    /**
+     * Destination context.
+     */
+    private ServiceContext m_context;
+
+    /**
+     * Constructor.
+     * @param fact : the targeted factory.
+     * @param svcContext : the service context to target.
+     */
+    public FactoryProxy(Factory fact, ServiceContext svcContext) {
+        m_delegate = fact;
+        m_context = svcContext;
+    }
+
+    /**
+     * Create an instance manager (i.e. component type instance).
+     * @param configuration : the configuration properties for this component.
+     * @return the created instance manager.
+     * @throws UnacceptableConfiguration : when a given configuration is not valid.
+     * @throws MissingHandlerException : occurs when the creation failed due to a missing handler (the factory should be invalid)
+     * @throws ConfigurationException : occurs when the creation failed due to a configuration issue
+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+     */
+    public ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException,
+            ConfigurationException {
+        return m_delegate.createComponentInstance(configuration, m_context);
+    }
+
+    /**
+     * Create an instance manager (i.e. component type instance). This has these service interaction in the scope given in argument.
+     * @param configuration : the configuration properties for this component.
+     * @param serviceContext : the service context of the component.
+     * @return the created instance manager.
+     * @throws UnacceptableConfiguration : when the given configuration is not valid.
+     * @throws MissingHandlerException : when at least one handler is missing.
+     * @throws ConfigurationException : when an issue occurs during the oconfiguration of the instance.
+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary, org.apache.felix.ipojo.ServiceContext)
+     */
+    public ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration,
+            MissingHandlerException, ConfigurationException {
+        return m_delegate.createComponentInstance(configuration, serviceContext);
+    }
+
+    /**
+     * Get the component type information containing provided service, configuration properties ...
+     * @return the component type information.
+     * @see org.apache.felix.ipojo.Factory#getDescription()
+     */
+    public Element getDescription() {
+        return m_delegate.getDescription();
+    }
+
+    /**
+     * Return the factory name.
+     * @return the name of the factory.
+     * @see org.apache.felix.ipojo.Factory#getName()
+     */
+    public String getName() {
+        return m_delegate.getName();
+    }
+
+    /**
+     * Check if the given configuration is acceptable as a configuration of a component instance.
+     * @param conf : the configuration to test
+     * @return true if the configuration is acceptable
+     * @see org.apache.felix.ipojo.Factory#isAcceptable(java.util.Dictionary)
+     */
+    public boolean isAcceptable(Dictionary conf) {
+        return m_delegate.isAcceptable(conf);
+    }
+
+    /**
+     * Reconfigure an instance already created. This configuration need to have the name property to identify the instance.
+     * @param conf : the configuration to reconfigure the instance.
+     * @throws UnacceptableConfiguration : if the given configuration is not consistent for the targeted instance.
+     * @throws MissingHandlerException : when at least one handler is missing
+     * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
+     */
+    public void reconfigure(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {
+        m_delegate.reconfigure(conf);
+    }
+
+    /**
+     * Add a factory listener.
+     * @param listener : the listener to add.
+     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void addFactoryStateListener(FactoryStateListener listener) {
+        m_delegate.addFactoryStateListener(listener);
+
+    }
+
+    public List getMissingHandlers() {
+        return m_delegate.getMissingHandlers();
+    }
+
+    public List getRequiredHandlers() {
+        return m_delegate.getRequiredHandlers();
+    }
+
+    /**
+     * Remove a service listener.
+     * @param listener : the listener to remove
+     * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void removeFactoryStateListener(FactoryStateListener listener) {
+        m_delegate.removeFactoryStateListener(listener);
+
+    }
+
+    public ComponentTypeDescription getComponentDescription() {
+        return m_delegate.getComponentDescription();
+    }
+
+    public String getClassName() {
+        return m_delegate.getClassName();
+    }
+
+    public int getState() {
+        return m_delegate.getState();
+    }
+
+    public BundleContext getBundleContext() {
+        return m_delegate.getBundleContext();
+    }
+
+    public String getVersion() {
+        return m_delegate.getVersion();
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
new file mode 100644
index 0000000..817ec08
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/architecture/ArchitectureHandler.java
@@ -0,0 +1,77 @@
+/* 
+ * 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.composite.architecture;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Composite Architecture Handler.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ArchitectureHandler extends CompositeHandler implements Architecture {
+
+    /**
+     * Name of the component.
+     */
+    private String m_name;
+
+    /**
+     * Configure the handler.
+     * 
+     * @param metadata : the metadata of the component
+     * @param configuration : the instance configuration
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager,
+     * org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary configuration) {
+        m_name = (String) configuration.get("instance.name");
+    }
+
+    /**
+     * Stop the handler.
+     * @see org.apache.felix.ipojo.Handler#stop()
+     */
+    public void stop() {
+        // Nothing to do.
+    }
+
+    /**
+     * Start the handler.
+     * @see org.apache.felix.ipojo.Handler#start()
+     */
+    public void start() { 
+        info("Start composite architecture handler with " + m_name + " name");
+    }
+
+    /**
+     * Get the instance description.
+     * @return the instance description
+     * @see org.apache.felix.ipojo.architecture.Architecture#getDescription()
+     */
+    public InstanceDescription getInstanceDescription() {
+        return getCompositeManager().getInstanceDescription();
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
new file mode 100644
index 0000000..696217c
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandler.java
@@ -0,0 +1,438 @@
+/*
+ * 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.composite.instance;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+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.InstanceManager;
+import org.apache.felix.ipojo.InstanceStateListener;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ParseException;
+
+/**
+ * Composite Instance Handler.
+ * This handler allows creating an instance inside a composite.
+ * This instance is determine by its type and a configuration.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class InstanceHandler extends CompositeHandler implements InstanceStateListener {
+
+    /**
+     * Internal context.
+     */
+    private ServiceContext m_scope;
+
+    /**
+     * Available factories.
+     */
+    private Factory[] m_factories;
+
+    /**
+     * Handler description.
+     */
+    private InstanceHandlerDescription m_description;
+
+
+    /**
+     * This structure aims to manage a configuration. It stores all necessary
+     * information to create an instance and to track the factory.
+     */
+    class ManagedConfiguration {
+        /**
+         * Configuration of the instance to create.
+         */
+        private Dictionary m_configuration;
+
+        /**
+         * Factory name.
+         */
+        private String m_factoryName;
+
+        /**
+         * Created instance.
+         */
+        private ComponentInstance m_instance;
+
+        /**
+         * Desired Factory (can be the classname).
+         */
+        private String m_desiredFactory;
+
+        /**
+         * Constructor.
+         *
+         * @param conf : the configuration to create.
+         */
+        ManagedConfiguration(Dictionary conf) {
+            m_configuration = conf;
+            m_desiredFactory = (String) conf.get("component");
+        }
+
+        /**
+         * Return the managed configuration.
+         * @return the configuration.
+         */
+        protected Dictionary getConfiguration() {
+            return m_configuration;
+        }
+
+        /**
+         * Return the used factory name.
+         * @return the factory name
+         */
+        protected String getFactory() {
+            return m_factoryName;
+        }
+
+        protected String getNeededFactoryName() {
+            return m_desiredFactory;
+        }
+
+        /**
+         * Return the created instance.
+         * @return the instance (or null if no instance are created).
+         */
+        protected ComponentInstance getInstance() {
+            return m_instance;
+        }
+
+        /**
+         * Set the factory name.
+         *
+         * @param name : the factory name.
+         */
+        protected void setFactory(String name) {
+            m_factoryName = name;
+        }
+
+        /**
+         * Set the instance object.
+         *
+         * @param instance : the instance
+         */
+        protected void setInstance(ComponentInstance instance) {
+            m_instance = instance;
+        }
+    }
+
+    /**
+     * Configurations to create and maintains.
+     */
+    private ManagedConfiguration[] m_configurations = new ManagedConfiguration[0];
+
+    /**
+     * Create an instance using the given factory and the given configuration.
+     *
+     * @param fact : the factory name to used.
+     * @param config : the configuration.
+     */
+    private void createInstance(Factory fact, ManagedConfiguration config) {
+        Dictionary conf = config.getConfiguration();
+        try {
+            config.setInstance(fact.createComponentInstance(conf, m_scope));
+            config.setFactory(fact.getName());
+            config.getInstance().addInstanceStateListener(this);
+        } catch (UnacceptableConfiguration e) {
+            error("A factory is available for the configuration but the configuration is not acceptable", e);
+        } catch (MissingHandlerException e) {
+            error("The instance creation has failed, at least one handler is missing", e);
+        } catch (ConfigurationException e) {
+            error("The instance creation has failed, an error during the configuration has occured", e);
+        }
+    }
+
+    /**
+     * A new valid factory appears.
+     * @param factory : factory.
+     */
+    public void bindFactory(Factory factory) {
+        boolean implicated = false;
+        String factName = factory.getName();
+        String className = factory.getComponentDescription().getClassName();
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() == null
+                    && (m_configurations[i].getNeededFactoryName().equals(factName)
+                            || m_configurations[i].getNeededFactoryName().equals(className))) {
+                createInstance(factory, m_configurations[i]);
+                implicated = true;
+            }
+        }
+        if (implicated && ! getValidity()) {
+            checkValidity();
+        }
+    }
+
+    /**
+     * An existing factory disappears or becomes invalid.
+     * @param factory : factory
+     */
+    public void unbindFactory(Factory factory) {
+        boolean implicated = false;
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() != null && m_configurations[i].getFactory().equals(factory.getName())) {
+                m_configurations[i].setInstance(null);
+                m_configurations[i].setFactory(null);
+                implicated = true;
+            }
+        }
+        if (implicated && getValidity()) {
+            checkValidity();
+        }
+    }
+
+    /**
+     * Stop all created instances.
+     */
+    public synchronized void stop() {
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() != null) {
+                m_configurations[i].getInstance().removeInstanceStateListener(this);
+                if (m_configurations[i].getInstance().getState() != ComponentInstance.DISPOSED) {
+                    m_configurations[i].getInstance().dispose();
+                }
+            }
+            m_configurations[i].setInstance(null);
+            m_configurations[i].setFactory(null);
+        }
+        m_configurations = new ManagedConfiguration[0];
+    }
+
+    /**
+     * Configure method.
+     * @param metadata : component type metadata.
+     * @param configuration : instance configuration.
+     * @throws ConfigurationException : occurs an instance cannot be parsed correctly.
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+        m_scope = getCompositeManager().getServiceContext();
+
+        // Prepare the configuration to append.
+        Properties toAppend = new Properties();
+        Enumeration keys = configuration.keys();
+        while(keys.hasMoreElements()) {
+            String key = (String) keys.nextElement();
+            if (! (key.equals("instance.name")
+                    || key.equals("component"))) { // Remove instance.name and component
+                toAppend.put(key, configuration.get(key));
+            }
+        }
+
+        Element[] instances = metadata.getElements("instance");
+        m_configurations = new ManagedConfiguration[instances.length];
+        for (int i = 0; i < instances.length; i++) {
+            Properties conf = null;
+            try {
+                conf = parseInstance(instances[i]);
+            } catch (ParseException e) {
+                error("An instance cannot be parsed correctly", e);
+                throw new ConfigurationException("An instance cannot be parsed correctly : " + e.getMessage());
+            }
+
+            Properties instanceConfiguration = new Properties();
+            instanceConfiguration.putAll(conf);
+            instanceConfiguration.putAll(toAppend);
+            m_configurations[i] = new ManagedConfiguration(instanceConfiguration);
+        }
+
+        m_description = new InstanceHandlerDescription(this, m_configurations);
+    }
+
+    /**
+     * Parse an Element to get a dictionary.
+     * @param instance : the Element describing an instance.
+     * @return : the resulting dictionary
+     * @throws ParseException : occurs when a configuration cannot be parse correctly.
+     */
+    public static Properties parseInstance(Element instance) throws ParseException {
+        Properties dict = new Properties();
+        String name = instance.getAttribute("name");
+        if (name != null) {
+            dict.put("instance.name", name);
+        }
+
+        String comp = instance.getAttribute("component");
+        if (comp == null) {
+            throw new ParseException("An instance does not have the 'component' attribute");
+        } else {
+            dict.put("component", comp);
+        }
+
+        Element[] props = instance.getElements("property");
+        for (int i = 0; props != null && i < props.length; i++) {
+            parseProperty(props[i], dict);
+        }
+
+        return dict;
+    }
+
+    /**
+     * Parse a property.
+     * @param prop : the current element to parse
+     * @param dict : the dictionary to populate
+     * @throws ParseException : occurs if the property cannot be parsed correctly
+     */
+    public static void parseProperty(Element prop, Dictionary dict) throws ParseException {
+        // Check that the property has a name
+        String name = prop.getAttribute("name");
+        String value = prop.getAttribute("value");
+        if (name == null) { throw new ParseException("A property does not have the 'name' attribute"); }
+        // Final case : the property element has a 'value' attribute
+        if (value == null) {
+            // Recursive case
+            // Check if there is 'property' element
+            Element[] subProps = prop.getElements("property");
+            if (subProps == null) { throw new ParseException("A complex property must have at least one 'property' sub-element"); }
+            Dictionary dict2 = new Properties();
+            for (int i = 0; i < subProps.length; i++) {
+                parseProperty(subProps[i], dict2);
+                dict.put(prop.getAttribute("name"), dict2);
+            }
+        } else {
+            dict.put(name, value);
+        }
+    }
+
+    /**
+     * Start method.
+     * @see org.apache.felix.ipojo.Handler#start()
+     */
+    public void start() {
+        for (int j = 0; j < m_factories.length; j++) {
+            String factName = m_factories[j].getName();
+            String className = m_factories[j].getClassName();
+            for (int i = 0; i < m_configurations.length; i++) {
+                if (m_configurations[i].getInstance() == null && (m_configurations[i].getNeededFactoryName().equals(factName) || m_configurations[i].getNeededFactoryName().equals(className))) {
+                    createInstance(m_factories[j], m_configurations[i]);
+                }
+            }
+        }
+        checkValidity();
+    }
+
+    /**
+     * Check handler validity.
+     * The method update the validaity of the handler.
+     */
+    private void checkValidity() {
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() == null || m_configurations[i].getInstance().getState() != ComponentInstance.VALID) {
+                setValidity(false);
+                return;
+            }
+        }
+        setValidity(true);
+    }
+
+    /**
+     *  Instance state listener.
+     *  This method listens when managed instance states change.
+     *  @param instance : instance
+     *  @param newState : the now state of the given instance
+     *  @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
+     */
+    public void stateChanged(ComponentInstance instance, int newState) {
+        switch (newState) {
+            case ComponentInstance.DISPOSED:
+            case ComponentInstance.STOPPED:
+                break; // Should not happen
+            case ComponentInstance.VALID:
+                if (!getValidity()) {
+                    checkValidity();
+                }
+                break;
+            case ComponentInstance.INVALID:
+                if (getValidity()) {
+                    checkValidity();
+                }
+                break;
+            default:
+                break;
+
+        }
+    }
+
+    /**
+     * Method returning an instance object of the given component type.
+     * This method must be called only on 'primitive' type.
+     * @param type : type.
+     * @return an instance object or null if not found.
+     */
+    public Object getObjectFromInstance(String type) {
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() != null && type.equals(m_configurations[i].getFactory())) {
+                if (m_configurations[i].getInstance().getState() == ComponentInstance.VALID) {
+                    return ((InstanceManager) m_configurations[i].getInstance()).getPojoObject();
+                } else {
+                    error("An object cannot be get from the instance of the type " + type + ": invalid instance" + m_configurations[i].getInstance().getInstanceDescription().getDescription());
+                    return null;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return the handler description, i.e. the state of created instances.
+     * @return the handler description.
+     * @see org.apache.felix.ipojo.Handler#getDescription()
+     */
+    public HandlerDescription getDescription() {
+        return m_description;
+    }
+
+    /**
+     * Get the list of used component type.
+     * @return the list containing the used component type
+     */
+    public List getUsedType() {
+        List result = new ArrayList();
+        for (int i = 0; i < m_configurations.length; i++) {
+            result.add(m_configurations[i].getConfiguration().get("component"));
+        }
+        return result;
+    }
+
+    /**
+     * The composite is reconfigured, we check if we have a property to change.
+     * We reconfigure all contained instances.
+     * @param configuration the new instance configuration
+     */
+    public void reconfigure(Dictionary configuration) {
+        for (int i = 0; i < m_configurations.length; i++) {
+            if (m_configurations[i].getInstance() != null) {
+                info("Reconfiguring " + m_configurations[i].getInstance().getInstanceName());
+                m_configurations[i].getInstance().reconfigure(configuration);
+            }
+        }
+
+    }
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
new file mode 100644
index 0000000..a7fc53e
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/instance/InstanceHandlerDescription.java
@@ -0,0 +1,90 @@
+/* 
+ * 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.composite.instance;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.composite.instance.InstanceHandler.ManagedConfiguration;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Description of the Instance Handler.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class InstanceHandlerDescription extends HandlerDescription {
+
+  
+    /**
+     * List of managed instances.
+     */
+    private ManagedConfiguration[] m_configurations; 
+
+    /**
+     * Constructor.
+     * 
+     * @param handler : handler
+     * @param insts : list of component instances
+     */
+    public InstanceHandlerDescription(CompositeHandler handler, ManagedConfiguration[] insts) {
+        super(handler);
+        m_configurations = insts;
+    }
+
+    /**
+     * Build handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element instances = super.getHandlerInfo();
+        for (int i = 0; i < m_configurations.length; i++) {
+            ManagedConfiguration inst = m_configurations[i];
+            Element instance = new Element("Instance", "");
+            if (inst.getInstance() == null) { 
+                instance.addAttribute(new Attribute("Factory", inst.getConfiguration().get("component").toString()));
+                instance.addAttribute(new Attribute("State", "Not Available"));
+            } else {
+                instance.addAttribute(new Attribute("Factory", inst.getFactory()));
+                instance.addAttribute(new Attribute("Name", inst.getInstance().getInstanceName()));
+                String state = null;
+                switch(inst.getInstance().getState()) {
+                    case ComponentInstance.DISPOSED : 
+                        state = "disposed"; break;
+                    case ComponentInstance.STOPPED : 
+                        state = "stopped"; break;
+                    case ComponentInstance.VALID : 
+                        state = "valid"; break;
+                    case ComponentInstance.INVALID : 
+                        state = "invalid"; break;
+                    default :
+                        break;
+                }
+                instance.addAttribute(new Attribute("State", state));
+                // The instance description is already contained inside parent instance description.
+                //instance.addElement(inst.getInstance().getInstanceDescription().getDescription());
+            }
+            instances.addElement(instance);
+        }
+        return instances;
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceDependencyHandler.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceDependencyHandler.java
new file mode 100644
index 0000000..5c1d8e0
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceDependencyHandler.java
@@ -0,0 +1,392 @@
+/*
+ * 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.composite.service.instantiator;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.Enumeration;
+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.PolicyServiceContext;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.composite.instance.InstanceHandler;
+import org.apache.felix.ipojo.composite.util.SourceManager;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ParseException;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.apache.felix.ipojo.util.DependencyStateListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * Service Instantiator Class. This handler allows to instantiate service
+ * instance inside the composition.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceDependencyHandler extends CompositeHandler implements DependencyStateListener {
+
+    /**
+     * List of instances to manage.
+     */
+    private List/* <SvcInstance> */m_instances = new ArrayList();
+
+    /**
+     * List of importers.
+     */
+    private List/* <ServiceImporter> */ m_importers = new ArrayList();
+
+    /**
+     * Flag indicating if the handler has already finished the start method.
+     */
+    private boolean m_isStarted;
+
+    /**
+     * The handler description.
+     */
+    private ServiceInstantiatorDescription m_description;
+
+    /**
+     * Source Managers.
+     */
+    private List m_sources;
+
+
+    /**
+     * Create a Service instance object form the given Element.
+     * This method parse the given element and configure the service instance object.
+     * @param service : the Element describing the service instance
+     * @param conf : the configuration from the composite instance
+     * @throws ConfigurationException : the service instance cannot be created correctly
+     */
+    private void createServiceInstance(Element service, Dictionary conf) throws ConfigurationException {
+        // Prepare the configuration to append.
+        Properties toAppend = new Properties();
+        Enumeration keys = conf.keys();
+        while(keys.hasMoreElements()) {
+        	String key = (String) keys.nextElement();
+        	if (! key.equals("instance.name")
+        			|| key.equals("component")) { // Remove instance.name and component
+        		toAppend.put(key, conf.get(key));
+        	}
+        }
+
+        String spec = service.getAttribute("specification");
+        if (spec == null) {
+            throw new ConfigurationException("Malformed service : the specification attribute is mandatory");
+        }
+        String filter = "(&(!(factory.name=" + getCompositeManager().getFactory().getComponentDescription().getName() + "))(factory.state=1))"; // Cannot reinstantiate yourself
+        String givenFilter = service.getAttribute("filter");
+        if (givenFilter != null) {
+            filter = "(&" + filter + givenFilter + ")"; //NOPMD
+        }
+
+        Filter fil;
+        try {
+            fil = getCompositeManager().getGlobalContext().createFilter(filter);
+        } catch (InvalidSyntaxException e) {
+            throw new ConfigurationException("Malformed filter " + filter + " : " + e.getMessage());
+        }
+
+        Properties prop = new Properties();
+        Element[] props = service.getElements("property");
+        for (int k = 0; props != null && k < props.length; k++) {
+            try {
+                InstanceHandler.parseProperty(props[k], prop);
+            } catch (ParseException e) {
+                throw new ConfigurationException("An instance configuration is invalid : " + e.getMessage());
+            }
+        }
+
+        Properties instanceConfiguration = new Properties();
+     	instanceConfiguration.putAll(prop);
+        instanceConfiguration.putAll(toAppend);
+
+        String aggregate = service.getAttribute("aggregate");
+        boolean agg = aggregate != null && aggregate.equalsIgnoreCase("true");
+
+        String optional = service.getAttribute("optional");
+        boolean opt = optional != null && optional.equalsIgnoreCase("true");
+
+        int policy = DependencyModel.getPolicy(service);
+
+        Comparator cmp = DependencyModel.getComparator(service, getCompositeManager().getGlobalContext());
+
+        SvcInstance inst = new SvcInstance(this, spec, instanceConfiguration, agg, opt, fil, cmp, policy);
+        m_instances.add(inst);
+
+        String sources = service.getAttribute("context-source");
+        if (sources != null) {
+            SourceManager source = new SourceManager(sources, filter, inst, getCompositeManager());
+            if (m_sources == null) {
+                m_sources = new ArrayList(1);
+            }
+            m_sources.add(source);
+        }
+    }
+
+    /**
+     * Create a Service importer object from the given Element.
+     * This method parse the given element and configure the service importer object.
+     * @param imp : Element describing the import
+     * @param confFilter : instance filter customization
+     * @throws ConfigurationException : the service importer cannot be created correctly
+     */
+    private void createServiceImport(Element imp, Dictionary confFilter) throws ConfigurationException {
+        boolean optional = false;
+        boolean aggregate = false;
+        String specification = imp.getAttribute("specification");
+
+        if (specification == null) {
+            // Malformed import
+            error("Malformed import: the specification attribute is mandatory");
+            throw new ConfigurationException("Malformed import : the specification attribute is mandatory");
+        } else {
+            String opt = imp.getAttribute("optional");
+            optional = opt != null && opt.equalsIgnoreCase("true");
+
+            String agg = imp.getAttribute("aggregate");
+            aggregate = agg != null && agg.equalsIgnoreCase("true");
+
+            String original = "(&(objectClass=" + specification + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
+            String filter = original;
+            String givenFilter = imp.getAttribute("filter");
+            if (givenFilter != null) {
+                filter = "(&" + filter + givenFilter + ")"; //NOPMD
+            }
+
+            String identitity = imp.getAttribute("id");
+
+            String scope = imp.getAttribute("scope");
+            BundleContext context = getCompositeManager().getGlobalContext(); // Get the default bundle context.
+            if (scope != null) {
+                if (scope.equalsIgnoreCase("global")) {
+                    context = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.GLOBAL);
+                } else if (scope.equalsIgnoreCase("composite")) {
+                    context = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL);
+                } else if (scope.equalsIgnoreCase("composite+global")) {
+                    context = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL_AND_GLOBAL);
+                }
+            }
+
+            // Configure instance filter if available
+            if (confFilter != null && identitity != null && confFilter.get(identitity) != null) {
+                filter = "(&" + original + (String) confFilter.get(identitity) + ")";
+            }
+
+            Filter fil = null;
+            if (filter != null) {
+                try {
+                    fil = getCompositeManager().getGlobalContext().createFilter(filter);
+                } catch (InvalidSyntaxException e) {
+                    throw new ConfigurationException("A required filter " + filter + " is malformed : " + e.getMessage());
+                }
+            }
+
+            Comparator cmp = DependencyModel.getComparator(imp, getCompositeManager().getGlobalContext());
+            Class spec = DependencyModel.loadSpecification(specification, getCompositeManager().getGlobalContext());
+            int policy = DependencyModel.getPolicy(imp);
+
+            ServiceImporter importer = new ServiceImporter(spec, fil, aggregate, optional, cmp, policy, context, identitity, this);
+            m_importers.add(importer);
+
+            String sources = imp.getAttribute("context-source");
+            if (sources != null) {
+                SourceManager source = new SourceManager(sources, filter, importer, getCompositeManager());
+                if (m_sources == null) {
+                    m_sources = new ArrayList(1);
+                }
+                m_sources.add(source);
+            }
+
+        }
+    }
+
+    /**
+     * Configure the handler.
+     * @param metadata : the metadata of the component
+     * @param conf : the instance configuration
+     * @throws ConfigurationException : the specification attribute is missing
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary conf) throws ConfigurationException {
+        Element[] services = metadata.getElements("subservice");
+        // Get instance filters
+        Dictionary confFilter = null;
+        if (conf.get("requires.filters") != null) {
+            confFilter = (Dictionary) conf.get("requires.filters");
+        }
+
+        for (int i = 0; i < services.length; i++) {
+            String action = services[i].getAttribute("action");
+            if (action == null) {
+                throw new ConfigurationException("The action attribute must be set to 'instantiate' or 'import'");
+            } else if ("instantiate".equalsIgnoreCase(action)) {
+                createServiceInstance(services[i], conf);
+            } else if ("import".equalsIgnoreCase(action)) {
+                createServiceImport(services[i], confFilter);
+            } else {
+                throw new ConfigurationException("Unknown action : " + action);
+            }
+        }
+
+        m_description = new ServiceInstantiatorDescription(this, m_instances, m_importers);
+    }
+
+    /**
+     * Start the service instantiator handler.
+     * Start all created service instance.
+     * @see org.apache.felix.ipojo.CompositeHandler#start()
+     */
+    public void start() {
+        for (int i = 0; m_sources != null && i < m_sources.size(); i++) {
+            SourceManager source = (SourceManager) m_sources.get(i);
+            source.start();
+        }
+
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter imp = (ServiceImporter) m_importers.get(i);
+            imp.start();
+        }
+
+        for (int i = 0; i < m_instances.size(); i++) {
+            SvcInstance inst = (SvcInstance) m_instances.get(i);
+            inst.start();
+        }
+
+        isHandlerValid();
+        m_isStarted = true;
+    }
+
+    /**
+     * Check the handler validity.
+     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+     */
+    private void isHandlerValid() {
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter imp = (ServiceImporter) m_importers.get(i);
+            if (imp.getState() != DependencyModel.RESOLVED) {
+                setValidity(false);
+                return;
+            }
+        }
+
+        for (int i = 0; i < m_instances.size(); i++) {
+            SvcInstance inst = (SvcInstance) m_instances.get(i);
+            if (inst.getState() != DependencyModel.RESOLVED) {
+                setValidity(false);
+                return;
+            }
+        }
+
+        setValidity(true);
+    }
+
+    /**
+     * Handler stop method.
+     * Stop all created service instance.
+     * @see org.apache.felix.ipojo.CompositeHandler#stop()
+     */
+    public void stop() {
+        for (int i = 0; m_sources != null && i < m_sources.size(); i++) {
+            SourceManager source = (SourceManager) m_sources.get(i);
+            source.stop();
+        }
+
+        for (int i = 0; i < m_instances.size(); i++) {
+            SvcInstance inst = (SvcInstance) m_instances.get(i);
+            inst.stop();
+        }
+
+        for (int i = 0; i < m_importers.size(); i++) {
+            ServiceImporter imp = (ServiceImporter) m_importers.get(i);
+            imp.stop();
+        }
+
+        m_isStarted = false;
+    }
+
+    /**
+     * State change callback.
+     * This method is used to freeze the set of used provider if the static binding policy is used.
+     * @param newState : the new state of the underlying instance
+     * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+     */
+    public void stateChanged(int newState) {
+        // If we are becoming valid and started, check if we need to freeze importers.
+        if (m_isStarted && newState == ComponentInstance.VALID) {
+            for (int i = 0; i < m_importers.size(); i++) {
+                ServiceImporter imp = (ServiceImporter) m_importers.get(i);
+                if (imp.getBindingPolicy() == DependencyModel.STATIC_BINDING_POLICY) {
+                    imp.freeze();
+                }
+            }
+
+            for (int i = 0; i < m_instances.size(); i++) {
+                SvcInstance imp = (SvcInstance) m_instances.get(i);
+                if (imp.getBindingPolicy() == DependencyModel.STATIC_BINDING_POLICY) {
+                    imp.freeze();
+                }
+            }
+        }
+    }
+
+    /**
+     * An service instance becomes valid.
+     * @param dep : dependency becoming valid.
+     */
+    public void validate(DependencyModel dep) {
+        if (!getValidity()) {
+            isHandlerValid();
+        }
+    }
+
+    /**
+     * A service instance becomes invalid.
+     * @param dep : dependency becoming valid.
+     */
+    public void invalidate(DependencyModel dep) {
+        if (getValidity()) {
+            isHandlerValid();
+        }
+    }
+
+    /**
+     * Get the service instantiator handler description.
+     * @return the description
+     * @see org.apache.felix.ipojo.CompositeHandler#getDescription()
+     */
+    public HandlerDescription getDescription() {
+        return m_description;
+    }
+
+    public List getInstances() {
+        return m_instances;
+    }
+
+    public List getRequirements() {
+        return m_importers;
+    }
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceImporter.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceImporter.java
new file mode 100644
index 0000000..ed63da7
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceImporter.java
@@ -0,0 +1,327 @@
+/* 
+ * 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.composite.service.instantiator;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.PolicyServiceContext;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Import a service form the parent to the internal service registry.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceImporter extends DependencyModel {
+
+    /**
+     * Reference on the handler.
+     */
+    private ServiceDependencyHandler m_handler;
+
+    private final class Record {
+        /**
+         * External Reference.
+         */
+        private ServiceReference m_ref;
+
+        /**
+         * Internal Registration.
+         */
+        private ServiceRegistration m_reg;
+
+        /**
+         * Exposed Object.
+         */
+        private Object m_svcObject;
+
+        /**
+         * Constructor.
+         * @param ref : service reference.
+         */
+        protected Record(ServiceReference ref) {
+            m_ref = ref;
+        }
+
+        /**
+         * Register the current import.
+         */
+        private void register() {
+            if (m_reg != null) {
+                m_reg.unregister();
+            }
+            m_svcObject = getService(m_ref);
+            m_reg = m_handler.getCompositeManager().getServiceContext()
+                .registerService(getSpecification().getName(), m_svcObject, getProps(m_ref));
+        }
+
+        /**
+         * Update the current import.
+         */
+        private void update() {
+            if (m_reg != null) {
+                m_reg.setProperties(getProps(m_ref));
+            }
+        }
+
+        /**
+         * Unregister and release the current import.
+         */
+        private void dispose() {
+            if (m_reg != null) {
+                m_reg.unregister();
+                m_svcObject = null;
+                m_reg = null;
+            }
+            m_ref = null;
+        }
+
+        /**
+         * Test object equality.
+         * @param object : object to confront against the current object.
+         * @return true if the two objects are equals (same service reference).
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        public boolean equals(Object object) {
+            if (object instanceof Record) {
+                Record rec = (Record) object;
+                return rec.m_ref == m_ref;
+            }
+            return false;
+        }
+        
+        /**
+         * Hash code method.
+         * @return the hash code by calling the parent method.
+         */
+        public int hashCode() {
+            return super.hashCode();
+        }
+    }
+
+    /**
+     * List of managed records.
+     */
+    private List/*<Record>*/m_records = new ArrayList()/* <Record> */;
+
+    /**
+     * Requirement Id.
+     */
+    private String m_id;
+
+    /**
+     * Is this requirement attached to a service-level requirement.
+     */
+    private boolean m_specLevelReq;
+
+    /**
+     * Is the set of used provider frozen ?
+     */
+    private boolean m_isFrozen;
+
+    /**
+     * Constructor.
+     * 
+     * @param specification : targeted specification
+     * @param filter : LDAP filter
+     * @param multiple : should the importer imports several services ?
+     * @param optional : is the import optional ?
+     * @param cmp : comparator to use for the tracking 
+     * @param policy : resolving policy
+     * @param context : bundle context to use for the tracking (can be a servie context)
+     * @param identitity : requirement id (may be null)
+     * @param handler : handler
+     */
+    public ServiceImporter(Class specification, Filter filter, boolean multiple, boolean optional, Comparator cmp, int policy, BundleContext context, String identitity
+            , ServiceDependencyHandler handler) {
+        super(specification, multiple, optional, filter, cmp, policy, context, handler, handler.getCompositeManager());
+
+        this.m_handler = handler;
+
+        if (m_id == null) {
+            m_id = super.getSpecification().getName();
+        } else {
+            m_id = identitity;
+        }
+
+    }
+
+    /**
+     * Get the properties for the exposed service from the given reference.
+     * 
+     * @param ref : the reference.
+     * @return the property dictionary
+     */
+    private static Dictionary getProps(ServiceReference ref) {
+        Properties prop = new Properties();
+        String[] keys = ref.getPropertyKeys();
+        for (int i = 0; i < keys.length; i++) {
+            prop.put(keys[i], ref.getProperty(keys[i]));
+        }
+        return prop;
+    }
+
+    /**
+     * Freeze the set of used provider.
+     * This method allow to fix the set of provider when the static binding policy is used.
+     */
+    public void freeze() {
+        m_isFrozen = true;
+    }
+    
+    /**
+     * Unfreezes.
+     */
+    public void unfreeze() {
+        m_isFrozen = false;
+    }
+
+    public boolean isFrozen() {
+        return m_isFrozen;
+    }
+
+    /**
+     * Stop the management of the import.
+     */
+    public void stop() {
+
+        super.stop();
+
+        for (int i = 0; i < m_records.size(); i++) {
+            Record rec = (Record) m_records.get(i);
+            rec.dispose();
+        }
+
+        m_records.clear();
+
+    }
+
+    /**
+     * Get the record list using the given reference.
+     * 
+     * @param ref : the reference
+     * @return the list containing all record using the given reference
+     */
+    private List/* <Record> */getRecordsByRef(ServiceReference ref) {
+        List list = new ArrayList();
+        for (int i = 0; i < m_records.size(); i++) {
+            Record rec = (Record) m_records.get(i);
+            if (rec.m_ref == ref) {
+                list.add(rec);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Build the list of imported service provider.
+     * @return the list of all imported services.
+     */
+    public List getProviders() {
+        List list = new ArrayList();
+        for (int i = 0; i < m_records.size(); i++) {
+            list.add((((Record) m_records.get(i)).m_ref).getProperty("instance.name"));
+        }
+        return list;
+    }
+
+    /**
+     * Set that this dependency is a service level dependency.
+     * This forces the scoping policy to be STRICT. 
+     * @param b
+     */
+    public void setServiceLevelDependency() {
+        m_specLevelReq = true;
+        PolicyServiceContext context = new PolicyServiceContext(m_handler.getCompositeManager().getGlobalContext(), m_handler.getCompositeManager().getParentServiceContext(), PolicyServiceContext.LOCAL);
+        setBundleContext(context);
+    }
+
+    public String getId() {
+        return m_id;
+    }
+
+    public boolean isServiceLevelRequirement() {
+        return m_specLevelReq;
+    }
+
+    /**
+     * On Dependency Reconfiguration notification method.
+     * @param departs : leaving service references.
+     * @param arrivals : new injected service references.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])
+     */
+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {
+        for (int i = 0; departs != null && i < departs.length; i++) {
+            onServiceDeparture(departs[i]);
+        }
+        
+        for (int i = 0; arrivals != null && i < arrivals.length; i++) {
+            onServiceArrival(arrivals[i]);
+        }
+    }
+
+    /**
+     * A new service is injected by the tracker.
+     * This method create a 'Record' and register it.
+     * @param ref : new service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceArrival(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceArrival(ServiceReference ref) {
+        Record rec = new Record(ref);
+        m_records.add(rec);
+        // Always register the reference, as the method is call only when needed. 
+        rec.register();
+    }
+
+    /**
+     * A used service disappears.
+     * This method find the implicated 'Record', dispose it and remove it from the list.
+     * @param ref : leaving service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceDeparture(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceDeparture(ServiceReference ref) {
+        List list = getRecordsByRef(ref);
+        for (int i = 0; i < list.size(); i++) { // Stop the implied record
+            Record rec = (Record) list.get(i);
+            rec.dispose();
+        }
+        m_records.removeAll(list);
+    }
+
+    /**
+     * A used service is modified.
+     * @param ref : modified service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceModification(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceModification(ServiceReference ref) {
+        List list = getRecordsByRef(ref);
+        for (int i = 0; i < list.size(); i++) { // Stop the implied record
+            Record rec = (Record) list.get(i);
+            rec.update();
+        }
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
new file mode 100644
index 0000000..2125153
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/ServiceInstantiatorDescription.java
@@ -0,0 +1,117 @@
+/* 
+ * 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.composite.service.instantiator;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Description of the Service Creator Handler.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceInstantiatorDescription extends HandlerDescription {
+
+    /**
+     * List of managed service instances.
+     */
+    private List m_instances;
+
+    /**
+     * List of exports.
+     */
+    private List m_imports;
+
+    /**
+     * Constructor.
+     * 
+     * @param handler : composite handler
+     * @param insts : list of service instances
+     * @param imps : list of service importers
+     */
+    public ServiceInstantiatorDescription(CompositeHandler handler, List insts, List imps) {
+        super(handler);
+        m_instances = insts;
+        m_imports = imps;
+    }
+
+    /**
+     * Build service instantiator handler description.
+     * @return the handler description
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element services = super.getHandlerInfo();
+        for (int i = 0; i < m_imports.size(); i++) {
+            ServiceImporter imp = (ServiceImporter) m_imports.get(i);
+            Element impo = new Element("Requires", "");
+            impo.addAttribute(new Attribute("Specification", imp.getSpecification().getName()));
+            if (imp.getFilter() != null) {
+                impo.addAttribute(new Attribute("Filter", imp.getFilter()));
+            }
+            if (imp.getState() == DependencyModel.RESOLVED) {
+                impo.addAttribute(new Attribute("State", "resolved"));
+                for (int j = 0; j < imp.getProviders().size(); j++) {
+                    Element prov = new Element("Provider", "");
+                    prov.addAttribute(new Attribute("name", (String) imp.getProviders().get(j)));
+                    impo.addElement(prov);
+                }
+            } else {
+                impo.addAttribute(new Attribute("State", "unresolved"));
+            }
+            services.addElement(impo);
+        }
+        
+        for (int i = 0; i < m_instances.size(); i++) {
+            SvcInstance inst = (SvcInstance) m_instances.get(i);
+            Element service = new Element("Service", "");
+            service.addAttribute(new Attribute("Specification", inst.getServiceSpecification()));
+            String state = "unresolved";
+            if (inst.getState() == DependencyModel.RESOLVED) {
+                state = "resolved";
+            }
+            service.addAttribute(new Attribute("State", state));
+            Map map = inst.getMatchingFactories();
+            Set keys = map.keySet();
+            Iterator iterator = keys.iterator();
+            while (iterator.hasNext()) {
+                ServiceReference ref = (ServiceReference) iterator.next();
+                Object object = map.get(ref);
+                if (object != null) {
+                    Element fact = new Element("Factory", "");
+                    fact.addAttribute(new Attribute("Name", ((ComponentInstance) object).getFactory().getName()));
+                    service.addElement(fact);
+                }
+            }
+            services.addElement(service);
+        }
+        return services;
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
new file mode 100644
index 0000000..d61d347
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/instantiator/SvcInstance.java
@@ -0,0 +1,295 @@
+/* 
+ * 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.composite.service.instantiator;
+
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+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;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Manage a service instantiation. This service create component instance providing the required service specification.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SvcInstance extends DependencyModel {
+
+    /**
+     * Configuration to push to the instance.
+     */
+    private Dictionary m_configuration;
+
+    /**
+     * Handler creating the service instance.
+     */
+    private ServiceDependencyHandler m_handler;
+
+    /**
+     * Map of matching factories Service Reference => instance or null (null if the service reference is not actually used).
+     */
+    private Map /* <ServiceReference, Instance> */m_factories = new HashMap();
+
+    /**
+     * Required specification.
+     */
+    private String m_specification;
+
+    /**
+     * Is the service provider frozen ? (Is used for static biding policy)
+     */
+    private boolean m_isFrozen;
+
+    /**
+     * Constructor.
+     * @param handler : the handler.
+     * @param spec : required specification.
+     * @param conf : instance configuration.
+     * @param isAgg : is the service instance an aggregate service ?
+     * @param isOpt : is the service instance optional ?
+     * @param filt : LDAP filter
+     * @param cmp : comparator to use for the tracking
+     * @param policy : binding policy
+     * @throws ConfigurationException : an attribute cannot be parsed correctly, or is incorrect.
+     */
+    public SvcInstance(ServiceDependencyHandler handler, String spec, Dictionary conf, boolean isAgg, boolean isOpt, Filter filt, Comparator cmp, int policy) throws ConfigurationException {
+        super(Factory.class, isAgg, isOpt, filt, cmp, policy, null, handler, handler.getCompositeManager());
+
+        m_specification = spec;
+
+        m_handler = handler;
+        setBundleContext(m_handler.getCompositeManager().getServiceContext());
+
+        m_configuration = conf;
+    }
+
+    /**
+     * Stop the service instance.
+     */
+    public void stop() {
+        super.stop();
+
+        Set keys = m_factories.keySet();
+        Iterator iterator = keys.iterator();
+        while (iterator.hasNext()) {
+            ServiceReference ref = (ServiceReference) iterator.next();
+            Object object = m_factories.get(ref);
+            if (object != null) {
+                m_handler.info("Dispose a service instance when stopping the handler " + ((ComponentInstance) object).getInstanceName());
+                ((ComponentInstance) object).dispose();
+            }
+        }
+
+        m_factories.clear();
+
+    }
+
+    public boolean isFrozen() {
+        return m_isFrozen;
+    }
+
+    /**
+     * Freeze the set of used provider.
+     * This method is when the static binding policy is applied.
+     */
+    public void freeze() {
+        m_isFrozen = true;
+    }
+    
+    /**
+     * Unfreezes.
+     */
+    public void unfreeze() {
+        m_isFrozen = false;
+    }
+
+
+    /**
+     * Create an instance for the given reference. The instance is not added inside the map.
+     * @param factory : the factory from which we need to create the instance.
+     * @return the created component instance.
+     * @throws ConfigurationException : the instance cannot be configured correctly.
+     * @throws MissingHandlerException : the factory is invalid.
+     * @throws UnacceptableConfiguration : the given configuration is invalid for the given factory.
+     */
+    private ComponentInstance createInstance(Factory factory) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException {
+        // Recreate the configuration to avoid sharing.
+        Properties props = new Properties();
+        Enumeration keys = m_configuration.keys();
+        while (keys.hasMoreElements()) {
+            String key = (String) keys.nextElement();
+            props.put(key, m_configuration.get(key));
+        }
+        ComponentInstance instance = null;
+        instance = factory.createComponentInstance(props);
+        m_handler.info("Creation of a service instance " + instance.getInstanceName());
+        return instance;
+    }
+
+    /**
+     * Does the service instance match with the given factory ?
+     * @param fact : the factory to test.
+     * @return true if the factory match, false otherwise.
+     */
+    public boolean match(ServiceReference fact) {
+        // Check if the factory can provide the specification
+        ComponentTypeDescription desc = (ComponentTypeDescription) fact.getProperty("component.description");
+        if (desc == null) { 
+            return false; // No component type description.
+        }
+
+        String[] provides = desc.getprovidedServiceSpecification();
+        for (int i = 0; provides != null && i < provides.length; i++) {
+            if (provides[i].equals(m_specification)) {
+                // Check that the factory needs every properties contained in
+                // the configuration
+                PropertyDescription[] props = desc.getProperties();
+                Properties conf = new Properties();
+                Enumeration keys = m_configuration.keys();
+                while (keys.hasMoreElements()) {
+                    String key = (String) keys.nextElement();
+                    if (!containsProperty(key, props)) { return false; }
+                    conf.put(key, m_configuration.get(key));
+                }
+
+                Factory factory = (Factory) getService(fact);
+                return factory.isAcceptable(conf);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Does the factory support the given property ? This method check if the property is contained in the given property description array.
+     * @param name : name of the property
+     * @param props : list of property description
+     * @return true if the factory support this property
+     */
+    private boolean containsProperty(String name, org.apache.felix.ipojo.architecture.PropertyDescription[] props) {
+        for (int i = 0; props != null && i < props.length; i++) {
+            if (props[i].getName().equalsIgnoreCase(name)) { return true; }
+        }
+        if (name.equalsIgnoreCase("name")) { return true; } // Skip the name property
+        return false;
+    }
+
+    /**
+     * Get the required specification.
+     * @return the required specification.
+     */
+    public String getServiceSpecification() {
+        return m_specification;
+    }
+
+    /**
+     * Get the map of used references [reference, component instance].
+     * @return the map of used references.
+     */
+    protected Map getMatchingFactories() {
+        return m_factories;
+    }
+
+    /**
+     * On Dependency Reconfiguration notification method.
+     * @param departs : leaving service references.
+     * @param arrivals : new injected service references.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])
+     */
+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {
+        for (int i = 0; departs != null && i < departs.length; i++) {
+            onServiceDeparture(departs[i]);
+        }
+        
+        for (int i = 0; arrivals != null && i < arrivals.length; i++) {
+            onServiceArrival(arrivals[i]);
+        }
+    }
+
+    /**
+     * A new service is injected.
+     * This method create the sub-service instance in the composite.
+     * @param ref : service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceArrival(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceArrival(ServiceReference ref) {
+        // The given factory matches.
+        try {
+            Factory fact = (Factory) getService(ref);
+            if (m_factories.get(ref) == null) {
+                ComponentInstance instance = createInstance(fact);
+                m_factories.put(ref, instance);
+            } else {
+                m_handler
+                        .info("An arriving factory is already used, ignore the creation : "
+                                + fact.getName());
+            }
+            
+        } catch (UnacceptableConfiguration e) {
+            m_handler.error("A matching factory refuses the actual configuration : " + e.getMessage());
+            m_handler.getCompositeManager().stop();
+        } catch (MissingHandlerException e) {
+            m_handler.error("A matching factory is no more valid : " + e.getMessage());
+            m_handler.getCompositeManager().stop();
+        } catch (ConfigurationException e) {
+            m_handler.error("A matching configuration is refused by the instance : " + e.getMessage());
+            m_handler.getCompositeManager().stop();
+        }
+
+    }
+
+    
+    /**
+     * A used service is leaving.
+     * This method dispose the created instance.
+     * @param ref : leaving service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceDeparture(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceDeparture(ServiceReference ref) {
+        // Remove the reference is contained
+        Object instance = m_factories.remove(ref);
+        if (instance != null) {
+            m_handler.info("Dispose the instance (departure of the factory) "
+                    + ((ComponentInstance) instance).getInstanceName());
+            ((ComponentInstance) instance).dispose();
+        }
+    }
+
+    /**
+     * A factory is modified. This should not happen.
+     * @param arg0 the service reference
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceModification(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceModification(ServiceReference arg0) {
+        // Nothing to do.
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
new file mode 100644
index 0000000..9423d3c
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionException.java
@@ -0,0 +1,41 @@
+/* 
+ * 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.composite.service.provides;
+
+/**
+ * Exception occurs when a composition error occurs.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CompositionException extends Exception {
+    //TODO consider removing this class to use configuration exception.
+    /**
+     * serialVersionUID.
+     */
+    private static final long serialVersionUID = -3063353267573738105L;
+
+    /**
+     * Constructor.
+     * @param message : a message.
+     */
+    public CompositionException(String message) {
+        super(message);
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
new file mode 100644
index 0000000..69bc5bb
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/CompositionMetadata.java
@@ -0,0 +1,360 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+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;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Check and build a composition, i.e. a POJO containing the composition.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class CompositionMetadata {
+
+    /**
+     * Implemented composition.
+     */
+    private SpecificationMetadata m_specification;
+
+    /**
+     * Name of the composition.
+     */
+    private String m_name;
+
+    /**
+     * Bundle Context.
+     */
+    private BundleContext m_context;
+
+    /**
+     * Manipulation Metadata.
+     */
+    private Element m_manipulation;
+
+    /**
+     * Reference on the handler.
+     */
+    private ProvidedServiceHandler m_handler;
+
+    /**
+     * List of Mappings.
+     */
+    private List m_mappings = new ArrayList();
+
+    /**
+     * Constructor.
+     * @param context : bundle context
+     * @param description : 'provides' element
+     * @param psh : parent handler 
+     * @param name : name of the composition.
+     */
+    public CompositionMetadata(BundleContext context, Element description, ProvidedServiceHandler psh, String name) {
+        m_context = context;
+        m_handler = psh;
+        // Get the composition name
+        m_name = description.getAttribute("specification") + name;
+
+        // Get implemented service specification
+        String spec = description.getAttribute("specification");
+        m_specification = new SpecificationMetadata(spec, m_context, false, false, m_handler);
+
+        Element[] mappings = description.getElements("delegation");
+        for (int i = 0; mappings != null && i < mappings.length; i++) {
+            String methodName = mappings[i].getAttribute("method");
+            MethodMetadata method = m_specification.getMethodByName(methodName);
+            if (method == null) {
+                m_handler.error("The method " + methodName + " does not exist in the specicifation " + spec);
+                return;
+            }
+
+            if (mappings[i].getAttribute("policy").equalsIgnoreCase("All")) {
+                method.setAllPolicy();
+            }
+        }
+    }
+
+    protected BundleContext getBundleContext() {
+        return m_context;
+    }
+
+    public String getName() {
+        return m_name;
+    }
+
+    public SpecificationMetadata getSpecificationMetadata() {
+        return m_specification;
+    }
+
+    /**
+     * Build Available Mappings.
+     * @throws CompositionException : a factory is not available, the composition cannot be checked.
+     */
+    private void buildAvailableMappingList() throws CompositionException {
+        int index = 0;
+
+        for (int i = 0; i < m_handler.getInstanceType().size(); i++) {
+            String type = (String) m_handler.getInstanceType().get(i);
+            try {
+                ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), "(factory.name=" + type + ")");
+                if (refs == null) {
+                    m_handler.error("The factory " + type + " is not available, cannot check the composition");
+                    throw new CompositionException("The factory " + type + " needs to be available to check the composition");
+                } else {
+                    String className = (String) refs[0].getProperty("component.class");
+                    Class impl = m_context.getBundle().loadClass(className);
+                    SpecificationMetadata spec = new SpecificationMetadata(impl, type, m_handler);
+                    FieldMetadata field = new FieldMetadata(spec);
+                    field.setName("_field" + index);
+                    Mapping map = new Mapping(spec, field);
+                    m_mappings.add(map);
+                    index++;
+                }
+            } catch (InvalidSyntaxException e) {
+                m_handler.error("A LDAP filter is not valid : " + e.getMessage());
+            } catch (ClassNotFoundException e) {
+                m_handler.error("The implementation class of a component cannot be loaded : " + e.getMessage());
+            }
+        }
+
+        for (int i = 0; i < m_handler.getSpecifications().size(); i++) {
+            SpecificationMetadata spec = (SpecificationMetadata) m_handler.getSpecifications().get(i);
+            FieldMetadata field = new FieldMetadata(spec);
+            field.setName("_field" + index);
+            if (spec.isOptional()) {
+                field.setOptional(true);
+            }
+            if (spec.isAggregate()) {
+                field.setAggregate(true);
+            }
+            Mapping map = new Mapping(spec, field);
+            m_mappings.add(map);
+            index++;
+        }
+    }
+
+    /**
+     * Build the delegation mapping.
+     * @throws CompositionException : occurs when the mapping cannot be inferred correctly
+     */
+    protected void buildMapping() throws CompositionException {
+        buildAvailableMappingList();
+
+        // Dependency closure is OK, now look for method delegation
+        Map/* <MethodMetadata, Mapping> */svcMethods = new HashMap();
+        Map/* <MethodMetadata, Mapping> */instMethods = new HashMap();
+
+        for (int i = 0; i < m_mappings.size(); i++) {
+            Mapping map = (Mapping) m_mappings.get(i);
+            SpecificationMetadata spec = map.getSpecification();
+            for (int j = 0; j < spec.getMethods().size(); j++) {
+                MethodMetadata method = (MethodMetadata) spec.getMethods().get(j);
+                if (spec.isInterface()) {
+                    svcMethods.put(method, map);
+                } else {
+                    instMethods.put(method, map);
+                }
+            }
+        }
+
+        // For each needed method, search if available and store the mapping
+        for (int j = 0; j < m_specification.getMethods().size(); j++) {
+            MethodMetadata method = (MethodMetadata) m_specification.getMethods().get(j);
+            Set keys = instMethods.keySet(); // Look first in methods contained in the glue code.
+            Iterator iterator = keys.iterator();
+            boolean found = false;
+            while (iterator.hasNext() & !found) {
+                MethodMetadata met = (MethodMetadata) iterator.next();
+                if (met.equals(method)) {
+                    found = true;
+                    FieldMetadata field = ((Mapping) instMethods.get(met)).getField();
+                    field.setUseful(true);
+                    method.setDelegation(field);
+                }
+            }
+            if (!found) { // If not found looks inside method contained in services.
+                keys = svcMethods.keySet(); // Look first in methods contained in the glue code
+                iterator = keys.iterator();
+                while (!found && iterator.hasNext()) {
+                    MethodMetadata met = (MethodMetadata) iterator.next();
+                    if (met.equals(method)) {
+                        found = true;
+                        FieldMetadata field = ((Mapping) svcMethods.get(met)).getField();
+                        field.setUseful(true);
+                        method.setDelegation(field);
+                        // Test optional
+                        if (field.isOptional() && !method.throwsUnsupportedOperationException()) {
+                            m_handler.warn("The method " + method.getMethod().getName() + " could not be provided correctly : the specification " + field.getSpecification().getName() + " is optional");
+                        }
+                    }
+                }
+            }
+            if (!found) { throw new CompositionException("Inconsistent composition - the method " + method.getMethod() + " could not be delegated"); }
+        }
+    }
+
+    /**
+     * Build a service implementation.
+     * @return the byte[] of the POJO.
+     */
+    protected byte[] buildPOJO() {
+        Class clazz = null;
+        try {
+            clazz = getBundleContext().getBundle().loadClass(m_specification.getName());
+        } catch (ClassNotFoundException e1) {
+            // The class has already be loaded.
+            return null;
+        }
+        byte[] pojo = POJOWriter.dump(clazz, m_name, getFieldList(), getMethodList(), m_handler);
+        Manipulator manipulator = new Manipulator();
+        try {
+            byte[] newclazz = manipulator.manipulate(pojo);
+            m_manipulation = manipulator.getManipulationMetadata();
+            return newclazz;
+        } catch (IOException e) {
+            m_handler.error("An error occurs during the composite implementation creation : " + e.getMessage(), e);
+        }
+        return null;
+    }
+
+    /**
+     * Build service implementation metadata.
+     * @param name : name of the future instance (used to avoid cycle)
+     * @return Component Type metadata. 
+     */
+    protected Element buildMetadata(String name) {
+        Element elem = new Element("component", "");
+        Attribute className = new Attribute("classname", m_name);
+        Attribute factory = new Attribute("public", "false");
+        elem.addAttribute(className);
+        elem.addAttribute(factory);
+
+        // Add architecture for debug
+        elem.addAttribute(new Attribute("architecture", "true"));
+
+        // Provides
+        Element provides = new Element("provides", "");
+        provides.addAttribute(new Attribute("specification", m_specification.getName()));
+        elem.addElement(provides);
+
+        // Dependencies
+        List fields = getFieldList();
+        for (int i = 0; i < fields.size(); i++) {
+            FieldMetadata field = (FieldMetadata) fields.get(i);
+            if (field.isUseful() && field.getSpecification().isInterface()) {
+                Element dep = new Element("requires", "");
+                dep.addAttribute(new Attribute("field", field.getName()));
+                dep.addAttribute(new Attribute("scope", "composite"));
+                dep.addAttribute(new Attribute("proxy", "false"));
+                if (field.getSpecification().isOptional()) {
+                    dep.addAttribute(new Attribute("optional", "true"));
+                }
+                dep.addAttribute(new Attribute("filter", "(!(instance.name=" + name + "))"));
+                elem.addElement(dep);
+            }
+        }
+
+        Element properties = new Element("properties", "");
+        for (int i = 0; i < fields.size(); i++) {
+            FieldMetadata field = (FieldMetadata) fields.get(i);
+            if (field.isUseful() && !field.getSpecification().isInterface()) {
+                Element prop = new Element("Property", "");
+                prop.addAttribute(new Attribute("field", field.getName()));
+                properties.addElement(prop);
+            }
+        }
+        if (properties.getElements().length != 0) {
+            elem.addElement(properties);
+        }
+
+        // Insert information to metadata
+        elem.addElement(m_manipulation);
+
+        return elem;
+    }
+
+    /**
+     * Get the field list to use for the delegation.
+     * @return the field list.
+     */
+    public List getFieldList() {
+        List list = new ArrayList();
+        for (int i = 0; i < m_mappings.size(); i++) {
+            Mapping map = (Mapping) m_mappings.get(i);
+            list.add(map.getField());
+        }
+        return list;
+    }
+
+    /**
+     * Get the method list contained in the implemented specification.
+     * @return the List of implemented method.
+     */
+    private List getMethodList() {
+        return m_specification.getMethods();
+    }
+
+    /**
+     * Store links between Field and pointed Specification.
+     */
+    private class Mapping {
+
+        /**
+         * Specification.
+         */
+        private SpecificationMetadata m_spec;
+
+        /**
+         * Field.
+         */
+        private FieldMetadata m_field;
+
+        /**
+         * Constructor.
+         * @param spec : specification metadata.
+         * @param field : the field.
+         */
+        public Mapping(SpecificationMetadata spec, FieldMetadata field) {
+            m_spec = spec;
+            m_field = field;
+        }
+
+        public SpecificationMetadata getSpecification() {
+            return m_spec;
+        }
+
+        public FieldMetadata getField() {
+            return m_field;
+        }
+
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
new file mode 100644
index 0000000..4df41a8
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/FieldMetadata.java
@@ -0,0 +1,105 @@
+/* 
+ * 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.composite.service.provides;
+
+/**
+ * Field used inside a composition.
+ * This class contains all information useful for the generation.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FieldMetadata {
+
+    /**
+     * Name of the field.
+     */
+    private String m_name;
+
+    /**
+     * Is the field an array?
+     */
+    private boolean m_isAggregate = false;
+
+    /**
+     * Interface of the field.
+     */
+    private SpecificationMetadata m_specification;
+
+    /**
+     * Is the field useful in this composition.
+     */
+    private boolean m_isUseful;
+
+    /**
+     * Is the dependency for this field optional.
+     */
+    private boolean m_isOptional = false;
+
+    /**
+     * Constructor.
+     * @param specification : interface of the field.
+     */
+    public FieldMetadata(SpecificationMetadata specification) {
+        super();
+        this.m_specification = specification;
+        if (m_specification.isAggregate()) {
+            m_isAggregate = true;
+        }
+    }
+
+    public boolean isAggregate() {
+        return m_isAggregate;
+    }
+
+    public void setAggregate(boolean aggregate) {
+        m_isAggregate = aggregate;
+    }
+
+    public String getName() {
+        return m_name;
+    }
+
+    public void setName(String name) {
+        this.m_name = name;
+    }
+
+    public SpecificationMetadata getSpecification() {
+        return m_specification;
+    }
+
+    public void setSpecification(SpecificationMetadata specification) {
+        this.m_specification = specification;
+    }
+
+    public boolean isUseful() {
+        return m_isUseful;
+    }
+
+    public void setUseful(boolean useful) {
+        m_isUseful = useful;
+    }
+
+    public boolean isOptional() {
+        return m_isOptional;
+    }
+
+    public void setOptional(boolean opt) {
+        m_isOptional = opt;
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
new file mode 100644
index 0000000..510514e
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/MethodMetadata.java
@@ -0,0 +1,138 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.lang.reflect.Method;
+
+/**
+ * Information on Method for the composition.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class MethodMetadata {
+
+    /**
+     * ONE POLICY.
+     */
+    public static final int ONE_POLICY = 1;
+
+    /**
+     * ALL POLICY. 
+     */
+    public static final int ALL_POLICY = 2;
+
+    /**
+     * Method Object.
+     */
+    private Method m_method;
+    
+    /**
+     * Delegation field.
+     */
+    private FieldMetadata m_delegation;
+
+    /**
+     * Delegation policy (default = ONE).
+     */
+    private int m_policy = ONE_POLICY;
+
+    /**
+     * Constructor.
+     * @param method : method object.
+     */
+    public MethodMetadata(Method method) {
+        m_method = method;
+    }
+
+    public Method getMethod() {
+        return m_method;
+    }
+
+    public void setDelegation(FieldMetadata field) {
+        m_delegation = field;
+    }
+
+    public FieldMetadata getDelegation() {
+        return m_delegation;
+    }
+    
+    /**
+     * Equals method.
+     * This method check if two MethodMetadata are equals or if the current MemethodMetadata is equals with a Method object. 
+     * @param object : object.
+     * @return true if the current object and the given object are equals.
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object object) {
+        if (object instanceof MethodMetadata) {
+            Method met = ((MethodMetadata) object).getMethod();
+            return equals(met);
+        }
+        
+        if (object instanceof Method) {
+            Method met = (Method) object;
+            if (! met.getName().equals(m_method.getName()) || met.getParameterTypes().length != m_method.getParameterTypes().length) {
+                return false;
+            }
+
+            for (int i = 0; i < m_method.getParameterTypes().length; i++) {
+                if (!m_method.getParameterTypes()[i].getName().equals(met.getParameterTypes()[i].getName())) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+        
+        return false;
+    }
+    
+    /**
+     * Hash code method.
+     * @return the parent hash code.
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    public int getPolicy() {
+        return m_policy;
+    }
+
+    /**
+     * Activate the all policy for this method.
+     */
+    public void setAllPolicy() {
+        m_policy = ALL_POLICY;
+    }
+    
+    /**
+     * Check if the method can throw UnsupportedOperationException.
+     * @return true if the method has declared the UnsupportedOperationException.
+     */
+    protected boolean throwsUnsupportedOperationException() {
+        for (int i = 0; i < m_method.getExceptionTypes().length; i++) {
+            if (m_method.getExceptionTypes()[i].getName().equals(UnsupportedOperationException.class.getName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
new file mode 100644
index 0000000..ffca9c8
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/POJOWriter.java
@@ -0,0 +1,323 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.felix.ipojo.Handler;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * Create the Proxy class.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class POJOWriter implements Opcodes {
+    
+    //TODO : merge this class with another class only static methods.
+
+    /**
+     * Create a class.
+     * @param cw : class writer
+     * @param className : class name
+     * @param spec : implemented specification
+     */
+    private static void createClass(ClassWriter cw, String className, String spec) {
+        // Create the class
+        cw.visit(V1_2, ACC_PUBLIC + ACC_SUPER, className, null, "java/lang/Object", new String[] { spec.replace('.', '/') });
+    }
+
+    /**
+     * Inject field in the current class.
+     * @param cw : class writer.
+     * @param fields : list of field to inject.
+     */
+    private static void injectFields(ClassWriter cw, List fields) {
+        // Inject fields
+        for (int i = 0; i < fields.size(); i++) {
+            FieldMetadata field = (FieldMetadata) fields.get(i);
+            if (field.isUseful()) {
+                SpecificationMetadata spec = field.getSpecification();
+                String fieldName = field.getName();
+                String desc = "";
+                if (field.isAggregate()) {
+                    desc = "[L" + spec.getName().replace('.', '/') + ";";
+                } else {
+                    desc = "L" + spec.getName().replace('.', '/') + ";";
+                }
+
+                cw.visitField(Opcodes.ACC_PRIVATE, fieldName, desc, null, null);
+            }
+        }
+    }
+    
+    /**
+     * Generates an empty constructor.
+     * this constructor just call the java.lang.Object constructor.
+     * @param cw class writer
+     */
+    private static void generateConstructor(ClassWriter cw) {
+        // Inject a constructor <INIT>()V
+        MethodVisitor cst = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
+        cst.visitVarInsn(ALOAD, 0);
+        cst.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+        cst.visitInsn(RETURN);
+        cst.visitMaxs(0, 0);
+        cst.visitEnd();
+    }
+
+    /**
+     * Return the proxy 'classname' for the contract 'contractname' by delegating on available service.
+     * @param clazz : Specification class
+     * @param className : The class name to create
+     * @param fields : the list of fields on which delegate
+     * @param methods : the list of method on which delegate
+     * @param handler : handler object used to access the logger
+     * @return byte[] : the build class
+     */
+    public static byte[] dump(Class clazz, String className, List fields, List methods, Handler handler) {
+        Method[] itfmethods = clazz.getMethods();
+
+        // Create the class
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        className = className.replace('.', '/');
+        createClass(cw, className, clazz.getName());
+
+        // Inject fields inside the POJO
+        injectFields(cw, fields);
+
+        generateConstructor(cw);
+        
+        for (int i = 0; i < itfmethods.length; ++i) {
+            Method method = itfmethods[i];
+
+            // Get the field for this method
+            // 1) find the MethodMetadata
+            FieldMetadata delegator = null; // field to delegate
+            MethodMetadata methodDelegator = null; // field to delegate
+            for (int j = 0; j < methods.size(); j++) {
+                MethodMetadata methodMeta = (MethodMetadata) methods.get(j);
+                if (methodMeta.equals(method)) {
+                    delegator = methodMeta.getDelegation();
+                    methodDelegator = methodMeta;
+                }
+            }
+
+            generateMethod(cw, className, methodDelegator, method, delegator, handler);
+
+        }
+
+        // End process
+        cw.visitEnd();
+        return cw.toByteArray();
+    }
+
+    /**
+     * Generate on method.
+     * @param cw : class writer
+     * @param className : the current class name
+     * @param method : the method to generate
+     * @param sign : method signature to generate
+     * @param delegator : the field on which delegate
+     * @param handler : the handler (used to acess the logger)
+     */
+    private static void generateMethod(ClassWriter cw, String className, MethodMetadata method, Method sign, FieldMetadata delegator, Handler handler) {
+        String desc = Type.getMethodDescriptor(sign);
+        String name = sign.getName();
+        String[] exc = new String[sign.getExceptionTypes().length];
+        for (int i = 0; i < sign.getExceptionTypes().length; i++) {
+            exc[i] = Type.getType(sign.getExceptionTypes()[i]).getInternalName();
+        }
+
+        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, name, desc, null, exc);
+
+        if (delegator.isOptional()) {
+            if (!delegator.isAggregate()) {
+                generateOptionalCase(mv, delegator, className);
+            }
+            if (delegator.isAggregate() /*&& method.getPolicy() == MethodMetadata.ONE_POLICY*/) {
+                generateOptionalAggregateCase(mv, delegator, className);
+            }
+        }
+
+        if (delegator.isAggregate()) {
+            if (method.getPolicy() == MethodMetadata.ONE_POLICY) {
+                // Aggregate and One Policy
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "[L" + delegator.getSpecification().getName().replace('.', '/') + ";");
+                mv.visitInsn(ICONST_0); // Use the first one
+                mv.visitInsn(AALOAD);
+
+                loadArgs(mv, ACC_PUBLIC, Type.getArgumentTypes(desc));
+
+                // Invoke
+                mv.visitMethodInsn(INVOKEINTERFACE, delegator.getSpecification().getName().replace('.', '/'), name, desc);
+
+                // Return
+                mv.visitInsn(Type.getReturnType(desc).getOpcode(Opcodes.IRETURN));
+
+            } else { // All policy
+                if (Type.getReturnType(desc).getSort() != Type.VOID) {
+                    handler.error("All policy cannot be used on method which does not return void");
+                }
+
+                Type[] args = Type.getArgumentTypes(desc);
+                int index = args.length + 1;
+
+                // Init
+                mv.visitInsn(ICONST_0);
+                mv.visitVarInsn(ISTORE, index);
+                Label l1b = new Label();
+                mv.visitLabel(l1b);
+                Label l2b = new Label();
+                mv.visitJumpInsn(GOTO, l2b);
+
+                // Loop
+                Label l3b = new Label();
+                mv.visitLabel(l3b);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "[L" + delegator.getSpecification().getName().replace('.', '/') + ";");
+                mv.visitVarInsn(ILOAD, index);
+                mv.visitInsn(AALOAD);
+
+                loadArgs(mv, ACC_PUBLIC, Type.getArgumentTypes(desc));
+
+                mv.visitMethodInsn(INVOKEINTERFACE, delegator.getSpecification().getName().replace('.', '/'), name, desc);
+
+                Label l4b = new Label();
+                mv.visitLabel(l4b);
+                mv.visitIincInsn(index, 1); // i++;
+
+                // Condition
+                mv.visitLabel(l2b);
+                mv.visitVarInsn(ILOAD, index);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "[L" + delegator.getSpecification().getName().replace('.', '/') + ";");
+                mv.visitInsn(ARRAYLENGTH);
+                mv.visitJumpInsn(IF_ICMPLT, l3b);
+
+                Label l5b = new Label();
+                mv.visitLabel(l5b);
+                mv.visitInsn(RETURN);
+            }
+        } else {
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "L" + delegator.getSpecification().getName().replace('.', '/') + ";");
+
+            loadArgs(mv, ACC_PUBLIC, Type.getArgumentTypes(desc));
+
+            // Invoke
+            if (delegator.getSpecification().isInterface()) {
+                mv.visitMethodInsn(INVOKEINTERFACE, delegator.getSpecification().getName().replace('.', '/'), name, desc);
+            } else {
+                mv.visitMethodInsn(INVOKEVIRTUAL, delegator.getSpecification().getName().replace('.', '/'), name, desc);
+            }
+
+            // Return
+            mv.visitInsn(Type.getReturnType(desc).getOpcode(IRETURN));
+        }
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    /**
+     * Generate Optional Case for aggregate field.
+     * @param mv : method visitor
+     * @param delegator : Field on which delegate
+     * @param className : current class name
+     */
+    private static void generateOptionalAggregateCase(MethodVisitor mv, FieldMetadata delegator, String className) {
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "[L" + delegator.getSpecification().getName().replace('.', '/') + ";");
+        mv.visitInsn(ARRAYLENGTH);
+        Label l1a = new Label();
+        mv.visitJumpInsn(IFNE, l1a);
+        Label l2a = new Label();
+        mv.visitLabel(l2a);
+        mv.visitTypeInsn(NEW, "java/lang/UnsupportedOperationException");
+        mv.visitInsn(DUP);
+        mv.visitLdcInsn("Operation not supported");
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>", "(Ljava/lang/String;)V");
+        mv.visitInsn(ATHROW);
+        mv.visitLabel(l1a);
+    }
+
+    /**
+     * Generate Optional case for non aggregate fields.
+     * 
+     * @param mv : the method visitor
+     * @param delegator : the field on which delegate.
+     * @param className : the name of the current class.
+     */
+    private static void generateOptionalCase(MethodVisitor mv, FieldMetadata delegator, String className) {
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, className, delegator.getName(), "L" + delegator.getSpecification().getName().replace('.', '/') + ";");
+        mv.visitTypeInsn(INSTANCEOF, "org/apache/felix/ipojo/Nullable");
+        Label end = new Label();
+        mv.visitJumpInsn(IFEQ, end);
+        Label begin = new Label();
+        mv.visitLabel(begin);
+        mv.visitTypeInsn(NEW, "java/lang/UnsupportedOperationException");
+        mv.visitInsn(DUP);
+        mv.visitLdcInsn("Operation not supported");
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>", "(Ljava/lang/String;)V");
+        mv.visitInsn(ATHROW);
+        mv.visitLabel(end);
+    }
+    
+    /**
+     * Load on stack the method arguments.
+     * @param mv method visitor
+     * @param access access level of the method
+     * @param args argument types array
+     */
+    private static void loadArgs(MethodVisitor mv, int access, Type[] args) {
+        int i = 0;
+        int j = args.length;
+        int k = getArgIndex(access, args, i);
+        for (int l = 0; l < j; l++) {
+            Type type = args[i + l];
+            mv.visitVarInsn(type.getOpcode(ILOAD), k);
+            k += type.getSize();
+        }
+    }
+    
+    /**
+     * Gets the index of the argument 'i'.
+     * This method manages double-spaces.
+     * @param access method access (mostly public)
+     * @param args argument type array
+     * @param i wanted index
+     * @return the real index
+     */
+    private static int getArgIndex(int access, Type[] args, int i) {
+        int j = (access & 8) != 0 ? 0 : 1;
+        for (int k = 0; k < i; k++) {
+            j += args[k].getSize();
+        }
+        return j;
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
new file mode 100644
index 0000000..48ead7d
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedService.java
@@ -0,0 +1,236 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.composite.CompositeManager;
+import org.apache.felix.ipojo.composite.instance.InstanceHandler;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.apache.felix.ipojo.util.DependencyStateListener;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+
+/**
+ * Composite Provided Service.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProvidedService implements DependencyStateListener {
+
+    /**
+     * Composite Manager.
+     */
+    private CompositeManager m_manager;
+
+    /**
+     * Composition Model.
+     */
+    private CompositionMetadata m_composition;
+
+    /**
+     * Internal context.
+     */
+    private ServiceContext m_scope;
+
+    /**
+     * External context.
+     */
+    private BundleContext m_context;
+
+    /**
+     * Created Factory.
+     */
+    private ComponentFactory m_factory;
+
+    /**
+     * Created Instance.
+     */
+    private ComponentInstance m_instance;
+
+    /**
+     * Exporter.
+     */
+    private ServiceExporter m_exports;
+
+    /**
+     * Created instance name.
+     */
+    private String m_instanceName;
+
+    /**
+     * Constructor.
+     * The delegation mapping is infers in this method.
+     * @param handler : the handler.
+     * @param element : 'provides' element.
+     * @param name : name of this provided service.
+     */
+    public ProvidedService(ProvidedServiceHandler handler, Element element, String name) {
+        m_manager = handler.getCompositeManager();
+        m_scope = m_manager.getServiceContext();
+        m_context = m_manager.getContext();
+        m_composition = new CompositionMetadata(m_manager.getContext(), element, handler, name);
+    }
+
+    /**
+     * Start method.
+     * Build service implementation type, factory and instance.
+     * @throws CompositionException if a consistent mapping cannot be discovered.
+     */
+    public void start() throws CompositionException {
+        m_composition.buildMapping();
+
+        m_instanceName = m_composition.getSpecificationMetadata().getName() + "Provider-Gen";
+        byte[] clazz = m_composition.buildPOJO();
+        Element metadata = m_composition.buildMetadata(m_instanceName);
+
+        // Create the factory
+        try {
+            m_factory = new ComponentFactory(m_context, clazz, metadata);
+            m_factory.start();
+        } catch (ConfigurationException e) {
+            // Should not happen.
+            m_manager.getFactory().getLogger().log(Logger.ERROR, "A factory cannot be created", e);
+        }
+
+        try {
+            Class spec = DependencyModel.loadSpecification(m_composition.getSpecificationMetadata().getName(), m_context);
+            Filter filter = m_context.createFilter("(instance.name=" + m_instanceName + ")");
+            // Create the exports
+            m_exports = new ServiceExporter(spec, filter, false, false, null, DependencyModel.DYNAMIC_BINDING_POLICY, m_scope, m_context, this, m_manager);
+        } catch (InvalidSyntaxException e) {
+            throw new CompositionException("A provided service filter is invalid : " + e.getMessage());
+        } catch (ConfigurationException e) {
+            throw new CompositionException("The class " + m_composition.getSpecificationMetadata().getName() + " cannot be loaded : " + e.getMessage());
+        }
+    }
+
+    /**
+     * Stop the provided service.
+     * Kill the exporter, the instance and the factory.
+     */
+    public void stop() {
+        if (m_exports != null) {
+            m_exports.stop();
+            m_exports = null;
+        }
+        if (m_instance != null) {
+            m_instance.dispose();
+            m_instance = null;
+        }
+        if (m_factory != null) {
+            m_factory.stop();
+            m_factory = null;
+        }
+    }
+
+    protected CompositeManager getManager() {
+        return m_manager;
+    }
+
+    /**
+     * The exporter becomes valid.
+     * @param exporter : the exporter
+     */
+    public void validate(DependencyModel exporter) {
+        // Nothing to do.
+    }
+
+    /**
+     * The exporter becomes invalid.
+     * @param exporter : the exporter
+     */
+    public void invalidate(DependencyModel exporter) {
+        // Nothing to do.
+    }
+
+    /**
+     * Get an object from the given type.
+     * @param type : type
+     * @return an object from an instance of this type or null
+     */
+    private Object getObjectByType(String type) {
+        InstanceHandler handler = (InstanceHandler) m_manager.getCompositeHandler("org.apache.felix.ipojo.composite.instance.InstanceHandler");
+        Object pojo = handler.getObjectFromInstance(type);
+        if (pojo == null) {
+            m_manager.getFactory().getLogger().log(Logger.ERROR, "An instance object cannot be found for the type : " + type);
+        }
+        return pojo;
+    }
+
+    public String getSpecification() {
+        return m_composition.getSpecificationMetadata().getName();
+    }
+
+    /**
+     * Unregister the exposed service.
+     */
+    public void unregister() {
+        m_exports.stop();
+    }
+
+    /**
+     * Register the exposed service.
+     */
+    public void register() {
+        Properties props = new Properties();
+        props.put("instance.name", m_instanceName);
+        List fields = m_composition.getFieldList();
+        for (int i = 0; i < fields.size(); i++) {
+            FieldMetadata field = (FieldMetadata) fields.get(i);
+            if (field.isUseful() && !field.getSpecification().isInterface()) {
+                String type = field.getSpecification().getComponentType();
+                Object pojo = getObjectByType(type);
+                props.put(field.getName(), pojo);
+            }
+        }
+
+        if (m_instance == null) {
+         // Else we have to create the instance 
+            try {
+                m_instance = m_factory.createComponentInstance(props, m_manager.getServiceContext());
+            } catch (UnacceptableConfiguration e) {
+                throw new IllegalStateException("Cannot create the service implementation : " + e.getMessage());
+            } catch (MissingHandlerException e) {
+                throw new IllegalStateException("Cannot create the service implementation : " + e.getMessage());
+            } catch (ConfigurationException e) {
+                throw new IllegalStateException("Cannot create the service implementation : " + e.getMessage());
+            }
+        } else {
+            // We have to reconfigure the instance in order to inject up to date glue component instance.
+            m_instance.reconfigure(props);
+        }
+        
+        m_exports.start();
+    }
+
+    public boolean isRegistered() {
+        return m_exports.getState() == DependencyModel.RESOLVED;
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
new file mode 100644
index 0000000..2c82005
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandler.java
@@ -0,0 +1,503 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Comparator;
+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.HandlerFactory;
+import org.apache.felix.ipojo.HandlerManager;
+import org.apache.felix.ipojo.MissingHandlerException;
+import org.apache.felix.ipojo.PolicyServiceContext;
+import org.apache.felix.ipojo.UnacceptableConfiguration;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.composite.instance.InstanceHandler;
+import org.apache.felix.ipojo.composite.service.instantiator.ServiceDependencyHandler;
+import org.apache.felix.ipojo.composite.service.instantiator.ServiceImporter;
+import org.apache.felix.ipojo.composite.service.instantiator.SvcInstance;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.apache.felix.ipojo.util.DependencyStateListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Composite Provided Service Handler.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProvidedServiceHandler extends CompositeHandler implements DependencyStateListener {
+
+    /**
+     * External context.
+     */
+    private BundleContext m_context;
+    
+    /**
+     * List of "available" services in the internal context.
+     */
+    private List m_services = new ArrayList();
+
+    /**
+     * List of exporters.
+     */
+    private List m_exporters = new ArrayList();
+
+    /**
+     * List of managed services.
+     */
+    private List m_managedServices = new ArrayList();
+
+    /**
+     * List of component type.
+     */
+    private List m_types;
+    
+    /**
+     * Handler description.
+     */
+    private ProvidedServiceHandlerDescription m_description;
+
+    /**
+     * Initialize the component type.
+     * @param desc : component type description to populate.
+     * @param metadata : component type metadata.
+     * @throws ConfigurationException : metadata are incorrect.
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
+     */
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
+        Element[] provides = metadata.getElements("provides");
+        for (int i = 0; i < provides.length; i++) {
+            String action = provides[i].getAttribute("action");
+            if (action == null) {
+                throw new ConfigurationException("Invalid composition service providing : no specified action");
+            } else if (action.equalsIgnoreCase("implement")) {
+                String spec = provides[i].getAttribute("specification");
+                if (spec == null) {
+                    throw new ConfigurationException("Malformed provides : the specification attribute is mandatory");
+                } else {
+                    desc.addProvidedServiceSpecification(spec);
+                }
+            } else if (action.equalsIgnoreCase("export")) {
+                String spec = provides[i].getAttribute("specification");
+                if (spec == null) {
+                    throw new ConfigurationException("Malformed exports - Missing the specification attribute");
+                } else {
+                    desc.addProvidedServiceSpecification(spec);
+                }
+            } else {
+                throw new ConfigurationException("Invalid composition service providing : unknown action " + action);
+            }
+        }
+    }
+
+    /**
+     * Configure the handler.
+     * @param metadata : the metadata of the component
+     * @param configuration : the instance configuration
+     * @throws ConfigurationException  : the exporter cannot be created
+     * @see org.apache.felix.ipojo.CompositeHandler#configure(org.apache.felix.ipojo.CompositeManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+        m_context = getCompositeManager().getContext();
+
+        Element[] provides = metadata.getElements("provides", "");
+        for (int i = 0; i < provides.length; i++) {
+            String action = provides[i].getAttribute("action");
+            if (action.equalsIgnoreCase("implement")) {
+                ProvidedService svc = new ProvidedService(this, provides[i], Integer.toString(i));
+                m_managedServices.add(svc);
+            } else if (action.equalsIgnoreCase("export")) {
+                boolean optional = false;
+                boolean aggregate = false;
+                String specification = provides[i].getAttribute("specification");
+
+                String filter = "(objectClass=" + specification + ")";
+
+                String opt = provides[i].getAttribute("optional");
+                optional = opt != null && opt.equalsIgnoreCase("true");
+
+                String agg = provides[i].getAttribute("aggregate");
+                aggregate = agg != null && agg.equalsIgnoreCase("true");
+
+                String givenFilter = provides[i].getAttribute("filter");
+                if (givenFilter != null) {
+                    filter = "(&" + filter + givenFilter + ")"; //NOPMD
+                }
+
+                Filter fil = null;
+                try {
+                    fil = m_context.createFilter(filter);
+                } catch (InvalidSyntaxException e) {
+                    throw new ConfigurationException("An exporter filter is invalid " + filter + " : " + e.getMessage());
+                }
+
+                Comparator cmp = DependencyModel.getComparator(provides[i], m_context);
+                int policy = DependencyModel.getPolicy(provides[i]);
+                Class spec = DependencyModel.loadSpecification(specification, m_context);
+
+                ServiceExporter imp = new ServiceExporter(spec, fil, aggregate, optional, cmp, policy, getCompositeManager().getServiceContext(), m_context, this, getCompositeManager());
+                m_exporters.add(imp);
+            } // Others case cannot happen. The test was already made during the factory initialization.
+        }
+        
+        m_description = new ProvidedServiceHandlerDescription(this, m_managedServices, m_exporters);
+
+    }
+
+    /**
+     * Start method.
+     * Start all managed provided service.
+     * @see org.apache.felix.ipojo.CompositeHandler#start()
+     */
+    public void start() {
+        // Compute imports and instances
+        computeAvailableServices();
+        computeAvailableTypes();
+
+        for (int i = 0; i < m_managedServices.size(); i++) {
+            ProvidedService svc = (ProvidedService) m_managedServices.get(i);
+            try {
+                checkServiceSpecification(svc);
+                svc.start();
+            } catch (CompositionException e) {
+                error("Cannot start the provided service handler", e);
+                setValidity(false);
+                return;
+            }
+        }
+
+        for (int i = 0; i < m_exporters.size(); i++) {
+            ServiceExporter exp = (ServiceExporter) m_exporters.get(i);
+            exp.start();
+        }
+
+        isHandlerValid();
+    }
+
+    /**
+     * Stop method.
+     * Stop all managed provided service.
+     * @see org.apache.felix.ipojo.CompositeHandler#stop()
+     */
+    public void stop() {
+        for (int i = 0; i < m_managedServices.size(); i++) {
+            ProvidedService svc = (ProvidedService) m_managedServices.get(i);
+            svc.stop();
+        }
+
+        for (int i = 0; i < m_exporters.size(); i++) {
+            ServiceExporter exp = (ServiceExporter) m_exporters.get(i);
+            exp.stop();
+        }
+    }
+
+    /**
+     * Check the handler validity.
+     * @see org.apache.felix.ipojo.CompositeHandler#isValid()
+     */
+    private void isHandlerValid() {
+        for (int i = 0; i < m_exporters.size(); i++) {
+            ServiceExporter exp = (ServiceExporter) m_exporters.get(i);
+            if (exp.getState() != DependencyModel.RESOLVED) {
+                setValidity(false);
+                return;
+            }
+        }
+
+        setValidity(true);
+    }
+
+    /**
+     * Handler state changed.
+     * @param state : the new instance state.
+     * @see org.apache.felix.ipojo.CompositeHandler#stateChanged(int)
+     */
+    public void stateChanged(int state) {
+        if (state == ComponentInstance.INVALID) {
+            for (int i = 0; i < m_managedServices.size(); i++) {
+                ProvidedService svc = (ProvidedService) m_managedServices.get(i);
+                svc.unregister();
+            }
+            return;
+        }
+
+        // If the new state is VALID => register all the services
+        if (state == ComponentInstance.VALID) {
+            for (int i = 0; i < m_managedServices.size(); i++) {
+                ProvidedService svc = (ProvidedService) m_managedServices.get(i);
+                svc.register();
+            }
+            return;
+        }
+    }
+
+    /**
+     * Notify the handler that an exporter becomes invalid.
+     * 
+     * @param exporter : the implicated exporter.
+     */
+    public void invalidate(DependencyModel exporter) {
+        // An export is no more valid
+        if (getValidity()) {
+            setValidity(false);
+        }
+
+    }
+
+    /**
+     * Notify the handler that an exporter becomes valid.
+     * 
+     * @param exporter : the implicated exporter.
+     */
+    public void validate(DependencyModel exporter) {
+        // An import becomes valid
+        if (!getValidity()) {
+            isHandlerValid();
+        }
+    }
+
+    /**
+     * Build the list of available specification.
+     * @return the list of available specification.
+     */
+    protected List getSpecifications() {
+        return m_services;
+    }
+
+    /**
+     * Build the list of available specifications.
+     */
+    private void computeAvailableServices() {
+        // Get instantiated services :
+        ServiceDependencyHandler handler = (ServiceDependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":subservice");
+
+        for (int i = 0; handler != null && i < handler.getInstances().size(); i++) {
+            SvcInstance svc = (SvcInstance) handler.getInstances().get(i);
+            String itf = svc.getServiceSpecification();
+            boolean agg = svc.isAggregate();
+            boolean opt = svc.isOptional();
+
+            SpecificationMetadata specMeta = new SpecificationMetadata(itf, m_context, agg, opt, this);
+            m_services.add(specMeta);
+        }
+
+        for (int i = 0; handler != null && i < handler.getRequirements().size(); i++) {
+            ServiceImporter imp = (ServiceImporter) handler.getRequirements().get(i);
+            String itf = imp.getSpecification().getName();
+            boolean agg = imp.isAggregate();
+            boolean opt = imp.isOptional();
+
+            SpecificationMetadata specMeta = new SpecificationMetadata(itf, m_context, agg, opt, this);
+            m_services.add(specMeta);
+        }
+    }
+
+    /**
+     * Check composite requirement against service specification requirement is available.
+     * @param svc : the provided service to check
+     * @throws CompositionException : occurs if the specification field of the service specification cannot be analyzed correctly.
+     */
+    private void checkServiceSpecification(ProvidedService svc) throws CompositionException {
+        try {
+            Class spec = m_context.getBundle().loadClass(svc.getSpecification());
+            Field specField = spec.getField("specification");
+            Object object = specField.get(null);
+            if (object instanceof String) {
+                Element specification = ManifestMetadataParser.parse((String) object);
+                Element[] reqs = specification.getElements("requires");
+                for (int j = 0; reqs != null && j < reqs.length; j++) {
+                    ServiceImporter imp = getAttachedRequirement(reqs[j]);
+                    if (imp != null) {
+                        // Fix service-level dependency flag
+                        imp.setServiceLevelDependency();
+                    }
+                    checkRequirement(imp, reqs[j]);
+                }
+            } else {
+                error("[" + getCompositeManager().getInstanceName() + "] The specification field of the service specification " + svc.getSpecification() + " needs to be a String");
+                throw new CompositionException("Service Specification checking failed : The specification field of the service specification " + svc.getSpecification() + " needs to be a String");
+            }
+        } catch (NoSuchFieldException e) {
+            return; // No specification field
+        } catch (ClassNotFoundException e) {
+            error("[" + getCompositeManager().getInstanceName() + "] The service specification " + svc.getSpecification() + " cannot be load");
+            throw new CompositionException("The service specification " + svc.getSpecification() + " cannot be load : " + e.getMessage());
+        } catch (IllegalArgumentException e) {
+            error("[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + svc.getSpecification() + " is not accessible : " + e.getMessage());
+            throw new CompositionException("The field 'specification' of the service specification " + svc.getSpecification() + " is not accessible : " + e.getMessage());
+        } catch (IllegalAccessException e) {
+            error("[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + svc.getSpecification() + " is not accessible : " + e.getMessage());
+            throw new CompositionException("The field 'specification' of the service specification " + svc.getSpecification() + " is not accessible : " + e.getMessage());
+        } catch (ParseException e) {
+            error("[" + getCompositeManager().getInstanceName() + "] The field 'specification' of the service specification " + svc.getSpecification() + " does not contain a valid String : " + e.getMessage());
+            throw new CompositionException("The field 'specification' of the service specification " + svc.getSpecification() + " does not contain a valid String : " + e.getMessage());
+        }
+    }
+
+    /**
+     * Look for the implementation (i.e. composite) requirement for the given service-level requirement metadata.
+     * @param element : the service-level requirement metadata
+     * @return the ServiceImporter object, null if not found or if the DependencyHandler is not plugged to the instance
+     */
+    private ServiceImporter getAttachedRequirement(Element element) {
+        ServiceDependencyHandler handler = (ServiceDependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":subservice");
+        if (handler == null) { return null; }
+
+        String identity = element.getAttribute("id");
+        if (identity != null) {
+            // Look for dependency Id
+            for (int i = 0; i < handler.getRequirements().size(); i++) {
+                ServiceImporter imp = (ServiceImporter) handler.getRequirements().get(i);
+                if (imp.getId().equals(identity)) { return imp; }
+            }
+        }
+
+        // If not found or no id, look for a dependency with the same specification
+        String requirement = element.getAttribute("specification");
+        for (int i = 0; i < handler.getRequirements().size(); i++) {
+            ServiceImporter imp = (ServiceImporter) handler.getRequirements().get(i);
+            if (imp.getId().equals(requirement) || imp.getSpecification().getName().equals(requirement)) { return imp; }
+        }
+        return null;
+    }
+
+    /**
+     * Check the correctness of the composite requirement against the service level dependency.
+     * @param imp : requirement to check
+     * @param elem : service-level dependency metadata
+     * @throws CompositionException : occurs if the requirement does not match with service-level specification requirement
+     */
+    private void checkRequirement(ServiceImporter imp, Element elem) throws CompositionException {
+        String optional = elem.getAttribute("optional");
+        boolean opt = optional != null && optional.equalsIgnoreCase("true");
+
+        String aggregate = elem.getAttribute("aggregate");
+        boolean agg = aggregate != null && aggregate.equalsIgnoreCase("true");
+
+        if (imp == null) {
+            // Add the missing requirement
+            ServiceDependencyHandler handler = (ServiceDependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":subservice");
+            if (handler == null) {
+                // Look for the ServiceDependencyHandler factory
+                HandlerManager handlerManager = null;
+                try {
+                    ServiceReference[] refs = m_context.getServiceReferences(Factory.class.getName(), "(&(handler.name=subservice)(handler.namespace=" + HandlerFactory.IPOJO_NAMESPACE + ")(handler.type=composite))");
+                    Factory factory = (Factory) m_context.getService(refs[0]);
+                    handlerManager = (HandlerManager) factory.createComponentInstance(null, getCompositeManager().getServiceContext());
+                } catch (InvalidSyntaxException e) {
+                    // Should not happen
+                } catch (UnacceptableConfiguration e) {
+                    // Should not happen
+                } catch (MissingHandlerException e) {
+                    // Should not happen
+                } catch (ConfigurationException e) {
+                    // Should not happen
+                }
+                
+                // Add the required handler 
+                try {
+                    handlerManager.init(getCompositeManager(), new Element("composite", ""), new Properties());
+                } catch (ConfigurationException e) {
+                    error("Internal error : cannot configure the Import Handler : " + e.getMessage());
+                    throw new CompositionException("Internal error : cannot configure the Import Handler : " + e.getMessage());
+                }
+                handler = (ServiceDependencyHandler) handlerManager.getHandler();
+                getCompositeManager().addCompositeHandler(handlerManager);
+            }
+
+            String spec = elem.getAttribute("specification");
+            String filter = "(&(objectClass=" + spec + ")(!(instance.name=" + getCompositeManager().getInstanceName() + ")))"; // Cannot import yourself
+            String givenFilter = elem.getAttribute("filter");
+            if (givenFilter != null) {
+                filter = "(&" + filter + givenFilter + ")"; //NOPMD
+            }
+
+            BundleContext context = new PolicyServiceContext(getCompositeManager().getGlobalContext(), getCompositeManager().getParentServiceContext(), PolicyServiceContext.GLOBAL);
+
+            Filter fil = null;
+            try {
+                fil = getCompositeManager().getGlobalContext().createFilter(filter);
+            } catch (InvalidSyntaxException e) {
+                throw new CompositionException("A required filter " + filter + " is malformed : " + e.getMessage());
+            }
+
+            Class specToImport = null;
+            try {
+                specToImport = getCompositeManager().getGlobalContext().getBundle().loadClass(spec);
+            } catch (ClassNotFoundException e) {
+                throw new CompositionException("A required specification cannot be loaded : " + spec);
+            }
+
+            ServiceImporter importer = new ServiceImporter(specToImport, fil, agg, opt, null, DependencyModel.DYNAMIC_BINDING_POLICY, context, null, handler);
+
+            handler.getRequirements().add(importer);
+            SpecificationMetadata specMeta = new SpecificationMetadata(spec, m_context, agg, opt, this);
+            m_services.add(specMeta); // Update the available types
+            return;
+        }
+
+        if (imp.isAggregate() && !agg) {
+            error("[" + getCompositeManager().getInstanceName() + "] The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
+            throw new CompositionException("The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
+        }
+
+        String filter = elem.getAttribute("filter");
+        if (filter != null) {
+            String filter2 = imp.getFilter();
+            if (filter2 == null || !filter2.equalsIgnoreCase(filter)) {
+                error("[" + getCompositeManager().getInstanceName() + "] The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
+                throw new CompositionException("The specification requirement " + elem.getAttribute("specification") + " as not the same filter as declared in the service-level requirement");
+            }
+        }
+    }
+
+    public HandlerDescription getDescription() {
+        return m_description;
+    }
+
+    /**
+     * Build available instance types.
+     */
+    private void computeAvailableTypes() {
+        InstanceHandler handler = (InstanceHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":instance");
+        if (handler == null) {
+            m_types = new ArrayList();
+        } else {
+            m_types = handler.getUsedType();
+        }
+    }
+
+    public List getInstanceType() {
+        return m_types;
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
new file mode 100644
index 0000000..5c22246
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ProvidedServiceHandlerDescription.java
@@ -0,0 +1,96 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.composite.CompositeHandler;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.DependencyModel;
+
+/**
+ * Provided Service Handler Description for composite.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProvidedServiceHandlerDescription extends HandlerDescription {
+
+    /**
+     * Provided Service Description list.
+     */
+    private List m_services = new ArrayList();
+    
+    /**
+     * List of exports.
+     */
+    private List m_exports;
+
+    /**
+     * Constructor.
+     * 
+     * @param handler : composite handler.
+     * @param services : The list of Provided Service.
+     * @param exporters : list of managed exports
+     */
+    public ProvidedServiceHandlerDescription(CompositeHandler handler, List services, List exporters) {
+        super(handler);
+        m_services = services;
+        m_exports = exporters;
+    }
+
+    /**
+     * Get the handler description.
+     * @return the provided service handler description
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element services = super.getHandlerInfo();
+        for (int i = 0; i < m_services.size(); i++) {
+            ProvidedService svc = (ProvidedService) m_services.get(i);
+            Element service = new Element("service", "");
+            String state = "unregistered";
+            if (svc.isRegistered()) {
+                state = "registered";
+            }
+            String spec = "[" + svc.getSpecification() + "]";
+            service.addAttribute(new Attribute("Specification", spec));
+            service.addAttribute(new Attribute("State", state));
+            services.addElement(service);
+        }
+        
+        for (int i = 0; i < m_exports.size(); i++) {
+            ServiceExporter exp = (ServiceExporter) m_exports.get(i);
+            Element expo = new Element("Exports", "");
+            expo.addAttribute(new Attribute("Specification", exp.getSpecification().getName()));
+            expo.addAttribute(new Attribute("Filter", exp.getFilter()));
+            if (exp.getState() == DependencyModel.RESOLVED) {
+                expo.addAttribute(new Attribute("State", "resolved"));
+            } else {
+                expo.addAttribute(new Attribute("State", "unresolved"));
+            }
+            services.addElement(expo);
+        }
+        
+        return services;
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
new file mode 100644
index 0000000..bb0b14f
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/ServiceExporter.java
@@ -0,0 +1,176 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.composite.CompositeManager;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.apache.felix.ipojo.util.DependencyStateListener;
+import org.apache.felix.ipojo.util.SecurityHelper;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Export an service from the scope to the parent context.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceExporter extends DependencyModel {
+
+    /**
+     * Destination context.
+     */
+    private BundleContext m_destination;
+
+    /**
+     * Composite Manager.
+     */
+    private CompositeManager m_manager;
+
+    /**
+     * Map of service reference - service registration storing exported services.
+     */
+    private Map/*<ServiceReference, ServiceRegistration>*/m_registrations = new HashMap();
+
+    /**
+     * Constructor.
+     * 
+     * @param specification : exported service specification.
+     * @param filter : LDAP filter
+     * @param multiple : is the export an aggregate export?
+     * @param optional : is the export optional?
+     * @param cmp : comparator to use in the dependency
+     * @param policy : binding policy.
+     * @param from : internal service context
+     * @param dest : parent bundle context
+     * @param listener : dependency lifecycle listener to notify when the dependency state change. 
+     * @param manager : composite manager
+     */
+    public ServiceExporter(Class specification, Filter filter, boolean multiple, boolean optional, Comparator cmp, int policy, ServiceContext from, BundleContext dest, DependencyStateListener listener, CompositeManager manager) {
+        super(specification, multiple, optional, filter, cmp, policy, from, listener, manager);
+
+        m_destination = dest;
+
+        m_manager = manager;
+
+    }
+
+    /**
+     * Transform service reference property in a dictionary.
+     * instance.name and factory.name are injected too.
+     * @param ref : the service reference.
+     * @return the dictionary containing all property of the given service reference.
+     */
+    private Dictionary getProps(ServiceReference ref) {
+        Properties prop = new Properties();
+        String[] keys = ref.getPropertyKeys();
+        for (int i = 0; i < keys.length; i++) {
+            prop.put(keys[i], ref.getProperty(keys[i]));
+        }
+
+        prop.put("instance.name", m_manager.getInstanceName());
+        prop.put("factory.name", m_manager.getFactory().getName());
+
+        return prop;
+    }
+
+    /**
+     * Stop an exporter.
+     * Remove the service listener
+     * Unregister all exported services.
+     */
+    public void stop() {
+        super.stop();
+        Set refs = m_registrations.keySet();
+        Iterator iterator = refs.iterator();
+        while (iterator.hasNext()) {
+            ServiceReference ref = (ServiceReference) iterator.next();
+            ServiceRegistration reg = (ServiceRegistration) m_registrations.get(ref);
+            try {
+                reg.unregister();
+            } catch (IllegalStateException e) {
+                // The service is already unregistered
+                // Do nothing silently
+            }
+        }
+        m_registrations.clear();
+    }
+
+    /**
+     * A service has been injected. Register it.
+     * @param reference : the new reference.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceArrival(ServiceReference reference) {
+        Object svc = getService(reference);
+        // Security Check
+        if (SecurityHelper.hasPermissionToRegisterService(getSpecification().getName(), m_destination)) {
+            ServiceRegistration reg = m_destination
+                .registerService(getSpecification().getName(), svc, getProps(reference));
+            m_registrations.put(reference, reg);
+        } else {
+            throw new SecurityException("The bundle " + m_destination.getBundle().getBundleId() + " does not have the "
+                    + "permission to register the service " + getSpecification().getName());
+        }
+    }
+
+    /**
+     * An exported service was modified.
+     * @param reference : modified reference
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void onServiceModification(ServiceReference reference) {
+        ServiceRegistration reg = (ServiceRegistration) m_registrations.get(reference);
+        if (reg != null) {
+            reg.setProperties(getProps(reference));
+        }
+    }
+
+    /**
+     * An exported service disappears.
+     * @param reference : service reference
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void onServiceDeparture(ServiceReference reference) {
+        ServiceRegistration reg = (ServiceRegistration) m_registrations.get(reference);
+        if (reg != null) {
+            reg.unregister();
+        }
+        m_registrations.remove(reference);
+    }
+
+    /**
+     * On Dependency Reconfiguration notification method.
+     * @param departs : leaving service references.
+     * @param arrivals : new injected service references.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])
+     */
+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {
+        throw new UnsupportedOperationException("Dynamic dependency reconfiguration is not supported by service exporter");
+    }
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
new file mode 100644
index 0000000..392de87
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/service/provides/SpecificationMetadata.java
@@ -0,0 +1,158 @@
+/* 
+ * 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.composite.service.provides;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.framework.BundleContext;
+
+/**
+ * Represent a service specification.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SpecificationMetadata {
+
+    /**
+     * Name of the specification, i.e. name of the interface.
+     */
+    private String m_name;
+
+    /**
+     * List of the method contained in the specification.
+     */
+    private List/* <MethodMetadata> */m_methods = new ArrayList/* <MethodMetadata> */();
+
+    /**
+     * Is the specification an aggregate?
+     */
+    private boolean m_isAggregate;
+
+    /**
+     * Is the specification optional?
+     */
+    private boolean m_isOptional = false;
+
+    /**
+     * Is the specification an interface?
+     */
+    private boolean m_isInterface = true;
+
+    /**
+     * Component Type.
+     */
+    private String m_componentType = null;
+
+    /**
+     * Reference on the handler.
+     */
+    private ProvidedServiceHandler m_handler;
+
+    /**
+     * Constructor.
+     * @param name : specification name.
+     * @param context : bundle context.
+     * @param isAggregate : is the specification aggregate.
+     * @param isOptional : is the specification optional.
+     * @param psd : the handler.
+     */
+    public SpecificationMetadata(String name, BundleContext context, boolean isAggregate, boolean isOptional, ProvidedServiceHandler psd) {
+        m_name = name;
+        m_handler = psd;
+
+        // Populate methods :
+        try {
+            Class clazz = context.getBundle().loadClass(name);
+            Method[] methods = clazz.getMethods();
+            for (int i = 0; i < methods.length; i++) {
+                MethodMetadata method = new MethodMetadata(methods[i]);
+                m_methods.add(method);
+            }
+        } catch (ClassNotFoundException e) {
+            m_handler.error("Cannot open " + name + " : " + e.getMessage());
+            return;
+        }
+
+        m_isAggregate = isAggregate;
+        m_isOptional = isOptional;
+    }
+
+    /**
+     * Constructor.
+     * @param clazz : class
+     * @param type : component type
+     * @param psd : the parent handler
+     */
+    public SpecificationMetadata(Class clazz, String type, ProvidedServiceHandler psd) {
+        m_handler = psd;
+        m_isAggregate = false;
+        m_isOptional = false;
+        m_componentType = type;
+        m_name = clazz.getName();
+        Method[] methods = clazz.getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            MethodMetadata method = new MethodMetadata(methods[i]);
+            m_methods.add(method);
+        }
+        m_isInterface = false;
+    }
+
+    public String getName() {
+        return m_name;
+    }
+
+    public List/* <MethodMetadata> */getMethods() {
+        return m_methods;
+    }
+
+    /**
+     * Get a method by its name.
+     * @param name : method name
+     * @return the method metadata contained in the current specification with the given name. Null if the method is not found.
+     */
+    public MethodMetadata getMethodByName(String name) {
+        for (int i = 0; i < m_methods.size(); i++) {
+            MethodMetadata met = (MethodMetadata) m_methods.get(i);
+            if (met.getMethod().getName().equals(name)) { return met; }
+        }
+        return null;
+    }
+
+    public boolean isAggregate() {
+        return m_isAggregate;
+    }
+
+    public boolean isOptional() {
+        return m_isOptional;
+    }
+
+    public boolean isInterface() {
+        return m_isInterface;
+    }
+
+    public void setIsOptional(boolean optional) {
+        m_isOptional = optional;
+    }
+
+    public String getComponentType() {
+        return m_componentType;
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/util/SourceManager.java b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/util/SourceManager.java
new file mode 100644
index 0000000..d7f227a
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/java/org/apache/felix/ipojo/composite/util/SourceManager.java
@@ -0,0 +1,376 @@
+/* 
+ * 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.composite.util;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.ContextListener;
+import org.apache.felix.ipojo.ContextSource;
+import org.apache.felix.ipojo.composite.CompositeManager;
+import org.apache.felix.ipojo.parser.ParseUtils;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * This class manages context-source management.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SourceManager implements ContextListener {
+
+    /**
+     * Source Name service property.
+     */
+    public static final String SOURCE_NAME = "source.name";
+
+    /**
+     * Managed dependency.
+     */
+    private DependencyModel m_dependency;
+
+    /**
+     * List of monitored context sources.
+     */
+    private List/* <ContextSource> */m_sources = new ArrayList(1);
+
+    /**
+     * PRoperties contained in the original filter.
+     */
+    private String[] m_properties;
+
+    /**
+     * Original filter (containing variables). 
+     */
+    private String m_filter;
+
+    /**
+     * Bundle context.
+     */
+    private BundleContext m_context;
+
+    /**
+     * Service Tracker List.
+     */
+    private List/*<SourceTracker>*/m_trackers = new ArrayList(1);
+
+    /**
+     * Constructor.
+     * @param sources : context-source attribute from the dependency metadata
+     * @param depfilter : original dependency filter
+     * @param dependency : dependency object
+     * @param manager : composite manager
+     * @throws ConfigurationException : the sources are incorrect.
+     */
+    public SourceManager(String sources, String depfilter, DependencyModel dependency, CompositeManager manager) throws ConfigurationException {
+        m_filter = depfilter;
+        m_properties = getProperties(depfilter);
+        m_dependency = dependency;
+        m_context = manager.getGlobalContext();
+        if (manager.getParentServiceContext() == null) {
+            // The parent is the global context
+            parseSources(sources, manager.getGlobalContext(), manager.getGlobalContext(), manager.getServiceContext());
+        } else {
+            parseSources(sources, manager.getGlobalContext(), manager.getParentServiceContext(), manager.getServiceContext());
+        }
+    }
+
+    /**
+     * Start the context management.
+     */
+    public void start() {
+        for (int i = 0; i < m_trackers.size(); i++) {
+            ((SourceTracker) m_trackers.get(i)).open();
+        }
+        computeFilter();
+    }
+
+    /**
+     * Stop the context management.
+     */
+    public void stop() {
+        for (int i = 0; i < m_trackers.size(); i++) {
+            ((SourceTracker) m_trackers.get(i)).close();
+        }
+        setFilter(m_filter);
+        m_sources.clear();
+    }
+
+    /**
+     * Get the state of this source manager.
+     * @return the state of this source manager.
+     */
+    public int getState() {
+        if (m_sources.isEmpty()) {
+            return DependencyModel.UNRESOLVED;
+        } else {
+            return DependencyModel.RESOLVED;
+        }
+    }
+
+    /**
+     * Set the filter of the managed dependency.
+     * @param filter : the new filter to apply
+     */
+    private void setFilter(String filter) {
+        if (!filter.equals(m_dependency.getFilter())) {
+            // Reconfigure
+            try {
+                m_dependency.setFilter(m_context.createFilter(filter));
+            } catch (InvalidSyntaxException e) {
+                throw new IllegalStateException("A context filter is invalid : " + filter);
+            }
+        }
+    }
+
+    /**
+     * Compute the new filter.
+     */
+    private void computeFilter() {
+        String fil = m_filter;
+        synchronized (this) {
+            for (int i = 0; i < m_sources.size(); i++) {
+                Dictionary props = ((ContextSource) m_sources.get(i)).getContext();
+                fil = substitute(fil, props); //NOPMD
+            }
+        }
+        if (!fil.equals(m_dependency.getFilter())) {
+            setFilter(fil);
+        }
+    }
+
+    /**
+     * This method substitute ${var} substring by values stored in a map.
+     * @param str : string with variables
+     * @param values : dictionary containing the variable name and the value.
+     * @return resulted string
+     */
+    public static String substitute(String str, Dictionary values) {       
+        int len = str.length();
+        StringBuffer buffer = new StringBuffer(len);
+
+        int prev = 0;
+        int start = str.indexOf("${");
+        int end = str.indexOf('}', start);
+        while (start != -1 && end != -1) {
+            String key = str.substring(start + 2, end);
+            Object value = values.get(key);
+            if (value == null) {
+                buffer.append(str.substring(prev, end + 1));
+            } else {
+                buffer.append(str.substring(prev, start));
+                buffer.append(value);
+            }
+            prev = end + 1;
+            if (prev >= str.length()) {
+                break;
+            }
+
+            start = str.indexOf("${", prev);
+            if (start != -1) {
+                end = str.indexOf('}', start);
+            }
+        }
+
+        buffer.append(str.substring(prev));
+
+        return buffer.toString();
+    }
+
+    /**
+     * Compute the properties (${name}) from the given filter.
+     * @param str : string form of the filter.
+     * @return the list of found properties.
+     */
+    public static String[] getProperties(String str) {
+        List list = new ArrayList();
+        int prev = 0;
+        int start = str.indexOf("${");
+        int end = str.indexOf('}', start);
+        while (start != -1 && end != -1) {
+            String key = str.substring(start + 2, end);
+            list.add(key);
+            prev = end + 1;
+            if (prev >= str.length()) {
+                break;
+            }
+
+            start = str.indexOf("${", prev);
+            if (start != -1) {
+                end = str.indexOf('}', start);
+            }
+        }
+
+        return (String[]) list.toArray(new String[list.size()]);
+    }
+
+    /**
+     * A context source has modified a monitored property. 
+     * @param source : source
+     * @param property : modified property
+     * @param value : new value.
+     * @see org.apache.felix.ipojo.ContextListener#update(org.apache.felix.ipojo.ContextSource, java.lang.String, java.lang.Object)
+     */
+    public synchronized void update(ContextSource source, String property, Object value) {
+        computeFilter();
+    }
+
+    /**
+     * Parse the context-source attribute in order to create source tracker object.
+     * @param sourceAtt : context-source attribute.
+     * @param global : global bundle context.
+     * @param parent : parent bundle context.
+     * @param local : local bundle context.
+     * @throws ConfigurationException : the context-source attribute is invalid.
+     */
+    private void parseSources(String sourceAtt, BundleContext global, BundleContext parent, BundleContext local) throws ConfigurationException {
+        String[] sources = ParseUtils.split(sourceAtt, ",");
+        for (int i = 0; i < sources.length; i++) {
+            String[] srcs = ParseUtils.split(sources[i], ":");
+            if (srcs.length == 1) {
+                // No prefix use local. //TODO choose default case.
+                SourceTracker tracker = new SourceTracker(srcs[0], local);
+                m_trackers.add(tracker);
+            } else if (srcs.length == 2) {
+                // According to prefix add the source in the good list.
+                if (srcs[0].equalsIgnoreCase("parent")) {
+                    SourceTracker tracker = new SourceTracker(srcs[1], parent);
+                    m_trackers.add(tracker);
+                } else if (srcs[0].equalsIgnoreCase("local")) {
+                    SourceTracker tracker = new SourceTracker(srcs[1], local);
+                    m_trackers.add(tracker);
+                } else if (srcs[0].equalsIgnoreCase("global")) {
+                    SourceTracker tracker = new SourceTracker(srcs[1], global);
+                    m_trackers.add(tracker);
+                } else {
+                    throw new ConfigurationException("Unknowns context scope : " + srcs[0]);
+                }
+            } else {
+                throw new ConfigurationException("Malformed context source : " + sources[i]);
+            }
+        }
+    }
+
+    /**
+     * A context source appears.
+     * @param source : new context source.
+     */
+    private void addContextSource(ContextSource source) {
+        m_sources.add(source);
+        computeFilter();
+        source.registerContextListener(this, m_properties);
+    }
+
+    /**
+     * A context source disappears.
+     * @param source : leaving context source.
+     */
+    private void removeContextSource(ContextSource source) {
+        m_sources.remove(source);
+        computeFilter();
+    }
+
+    private class SourceTracker implements TrackerCustomizer {
+
+        /**
+         * Service tracker.
+         */
+        private Tracker m_tracker;
+
+        /**
+         * Constructor.
+         * @param name : name of the required context-source.
+         * @param countext : bundle context to use.
+         * @throws ConfigurationException : the context-source name is invalid.
+         */
+        public SourceTracker(String name, BundleContext countext) throws ConfigurationException {
+            String fil = "(&(" + Constants.OBJECTCLASS + "=" + ContextSource.class.getName() + ")(" + SOURCE_NAME + "=" + name + "))";
+            try {
+                Filter filter = countext.createFilter(fil);
+                m_tracker = new Tracker(countext, filter, this);
+            } catch (InvalidSyntaxException e) {
+                throw new ConfigurationException("A Context source filter is invalid " + fil + " : " + e.getMessage());
+            }
+        }
+
+        /**
+         * Open the tracker.
+         */
+        public void open() {
+            m_tracker.open();
+        }
+
+        /**
+         * Close the tracker.
+         */
+        public void close() {
+            m_tracker.close();
+        }
+
+        /**
+         * A new context-source was added.
+         * This method inject the context-source object in the source manager.
+         * @param reference : service reference.
+         * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+         */
+        public void addedService(ServiceReference reference) {
+            addContextSource((ContextSource) m_tracker.getService(reference));
+        }
+
+        /**
+         * A new context-source is adding in the tracker.. 
+         * @param reference : service reference
+         * @return true.
+         * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+         */
+        public boolean addingService(ServiceReference reference) {
+            return true;
+        }
+
+        /**
+         * A used context-source is modified.
+         * @param reference : service reference.
+         * @param service : service object.
+         * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+         */
+        public void modifiedService(ServiceReference reference, Object service) {
+            // Nothing to do.
+        }
+
+        /**
+         * A used context-source disappears.
+         * This method notify the Source Manager in order to manage this departure. 
+         * @param reference : service reference.
+         * @param service : service object.
+         * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+         */
+        public void removedService(ServiceReference reference, Object service) {
+            removeContextSource((ContextSource) service);
+        }
+
+    }
+
+}
diff --git a/ipojo/runtime/composite/src/main/resources/composite.xsd b/ipojo/runtime/composite/src/main/resources/composite.xsd
new file mode 100644
index 0000000..6a95fb8
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/resources/composite.xsd
@@ -0,0 +1,147 @@
+<!--
+	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.
+-->
+<xs:schema elementFormDefault="qualified"
+	targetNamespace="org.apache.felix.ipojo.composite"
+	xmlns="org.apache.felix.ipojo.composite"
+	xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ipojo="org.apache.felix.ipojo">
+
+	<xs:import namespace="org.apache.felix.ipojo" schemaLocation="http://people.apache.org/~clement/ipojo/schemas/core.xsd"></xs:import>
+	<xs:complexType name="CompositeType">
+		<xs:choice minOccurs="0" maxOccurs="unbounded">
+			<xs:element ref="subservice" minOccurs="0"
+				maxOccurs="unbounded">
+			</xs:element>
+			<xs:element ref="provides" minOccurs="0"
+				maxOccurs="unbounded">
+			</xs:element>
+			<xs:element ref="instance" minOccurs="0"
+				maxOccurs="unbounded">
+			</xs:element>
+			<xs:any namespace="##other" processContents="lax"
+				minOccurs="0" maxOccurs="unbounded">
+			</xs:any>
+		</xs:choice>
+		<xs:attribute name="name" type="xs:string" use="optional"></xs:attribute>
+		<xs:attribute name="public" type="xs:boolean" use="optional"></xs:attribute>
+		<xs:attribute name="architecture" type="xs:boolean"
+			use="optional">
+		</xs:attribute>
+	</xs:complexType>
+
+	<xs:element name="subservice" type="SubserviceType" />
+	<xs:element name="provides" type="CompositeProvidesType" />
+	
+	<xs:complexType name="CompositeProvidesType">
+		<xs:complexContent>
+			<xs:extension base="ipojo:ServiceDependencyType">
+				<xs:sequence>
+					<xs:element name="delegation" type="DelegationType"></xs:element>
+				</xs:sequence>
+				<xs:attribute name="specification" type="xs:string"
+					use="required">
+				</xs:attribute>
+
+				<xs:attribute name="action">
+					<xs:simpleType>
+						<xs:restriction base="xs:string">
+							<xs:enumeration value="implement"></xs:enumeration>
+							<xs:enumeration value="export"></xs:enumeration>
+						</xs:restriction>
+					</xs:simpleType>
+				</xs:attribute>
+
+
+
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+
+	<xs:complexType name="SubserviceType">
+		<xs:complexContent>
+			<xs:extension base="ipojo:ServiceDependencyType">
+
+				<xs:sequence minOccurs="0" maxOccurs="unbounded">
+					<xs:element name="property" type="CompositePropertyType"></xs:element>
+				</xs:sequence>
+				<xs:attribute name="action" use="required">
+					<xs:simpleType>
+						<xs:restriction base="xs:string">
+							<xs:enumeration value="import"></xs:enumeration>
+							<xs:enumeration value="instantiate"></xs:enumeration>
+						</xs:restriction>
+					</xs:simpleType>
+				</xs:attribute>
+
+				<xs:attribute name="specification" type="xs:string"
+					use="required">
+				</xs:attribute>
+				<xs:attribute name="context-source" type="xs:string"
+					use="optional">
+				</xs:attribute>
+				<xs:attribute name="scope">
+					<xs:simpleType>
+						<xs:restriction base="xs:string">
+							<xs:enumeration value="global"></xs:enumeration>
+							<xs:enumeration value="composite"></xs:enumeration>
+							<xs:enumeration value="composite+global"></xs:enumeration>
+						</xs:restriction>
+					</xs:simpleType>
+				</xs:attribute>
+			</xs:extension>
+		</xs:complexContent>
+	</xs:complexType>
+
+	<xs:simpleType name="actionType">
+		<xs:restriction base="xs:string"></xs:restriction>
+	</xs:simpleType>
+
+	<xs:complexType name="CompositePropertyType">
+		<xs:sequence minOccurs="0" maxOccurs="unbounded">
+			<xs:element name="property" type="CompositePropertyType" minOccurs="0" maxOccurs="unbounded"></xs:element>
+		</xs:sequence>
+		<xs:attribute name="name" type="xs:string" use="required"></xs:attribute>
+		<xs:attribute name="value" type="xs:string" use="optional"></xs:attribute>
+	</xs:complexType>
+
+	<xs:complexType name="CompositeInstanceType">
+		<xs:sequence minOccurs="0" maxOccurs="unbounded">
+			<xs:element name="property" type="CompositePropertyType"></xs:element>
+		</xs:sequence>
+		<xs:attribute name="name" type="xs:string" use="optional"></xs:attribute>
+		<xs:attribute name="component" type="xs:string"
+			use="required">
+		</xs:attribute>
+	</xs:complexType>
+
+    <xs:element name="instance" type="CompositeInstanceType"></xs:element>
+
+    <xs:element name="composite" type="CompositeType"></xs:element>
+
+    <xs:complexType name="DelegationType">
+    	<xs:attribute name="method" type="xs:string" use="required"></xs:attribute>
+    	<xs:attribute name="policy" use="required">
+    		<xs:simpleType>
+    			<xs:restriction base="xs:string">
+    				<xs:enumeration value="all"></xs:enumeration>
+    				<xs:enumeration value="one"></xs:enumeration>
+    			</xs:restriction>
+    		</xs:simpleType>
+    	</xs:attribute>
+    </xs:complexType>
+</xs:schema>
\ No newline at end of file
diff --git a/ipojo/runtime/composite/src/main/resources/metadata.xml b/ipojo/runtime/composite/src/main/resources/metadata.xml
new file mode 100644
index 0000000..0f6262b
--- /dev/null
+++ b/ipojo/runtime/composite/src/main/resources/metadata.xml
@@ -0,0 +1,45 @@
+<!--
+	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.
+-->
+<ipojo>
+	<!-- Composite Handler -->
+	<handler
+		classname="org.apache.felix.ipojo.composite.instance.InstanceHandler"
+		name="instance" type="composite" architecture="false" level="1">
+		<requires filter="(factory.state=1)" field="m_factories"
+			optional="true">
+			<callback type="bind" method="bindFactory" />
+			<callback type="unbind" method="unbindFactory" />
+		</requires>
+	</handler>
+	<handler
+		classname="org.apache.felix.ipojo.composite.service.instantiator.ServiceDependencyHandler"
+		name="subservice" type="composite" architecture="false">
+	</handler>
+	<handler
+		classname="org.apache.felix.ipojo.composite.service.provides.ProvidedServiceHandler"
+		name="provides" type="composite" architecture="false" level="3">
+	</handler>
+	<handler
+		classname="org.apache.felix.ipojo.composite.architecture.ArchitectureHandler"
+		name="architecture" type="composite" architecture="false">
+		<provides>
+			<property field="m_name" name="architecture.instance"/>
+		</provides>
+	</handler>
+</ipojo>
\ No newline at end of file
diff --git a/ipojo/runtime/core/DEPENDENCIES b/ipojo/runtime/core/DEPENDENCIES
new file mode 100644
index 0000000..6cfe273
--- /dev/null
+++ b/ipojo/runtime/core/DEPENDENCIES
@@ -0,0 +1,28 @@
+Apache Felix iPOJO Runtime
+Copyright 2008-2011 The Apache Software Foundation
+
+This software was developed at the Apache Software Foundation
+(http://www.apache.org) and may have dependencies on other
+Apache software licensed under Apache License 2.0.
+
+I. Included Third-Party Software
+
+This product includes software developed at
+Copyright (c) 2000-2005 INRIA, France Telecom
+Licensed under BSD License.
+
+This product includes software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2007).
+Licensed under the Apache License 2.0.
+
+II. Used Third-Party Software
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2009).
+Licensed under the Apache License 2.0.
+
+III. Overall License Summary
+- Apache License 2.0
+- BSD License
diff --git a/ipojo/runtime/core/LICENSE b/ipojo/runtime/core/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/ipojo/runtime/core/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/runtime/core/LICENSE.asm b/ipojo/runtime/core/LICENSE.asm
new file mode 100644
index 0000000..cc529ed
--- /dev/null
+++ b/ipojo/runtime/core/LICENSE.asm
@@ -0,0 +1,29 @@
+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/runtime/core/NOTICE b/ipojo/runtime/core/NOTICE
new file mode 100644
index 0000000..65496d1
--- /dev/null
+++ b/ipojo/runtime/core/NOTICE
@@ -0,0 +1,15 @@
+Apache Felix iPOJO Runtime
+Copyright 2008-2011 The Apache Software Foundation
+
+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
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2009).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Copyright (c) 2000-2005 INRIA, France Telecom
+Licensed under BSD License.
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo.html b/ipojo/runtime/core/doc/apache-felix-ipojo.html
new file mode 100644
index 0000000..80c96b1
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo.html
@@ -0,0 +1,307 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html><head>
+
+
+  
+    <title>Apache Felix - Apache Felix iPOJO</title>
+    <link rel="stylesheet" href="apache-felix-ipojo_files/site.css" type="text/css" media="all">
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+  </head><body>
+    <div class="title"><div class="logo"><a href="http://felix.apache.org/site/index.html"><img alt="Apache Felix" src="apache-felix-ipojo_files/logo.png" border="0"></a></div><div class="header"><a href="http://www.apache.org/"><img alt="Apache" src="apache-felix-ipojo_files/apache.png" border="0"></a></div></div>
+    <div class="menu">
+<ul>
+	<li><a href="http://felix.apache.org/site/news.html" title="news">news</a></li>
+	<li><a href="http://felix.apache.org/site/license.html" title="license">license</a></li>
+	<li><a href="http://felix.apache.org/site/downloads.cgi" rel="nofollow">downloads</a></li>
+	<li><a href="http://felix.apache.org/site/documentation.html" title="documentation">documentation</a></li>
+	<li><a href="http://felix.apache.org/site/mailinglists.html" title="mailinglists">mailing lists</a></li>
+	<li><a href="http://felix.apache.org/site/contributing.html" title="Contributing">contributing</a></li>
+	<li><a href="http://www.apache.org/" rel="nofollow">asf</a></li>
+	<li><a href="http://www.apache.org/foundation/sponsorship.html" rel="nofollow">sponsorship</a></li>
+	<li><a href="http://www.apache.org/foundation/thanks.html" rel="nofollow">sponsors</a>
+<!-- ApacheCon Ad -->
+<iframe src="apache-felix-ipojo_files/button.html" style="border-width: 0pt; float: left;" scrolling="no" frameborder="0" height="135" width="135"></iframe>
+<p style="height: 100px;">
+<!-- ApacheCon Ad -->
+</p></li></ul> </div>
+    <div class="main">
+<style type="text/css">
+ @import url(http://people.apache.org/~clement/ipojo/site/superfish.css); 
+</style>
+
+<style type="text/css">
+ @import url(http://people.apache.org/~clement/ipojo/site/style.css); 
+</style>
+
+<p>
+<script class="javascript" src="apache-felix-ipojo_files/shCore.js"></script>
+<script class="javascript" src="apache-felix-ipojo_files/shBrushCSharp.js"></script>
+<script class="javascript" src="apache-felix-ipojo_files/shBrushPhp.js"></script>
+<script class="javascript" src="apache-felix-ipojo_files/shBrushJScript.js"></script>
+<script class="javascript" src="apache-felix-ipojo_files/shBrushVb.js"></script>
+<script class="javascript" src="apache-felix-ipojo_files/shBrushSql.js"></script>
+<script class="javascript" src="apache-felix-ipojo_files/shBrushXml.js"></script>
+<script class="javascript" src="apache-felix-ipojo_files/shBrushShell.js"></script>
+<script class="javascript" src="apache-felix-ipojo_files/shBrushDelphi.js"></script>
+<script class="javascript" src="apache-felix-ipojo_files/shBrushPython.js"></script>
+<script class="javascript" src="apache-felix-ipojo_files/shBrushJava.js"></script>
+
+<script type="text/javascript" src="apache-felix-ipojo_files/jquery-1.js"></script>
+<script type="text/javascript" src="apache-felix-ipojo_files/hoverIntent.js"></script> 
+<script type="text/javascript" src="apache-felix-ipojo_files/superfish.js"></script> 
+<script type="text/javascript" src="apache-felix-ipojo_files/supersubs.js"></script> 
+
+<script type="text/javascript"> 
+ 
+    $(document).ready(function(){ 
+        $("ul.sf-menu").supersubs({ 
+            minWidth:    14,   // minimum width of sub-menus in em units 
+            maxWidth:    30,   // maximum width of sub-menus in em units 
+            extraWidth:  1     // extra width can ensure lines don't sometimes turn over 
+                               // due to slight rounding differences and font-family 
+        }).superfish();  // call supersubs first, then superfish, so that subs are 
+                         // not display:none when measuring. Call before initialising 
+                         // containing tabs for same reason. 
+    }); 
+ 
+</script>
+</p><div class="main">
+<div class="page-header">
+<img src="apache-felix-ipojo_files/header.png" class="header">
+<a href="http://ipojo.org/"><img src="apache-felix-ipojo_files/ipojo.png" class="header-logo" width="225"></a>
+<ul class="sf-menu sf-js-enabled sf-shadow" id="ipojo-menu">
+<li class="current">
+<!-- Menu Overview -->
+<a href="" class="sf-with-ul">Overview<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+<ul style="float: none; width: 14em; display: none; visibility: hidden;">
+	<li style="white-space: normal; float: left; width: 100%;">
+	<a style="float: none; width: auto;" href="" title="Apache Felix iPOJO">Home</a>							
+	</li>
+	<li style="white-space: normal; float: left; width: 100%;">
+	<a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-why-choose-ipojo.html" title="apache-felix-ipojo-why-choose-ipojo">Why choose iPOJO</a>
+	</li>
+	<li style="white-space: normal; float: left; width: 100%;">
+	<a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-successstories.html" title="apache-felix-ipojo-successstories">Success stories</a>
+	</li>
+	<li style="white-space: normal; float: left; width: 100%;">
+	<a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-feature-overview.html" title="Apache Felix iPOJO Feature Overview">Features</a>
+	</li>
+</ul>
+</li>	
+
+<li class="">			
+<!-- Menu download -->
+</li><li>
+<a href="http://felix.apache.org/site/download.html" title="Download">Download </a>
+</li>
+
+<li class="">					
+<!-- Menu Documentation -->
+<a href="" class="sf-with-ul">Documentation<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+<ul style="float: none; width: 14em; display: none; visibility: hidden;">
+    <!-- sub- menu : getting started -->
+    <li style="white-space: normal; float: left; width: 100%;" class="">
+    <a style="float: none; width: auto;" href="" class="sf-with-ul">Getting Started<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+    <ul style="left: 14em; float: none; width: 14em; display: none; visibility: hidden;">
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-in-10-minutes.html" title="iPOJO in 10 minutes">iPOJO in 10 minutes</a></li>
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/how-to-use-ipojo-annotations.html" title="How to use iPOJO Annotations">Using Annotations</a></li>
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-hello-word-maven-based-tutorial.html" title="iPOJO Hello Word (Maven-Based) tutorial">Maven tutorial</a></li>
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-advanced-tutorial.html" title="iPOJO Advanced Tutorial">Advanced tutorial</a></li>
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-dosgi.html" title="apache-felix-ipojo-dosgi">Using Distributed OSGi</a></li>
+     <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-composition-tutorial.html" title="iPOJO Composition Tutorial">Application Composition</a></li>
+    </ul>
+    </li> <!-- end of getting started -->
+    <!-- sub menu : Describing Components -->
+     <li style="white-space: normal; float: left; width: 100%;" class="">
+        <a style="float: none; width: auto;" href="http://felix.apache.org/site/describing-components.html" class="sf-with-ul">Describing components<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+        <ul style="left: 14em; float: none; width: 14em; display: none; visibility: hidden;">
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/service-requirement-handler.html" title="Service Requirement Handler">Requiring a service</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/providing-osgi-services.html" title="Providing OSGi services">Providing a service</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/lifecycle-callback-handler.html" title="Lifecycle Callback Handler">Lifecycle management</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/configuration-handler.html" title="Configuration Handler">Configuration</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/architecture-handler.html" title="Architecture Handler">Introspection</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/controller-lifecycle-handler.html" title="Controller Lifecycle Handler">Impacting the lifecycle</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/event-admin-handlers.html" title="Event Admin Handlers">Asynchronous communication</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-jmx-handler.html" title="iPOJO JMX Handler">JMX management</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/extender-pattern-handler.html" title="Extender Pattern Handler">Extender pattern</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/white-board-pattern-handler.html" title="White Board Pattern Handler">Whiteboard pattern</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/temporal-service-dependency.html" title="Temporal Service Dependency">Temporal dependencies</a></li>
+        </ul>
+     </li> <!-- End of describing components -->
+    <!-- sub- menu : User Guide -->
+    <li style="white-space: normal; float: left; width: 100%;" class="">
+    <a style="float: none; width: auto;" href="" class="sf-with-ul">User Guide<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+        <ul style="left: 14em; float: none; width: 14em; display: none; visibility: hidden;">
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/using-xml-schemas.html" title="Using XML Schemas">XML Schemas</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-api.html" title="apache-felix-ipojo-api">API</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-testing-components.html" title="apache-felix-ipojo-testing-components">Testing components</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-eclipse-integration.html" title="apache-felix-ipojo-eclipse-integration">Eclipse Integration</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-faq.html" title="iPOJO FAQ">FAQ</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-reference-card.html" title="iPOJO-Reference-Card">Reference Card</a></li>
+        </ul>
+    </li> <!-- end of user guide -->
+    <!-- sub- menu : Dev Guide -->
+    <li class="" style="white-space: normal; float: left; width: 100%;"> 
+    <a style="float: none; width: auto;" href="" class="sf-with-ul">Advanced Topics<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+       <ul style="left: 14em; float: none; width: 14em; display: none; visibility: hidden;">
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/ipojo/api/1.2.0" rel="nofollow">Javadoc</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/how-to-write-your-own-handler.html" title="How to write your own handler">Handler development</a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/how-to-use-ipojo-manipulation-metadata.html" title="How to use iPOJO Manipulation Metadata">Manipulation Metadata </a></li>
+        <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/dive-into-the-ipojo-manipulation-depths.html" title="Dive into the iPOJO Manipulation depths">Dive into the iPOJO Manipulation depths</a></li>
+       </ul>
+    </li> <!-- End of Dev guide -->
+</ul> 
+</li> <!-- End of doc -->
+<!-- Menu 4 : Tools -->
+<li class="">
+<a href="" class="sf-with-ul">Tools<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+<ul style="float: none; width: 14em; display: none; visibility: hidden;">
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-ant-task.html" title="iPOJO Ant Task">Ant Task</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-eclipse-plug-in.html" title="iPOJO Eclipse Plug-in">Eclipse Plugin</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-maven-plug-in.html" title="iPOJO Maven Plug-in">Maven Plugin</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-arch-command.html" title="iPOJO-Arch-Command"><tt>arch</tt> shell command</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-online-manipulator.html" title="apache-felix-ipojo-online-manipulator">Online Manipulator</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/ipojo-webconsole-plugin.html" title="iPOJO Webconsole Plugin">Webconsole plugin</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-junit4osgi.html" title="apache-felix-ipojo-junit4osgi">Junit4OSGi</a></li>
+</ul>   
+</li><!-- End of tools -->					
+<!-- Menu 5 : Misc -->
+<li class="">
+<a href="" class="sf-with-ul">Misc<span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span><span class="sf-sub-indicator"> »</span></a>
+<ul style="float: none; width: 14em; display: none; visibility: hidden;">
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-issuestracker.html" title="apache-felix-ipojo-issuestracker">Issues Tracker</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-supportedvms.html" title="apache-felix-ipojo-supportedVMs">Supported JVMs</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/apache-felix-ipojo-supportedosgi.html" title="apache-felix-ipojo-supportedOSGi">Supported OSGi Implementations</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://ipojo-dark-side.blogspot.com/" rel="nofollow">iPOJO's Dark Side Blog</a></li>
+   <li style="white-space: normal; float: left; width: 100%;"><a style="float: none; width: auto;" href="http://felix.apache.org/site/article-presentations.html" title="Article &amp; Presentations">Article &amp; Presentations</a></li>
+</ul>
+</li><!-- End of misc -->
+</ul> <!-- End of the menu -->
+</div> <!-- Page header -->
+
+
+<div class="content">
+
+<p><b>iPOJO</b> is a service component runtime aiming to simplify OSGi
+application development. It natively supports ALL the dynamism of OSGi.
+Based on the concept of POJO, application logic is developed easily.
+Non functional properties are just <em>injected</em> in the component at runtime.
+<br clear="all">
+<br clear="all">
+iPOJO strength points are :</p>
+<ul>
+	<li>components are developed as POJO, nothing else is required !</li>
+	<li>the component model is extensible, so feel free to adapt it to your needs</li>
+	<li>the standard component model manages service providing and service dependencies, and so can require any other OSGi services</li>
+	<li>iPOJO manages the component instance lifecycle and the environment dynamics as it has never been possible</li>
+	<li>iPOJO provides a powerful composition system to create highly dynamic applications</li>
+</ul>
+
+
+<p><br clear="all"></p>
+
+<p>
+</p><div class="smallboxes" style="margin-left: auto; margin-right: auto; width: 824px;">
+<table>
+<tbody><tr>
+<td>
+<div class="smallbox" style="margin-left: 10px; margin-right: 10px;">
+	<div class="smallbox-title">
+		<img src="apache-felix-ipojo_files/status_online.png"> <b>Why choose iPOJO ?</b>
+	</div>
+	<div class="smallbox-content">
+	<ul> 
+	<li><a href="http://felix.apache.org/site/apache-felix-ipojo-successstories.html#apache-felix-ipojo-successstories-schneider">iPOJO at Schneider Electric</a></li>
+	<li><a href="http://felix.apache.org/site/apache-felix-ipojo-successstories.html#apache-felix-ipojo-successstories-ugasp">iPOJO at Ubidreams</a> </li>
+	<li><a href="http://felix.apache.org/site/apache-felix-ipojo-successstories.html" title="apache-felix-ipojo-successstories">others success stories</a></li>
+	<li><a href="http://felix.apache.org/site/apache-felix-ipojo-keypoints.html" title="apache-felix-ipojo-keypoints">iPOJO Key points</a></li> 
+	<li><a href="http://felix.apache.org/site/apache-felix-ipojo-why-choose-ipojo.html" title="apache-felix-ipojo-why-choose-ipojo">Why choose iPOJO </a></li>
+	</ul>
+	</div>
+</div>
+</td>
+<td>
+<div class="smallbox" style="margin-left: 10px; margin-right: 10px;">
+	<div class="smallbox-title">
+		<img src="apache-felix-ipojo_files/cog.png"> <b>Getting started</b>
+	</div>
+	<div class="smallbox-content">
+	<ul>
+        <li><a href="http://felix.apache.org/site/download.html" title="Download">Downloads</a></li>
+	<li><a href="http://felix.apache.org/site/ipojo-in-10-minutes.html" title="iPOJO in 10 minutes">iPOJO in 10 minutes</a></li>
+        <li><a href="http://felix.apache.org/site/how-to-use-ipojo-annotations.html" title="How to use iPOJO Annotations">Using Annotations</a></li>
+        <li><a href="http://felix.apache.org/site/ipojo-hello-word-maven-based-tutorial.html" title="iPOJO Hello Word (Maven-Based) tutorial">Maven tutorial</a></li>
+        <li><a href="http://felix.apache.org/site/ipojo-advanced-tutorial.html" title="iPOJO Advanced Tutorial">Advanced tutorial</a></li>
+	</ul>
+	</div>
+</div>
+</td>
+<td>
+<div class="smallbox" style="margin-left: 10px; margin-right: 10px;">
+	<div class="smallbox-title">
+		<img src="apache-felix-ipojo_files/user_edit.png"> <b>The developer corner</b>
+	</div>
+	<div class="smallbox-content">
+	<ul>
+	<li><a href="http://felix.apache.org/site/describing-components.html" title="Describing components">Describing components</a></li>
+	<li><a href="http://felix.apache.org/site/ipojo-reference-card.html" title="iPOJO-Reference-Card">iPOJO Reference Card</a></li>
+	<li><a href="http://felix.apache.org/site/apache-felix-ipojo-eclipse-integration.html" title="apache-felix-ipojo-eclipse-integration">Eclipse Integration</a></li>
+        <li><a href="http://felix.apache.org/site/apache-felix-ipojo-online-manipulator.html" title="apache-felix-ipojo-online-manipulator">Online Manipulator</a></li>
+        <li><a href="http://felix.apache.org/site/ipojo-faq.html" title="iPOJO FAQ">FAQ</a></li>
+	</ul>
+	</div>
+</div>
+</td>
+</tr>
+</tbody></table>
+</div>
+
+
+
+<p>The easiest way to get involved in iPOJO is to try it out. See the
+Quick Start Guide for how to get up and running with the iPOJO
+framework and the downloads page for more information on acquiring
+iPOJO &amp; related tools.</p>
+
+<p>You can also have a look to <a href="http://felix.apache.org/site/presentations.data/ipojo-berlin-20080611.pdf" rel="nofollow">this</a> presentation describing iPOJO main features.
+<br clear="all"></p>
+
+<h2><a name="ApacheFelixiPOJO-What'snews"></a>What's news</h2>
+
+<ul>
+	<li><b>New web site... and some issues</b> : the iPOJO web site
+has changed. Enjoy! However, we're still setting everything correctly,
+it should be done shortly. (2009-07-08)</li>
+	<li><b>iPOJO And Distributed Services</b> : New tutorial about Distributed OSGi and iPOJO available. (2009-07-05)</li>
+	<li><b>iPOJO web console plugin is now available</b> : Manages your iPOJO system with the Apache Felix Web Console. More info <a href="http://felix.apache.org/site/ipojo-webconsole-plugin.html" title="iPOJO Webconsole Plugin">here</a> (2009-06-30)</li>
+	<li><b>iPOJO online manipulator is now available</b> : It allows to avoid offline manipulation! More info <a href="http://felix.apache.org/site/apache-felix-ipojo-online-manipulator.html" title="apache-felix-ipojo-online-manipulator">here</a> (2009-04-22)</li>
+	<li><b>iPOJO API is now in the iPOJO Trunk</b> : The iPOJO API is now available from the iPOJO Trunk (2009-02-09)</li>
+	<li><b>Integrating iPOJO inside Eclipse</b> : <a href="http://felix.apache.org/site/apache-felix-ipojo-eclipse-integration.html" title="apache-felix-ipojo-eclipse-integration">How to don't break your compile &amp; run cycle</a> (2009-02-05)</li>
+	<li><b>Towards iPOJO 1.2.0</b> : The release process has began (2009-01-15)</li>
+	<li><b>Release of the Apache Felix iPOJO 1.0.0</b> : iPOJO 1.0.0 is available in the <a href="http://felix.apache.org/site/download.html" title="Download">download section</a> (2008-10-22)</li>
+</ul>
+
+<ul>
+	<li><a href="http://felix.apache.org/site/ipojo-news.html" title="iPOJO-news">all news...</a></li>
+</ul>
+
+
+
+
+ </div>
+        <img src="apache-felix-ipojo_files/footer.png" class="footer">
+</div>
+
+<script type="text/javascript">
+var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+</script><script src="apache-felix-ipojo_files/ga.js" type="text/javascript"></script>
+<script type="text/javascript">
+try{
+var pageTracker = _gat._getTracker("UA-1518442-4");
+pageTracker._trackPageview();
+} catch(err) {}
+</script>
+
+    </div>
+  </body></html>
\ No newline at end of file
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/apache.png b/ipojo/runtime/core/doc/apache-felix-ipojo_files/apache.png
new file mode 100644
index 0000000..5132f65
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/apache.png
Binary files differ
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/button.html b/ipojo/runtime/core/doc/apache-felix-ipojo_files/button.html
new file mode 100644
index 0000000..1721083
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/button.html
@@ -0,0 +1,2 @@
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8"></head><body></body></html>
\ No newline at end of file
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/cog.png b/ipojo/runtime/core/doc/apache-felix-ipojo_files/cog.png
new file mode 100644
index 0000000..67de2c6
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/cog.png
Binary files differ
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/footer.png b/ipojo/runtime/core/doc/apache-felix-ipojo_files/footer.png
new file mode 100644
index 0000000..15be425
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/footer.png
Binary files differ
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/ga.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/ga.js
new file mode 100644
index 0000000..0501070
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/ga.js
@@ -0,0 +1,41 @@
+var _gat=new Object({c:"length",lb:"4.3.1",m:"cookie",b:undefined,cb:function(d,a){this.zb=d;this.Nb=a},r:"__utma=",W:"__utmb=",ma:"__utmc=",Ta:"__utmk=",na:"__utmv=",oa:"__utmx=",Sa:"GASO=",X:"__utmz=",lc:"http://www.google-analytics.com/__utm.gif",mc:"https://ssl.google-analytics.com/__utm.gif",Wa:"utmcid=",Ya:"utmcsr=",$a:"utmgclid=",Ua:"utmccn=",Xa:"utmcmd=",Za:"utmctr=",Va:"utmcct=",Hb:false,_gasoDomain:undefined,_gasoCPath:undefined,e:window,a:document,k:navigator,t:function(d){var a=1,c=0,h,
+o;if(!_gat.q(d)){a=0;for(h=d[_gat.c]-1;h>=0;h--){o=d.charCodeAt(h);a=(a<<6&268435455)+o+(o<<14);c=a&266338304;a=c!=0?a^c>>21:a}}return a},C:function(d,a,c){var h=_gat,o="-",k,l,s=h.q;if(!s(d)&&!s(a)&&!s(c)){k=h.w(d,a);if(k>-1){l=d.indexOf(c,k);if(l<0)l=d[h.c];o=h.F(d,k+h.w(a,"=")+1,l)}}return o},Ea:function(d){var a=false,c=0,h,o;if(!_gat.q(d)){a=true;for(h=0;h<d[_gat.c];h++){o=d.charAt(h);c+="."==o?1:0;a=a&&c<=1&&(0==h&&"-"==o||_gat.P(".0123456789",o))}}return a},d:function(d,a){var c=encodeURIComponent;
+return c instanceof Function?(a?encodeURI(d):c(d)):escape(d)},J:function(d,a){var c=decodeURIComponent,h;d=d.split("+").join(" ");if(c instanceof Function)try{h=a?decodeURI(d):c(d)}catch(o){h=unescape(d)}else h=unescape(d);return h},Db:function(d){return d&&d.hash?_gat.F(d.href,_gat.w(d.href,"#")):""},q:function(d){return _gat.b==d||"-"==d||""==d},Lb:function(d){return d[_gat.c]>0&&_gat.P(" \n\r\t",d)},P:function(d,a){return _gat.w(d,a)>-1},h:function(d,a){d[d[_gat.c]]=a},T:function(d){return d.toLowerCase()},
+z:function(d,a){return d.split(a)},w:function(d,a){return d.indexOf(a)},F:function(d,a,c){c=_gat.b==c?d[_gat.c]:c;return d.substring(a,c)},uc:function(){var d=_gat.b,a=window;if(a&&a.gaGlobal&&a.gaGlobal.hid)d=a.gaGlobal.hid;else{d=Math.round(Math.random()*2147483647);a.gaGlobal=a.gaGlobal?a.gaGlobal:{};a.gaGlobal.hid=d}return d},wa:function(){return Math.round(Math.random()*2147483647)},Gc:function(){return(_gat.wa()^_gat.vc())*2147483647},vc:function(){var d=_gat.k,a=_gat.a,c=_gat.e,h=a[_gat.m]?
+a[_gat.m]:"",o=c.history[_gat.c],k,l,s=[d.appName,d.version,d.language?d.language:d.browserLanguage,d.platform,d.userAgent,d.javaEnabled()?1:0].join("");if(c.screen)s+=c.screen.width+"x"+c.screen.height+c.screen.colorDepth;else if(c.java){l=java.awt.Toolkit.getDefaultToolkit().getScreenSize();s+=l.screen.width+"x"+l.screen.height}s+=h;s+=a.referrer?a.referrer:"";k=s[_gat.c];while(o>0)s+=o--^k++;return _gat.t(s)}});_gat.hc=function(){var d=this,a=_gat.cb;function c(h,o){return new a(h,o)}d.db="utm_campaign";d.eb="utm_content";d.fb="utm_id";d.gb="utm_medium";d.hb="utm_nooverride";d.ib="utm_source";d.jb="utm_term";d.kb="gclid";d.pa=0;d.I=0;d.wb="15768000";d.Tb="1800";d.ea=[];d.ga=[];d.Ic="cse";d.Gb="q";d.ab="google";d.fa=[c(d.ab,d.Gb),c("yahoo","p"),c("msn","q"),c("bing","q"),c("aol","query"),c("aol","encquery"),c("lycos","query"),c("ask","q"),c("altavista","q"),c("netscape","query"),c("cnn","query"),c("looksmart","qt"),c("about",
+"terms"),c("mamma","query"),c("alltheweb","q"),c("gigablast","q"),c("voila","rdata"),c("virgilio","qs"),c("live","q"),c("baidu","wd"),c("alice","qs"),c("yandex","text"),c("najdi","q"),c("aol","q"),c("club-internet","query"),c("mama","query"),c("seznam","q"),c("search","q"),c("wp","szukaj"),c("onet","qt"),c("netsprint","q"),c("google.interia","q"),c("szukacz","q"),c("yam","k"),c("pchome","q"),c("kvasir","searchExpr"),c("sesam","q"),c("ozu","q"),c("terra","query"),c("nostrum","query"),c("mynet","q"),
+c("ekolay","q"),c("search.ilse","search_for")];d.B=undefined;d.Kb=false;d.p="/";d.ha=100;d.Da="/__utm.gif";d.ta=1;d.ua=1;d.G="|";d.sa=1;d.qa=1;d.pb=1;d.g="auto";d.D=1;d.Ga=1000;d.Yc=10;d.nc=10;d.Zc=0.2};_gat.Y=function(d,a){var c,h,o,k,l,s,q,f=this,n=_gat,w=n.q,x=n.c,g,z=a;f.a=d;function B(i){var b=i instanceof Array?i.join("."):"";return w(b)?"-":b}function A(i,b){var e=[],j;if(!w(i)){e=n.z(i,".");if(b)for(j=0;j<e[x];j++)if(!n.Ea(e[j]))e[j]="-"}return e}function p(){return u(63072000000)}function u(i){var b=new Date,e=new Date(b.getTime()+i);return"expires="+e.toGMTString()+"; "}function m(i,b){f.a[n.m]=i+"; path="+z.p+"; "+b+f.Cc()}function r(i,b,e){var j=f.V,t,v;for(t=0;t<j[x];t++){v=j[t][0];
+v+=w(b)?b:b+j[t][4];j[t][2](n.C(i,v,e))}}f.Jb=function(){return n.b==g||g==f.t()};f.Ba=function(){return l?l:"-"};f.Wb=function(i){l=i};f.Ma=function(i){g=n.Ea(i)?i*1:"-"};f.Aa=function(){return B(s)};f.Na=function(i){s=A(i)};f.Hc=function(){return g?g:"-"};f.Cc=function(){return w(z.g)?"":"domain="+z.g+";"};f.ya=function(){return B(c)};f.Ub=function(i){c=A(i,1)};f.K=function(){return B(h)};f.La=function(i){h=A(i,1)};f.za=function(){return B(o)};f.Vb=function(i){o=A(i,1)};f.Ca=function(){return B(k)};
+f.Xb=function(i){k=A(i);for(var b=0;b<k[x];b++)if(b<4&&!n.Ea(k[b]))k[b]="-"};f.Dc=function(){return q};f.Uc=function(i){q=i};f.pc=function(){c=[];h=[];o=[];k=[];l=n.b;s=[];g=n.b};f.t=function(){var i="",b;for(b=0;b<f.V[x];b++)i+=f.V[b][1]();return n.t(i)};f.Ha=function(i){var b=f.a[n.m],e=false;if(b){r(b,i,";");f.Ma(f.t());e=true}return e};f.Rc=function(i){r(i,"","&");f.Ma(n.C(i,n.Ta,"&"))};f.Wc=function(){var i=f.V,b=[],e;for(e=0;e<i[x];e++)n.h(b,i[e][0]+i[e][1]());n.h(b,n.Ta+f.t());return b.join("&")};
+f.bd=function(i,b){var e=f.V,j=z.p,t;f.Ha(i);z.p=b;for(t=0;t<e[x];t++)if(!w(e[t][1]()))e[t][3]();z.p=j};f.dc=function(){m(n.r+f.ya(),p())};f.Pa=function(){m(n.W+f.K(),u(z.Tb*1000))};f.ec=function(){m(n.ma+f.za(),"")};f.Ra=function(){m(n.X+f.Ca(),u(z.wb*1000))};f.fc=function(){m(n.oa+f.Ba(),p())};f.Qa=function(){m(n.na+f.Aa(),p())};f.cd=function(){m(n.Sa+f.Dc(),"")};f.V=[[n.r,f.ya,f.Ub,f.dc,"."],[n.W,f.K,f.La,f.Pa,""],[n.ma,f.za,f.Vb,f.ec,""],[n.oa,f.Ba,f.Wb,f.fc,""],[n.X,f.Ca,f.Xb,f.Ra,"."],[n.na,
+f.Aa,f.Na,f.Qa,"."]]};_gat.jc=function(d){var a=this,c=_gat,h=d,o,k=function(l){var s=(new Date).getTime(),q;q=(s-l[3])*(h.Zc/1000);if(q>=1){l[2]=Math.min(Math.floor(l[2]*1+q),h.nc);l[3]=s}return l};a.O=function(l,s,q,f,n,w,x){var g,z=h.D,B=q.location;if(!o)o=new c.Y(q,h);o.Ha(f);g=c.z(o.K(),".");if(g[1]<500||n){if(w)g=k(g);if(n||!w||g[2]>=1){if(!n&&w)g[2]=g[2]*1-1;g[1]=g[1]*1+1;l="?utmwv="+_gat.lb+"&utmn="+c.wa()+(c.q(B.hostname)?"":"&utmhn="+c.d(B.hostname))+(h.ha==100?"":"&utmsp="+c.d(h.ha))+l;if(0==z||2==z){var A=
+new Image(1,1);A.src=h.Da+l;var p=2==z?function(){}:x||function(){};A.onload=p}if(1==z||2==z){var u=new Image(1,1);u.src=("https:"==B.protocol?c.mc:c.lc)+l+"&utmac="+s+"&utmcc="+a.wc(q,f);u.onload=x||function(){}}}}o.La(g.join("."));o.Pa()};a.wc=function(l,s){var q=[],f=[c.r,c.X,c.na,c.oa],n,w=l[c.m],x;for(n=0;n<f[c.c];n++){x=c.C(w,f[n]+s,";");if(!c.q(x))c.h(q,f[n]+x+";")}return c.d(q.join("+"))}};_gat.i=function(){this.la=[]};_gat.i.bb=function(d,a,c,h,o,k){var l=this;l.cc=d;l.Oa=a;l.L=c;l.sb=h;l.Pb=o;l.Qb=k};_gat.i.bb.prototype.S=function(){var d=this,a=_gat.d;return"&"+["utmt=item","utmtid="+a(d.cc),"utmipc="+a(d.Oa),"utmipn="+a(d.L),"utmiva="+a(d.sb),"utmipr="+a(d.Pb),"utmiqt="+a(d.Qb)].join("&")};_gat.i.$=function(d,a,c,h,o,k,l,s){var q=this;q.v=d;q.ob=a;q.bc=c;q.ac=h;q.Yb=o;q.ub=k;q.$b=l;q.xb=s;q.ca=[]};_gat.i.$.prototype.mb=function(d,a,c,h,o){var k=this,l=k.Eb(d),s=k.v,q=_gat;if(q.b==
+l)q.h(k.ca,new q.i.bb(s,d,a,c,h,o));else{l.cc=s;l.Oa=d;l.L=a;l.sb=c;l.Pb=h;l.Qb=o}};_gat.i.$.prototype.Eb=function(d){var a,c=this.ca,h;for(h=0;h<c[_gat.c];h++)a=d==c[h].Oa?c[h]:a;return a};_gat.i.$.prototype.S=function(){var d=this,a=_gat.d;return"&"+["utmt=tran","utmtid="+a(d.v),"utmtst="+a(d.ob),"utmtto="+a(d.bc),"utmttx="+a(d.ac),"utmtsp="+a(d.Yb),"utmtci="+a(d.ub),"utmtrg="+a(d.$b),"utmtco="+a(d.xb)].join("&")};_gat.i.prototype.nb=function(d,a,c,h,o,k,l,s){var q=this,f=_gat,n=q.xa(d);if(f.b==
+n){n=new f.i.$(d,a,c,h,o,k,l,s);f.h(q.la,n)}else{n.ob=a;n.bc=c;n.ac=h;n.Yb=o;n.ub=k;n.$b=l;n.xb=s}return n};_gat.i.prototype.xa=function(d){var a,c=this.la,h;for(h=0;h<c[_gat.c];h++)a=d==c[h].v?c[h]:a;return a};_gat.gc=function(d){var a=this,c="-",h=_gat,o=d;a.Ja=screen;a.qb=!self.screen&&self.java?java.awt.Toolkit.getDefaultToolkit():h.b;a.a=document;a.e=window;a.k=navigator;a.Ka=c;a.Sb=c;a.tb=c;a.Ob=c;a.Mb=1;a.Bb=c;function k(){var l,s,q,f,n="ShockwaveFlash",w="$version",x=a.k?a.k.plugins:h.b;if(x&&x[h.c]>0)for(l=0;l<x[h.c]&&!q;l++){s=x[l];if(h.P(s.name,"Shockwave Flash"))q=h.z(s.description,"Shockwave Flash ")[1]}else{n=n+"."+n;try{f=new ActiveXObject(n+".7");q=f.GetVariable(w)}catch(g){}if(!q)try{f=
+new ActiveXObject(n+".6");q="WIN 6,0,21,0";f.AllowScriptAccess="always";q=f.GetVariable(w)}catch(z){}if(!q)try{f=new ActiveXObject(n);q=f.GetVariable(w)}catch(z){}if(q){q=h.z(h.z(q," ")[1],",");q=q[0]+"."+q[1]+" r"+q[2]}}return q?q:c}a.xc=function(){var l;if(self.screen){a.Ka=a.Ja.width+"x"+a.Ja.height;a.Sb=a.Ja.colorDepth+"-bit"}else if(a.qb)try{l=a.qb.getScreenSize();a.Ka=l.width+"x"+l.height}catch(s){}a.Ob=h.T(a.k&&a.k.language?a.k.language:(a.k&&a.k.browserLanguage?a.k.browserLanguage:c));a.Mb=
+a.k&&a.k.javaEnabled()?1:0;a.Bb=o?k():c;a.tb=h.d(a.a.characterSet?a.a.characterSet:(a.a.charset?a.a.charset:c))};a.Xc=function(){return"&"+["utmcs="+h.d(a.tb),"utmsr="+a.Ka,"utmsc="+a.Sb,"utmul="+a.Ob,"utmje="+a.Mb,"utmfl="+h.d(a.Bb)].join("&")}};_gat.n=function(d,a,c,h,o){var k=this,l=_gat,s=l.q,q=l.b,f=l.P,n=l.C,w=l.T,x=l.z,g=l.c;k.a=a;k.f=d;k.Rb=c;k.ja=h;k.o=o;function z(p){return s(p)||"0"==p||!f(p,"://")}function B(p){var u="";p=w(x(p,"://")[1]);if(f(p,"/")){p=x(p,"/")[1];if(f(p,"?"))u=x(p,"?")[0]}return u}function A(p){var u="";u=w(x(p,"://")[1]);if(f(u,"/"))u=x(u,"/")[0];return u}k.Fc=function(p){var u=k.Fb(),m=k.o;return new l.n.s(n(p,m.fb+"=","&"),n(p,m.ib+"=","&"),n(p,m.kb+"=","&"),k.ba(p,m.db,"(not set)"),k.ba(p,m.gb,"(not set)"),
+k.ba(p,m.jb,u&&!s(u.R)?l.J(u.R):q),k.ba(p,m.eb,q))};k.Ib=function(p){var u=A(p),m=B(p);if(f(u,k.o.ab)){p=x(p,"?").join("&");if(f(p,"&"+k.o.Gb+"="))if(m==k.o.Ic)return true}return false};k.Fb=function(){var p,u,m=k.Rb,r,i,b=k.o.fa;if(z(m)||k.Ib(m))return;p=A(m);for(r=0;r<b[g];r++){i=b[r];if(f(p,w(i.zb))){m=x(m,"?").join("&");if(f(m,"&"+i.Nb+"=")){u=x(m,"&"+i.Nb+"=")[1];if(f(u,"&"))u=x(u,"&")[0];return new l.n.s(q,i.zb,q,"(organic)","organic",u,q)}}}};k.ba=function(p,u,m){var r=n(p,u+"=","&"),i=!s(r)?
+l.J(r):(!s(m)?m:"-");return i};k.Nc=function(p){var u=k.o.ea,m=false,r,i;if(p&&"organic"==p.da){r=w(l.J(p.R));for(i=0;i<u[g];i++)m=m||w(u[i])==r}return m};k.Ec=function(){var p="",u="",m=k.Rb;if(z(m)||k.Ib(m))return;p=w(x(m,"://")[1]);if(f(p,"/")){u=l.F(p,l.w(p,"/"));if(f(u,"?"))u=x(u,"?")[0];p=x(p,"/")[0]}if(0==l.w(p,"www."))p=l.F(p,4);return new l.n.s(q,p,q,"(referral)","referral",q,u)};k.sc=function(p){var u="";if(k.o.pa){u=l.Db(p);u=""!=u?u+"&":u}u+=p.search;return u};k.zc=function(){return new l.n.s(q,
+"(direct)",q,"(direct)","(none)",q,q)};k.Oc=function(p){var u=false,m,r,i=k.o.ga;if(p&&"referral"==p.da){m=w(l.d(p.ia));for(r=0;r<i[g];r++)u=u||f(m,w(i[r]))}return u};k.U=function(p){return q!=p&&p.Fa()};k.yc=function(p,u){var m="",r="-",i,b,e=0,j,t,v=k.f;if(!p)return"";t=k.a[l.m]?k.a[l.m]:"";m=k.sc(k.a.location);if(k.o.I&&p.Jb()){r=p.Ca();if(!s(r)&&!f(r,";")){p.Ra();return""}}r=n(t,l.X+v+".",";");i=k.Fc(m);if(k.U(i)){b=n(m,k.o.hb+"=","&");if("1"==b&&!s(r))return""}if(!k.U(i)){i=k.Fb();if(!s(r)&&
+k.Nc(i))return""}if(!k.U(i)&&u){i=k.Ec();if(!s(r)&&k.Oc(i))return""}if(!k.U(i))if(s(r)&&u)i=k.zc();if(!k.U(i))return"";if(!s(r)){var y=x(r,"."),E=new l.n.s;E.Cb(y.slice(4).join("."));j=w(E.ka())==w(i.ka());e=y[3]*1}if(!j||u){var F=n(t,l.r+v+".",";"),I=F.lastIndexOf("."),G=I>9?l.F(F,I+1)*1:0;e++;G=0==G?1:G;p.Xb([v,k.ja,G,e,i.ka()].join("."));p.Ra();return"&utmcn=1"}else return"&utmcr=1"}};_gat.n.s=function(d,a,c,h,o,k,l){var s=this;s.v=d;s.ia=a;s.ra=c;s.L=h;s.da=o;s.R=k;s.vb=l};_gat.n.s.prototype.ka=
+function(){var d=this,a=_gat,c=[],h=[[a.Wa,d.v],[a.Ya,d.ia],[a.$a,d.ra],[a.Ua,d.L],[a.Xa,d.da],[a.Za,d.R],[a.Va,d.vb]],o,k;if(d.Fa())for(o=0;o<h[a.c];o++)if(!a.q(h[o][1])){k=h[o][1].split("+").join("%20");k=k.split(" ").join("%20");a.h(c,h[o][0]+k)}return c.join("|")};_gat.n.s.prototype.Fa=function(){var d=this,a=_gat.q;return!(a(d.v)&&a(d.ia)&&a(d.ra))};_gat.n.s.prototype.Cb=function(d){var a=this,c=_gat,h=function(o){return c.J(c.C(d,o,"|"))};a.v=h(c.Wa);a.ia=h(c.Ya);a.ra=h(c.$a);a.L=h(c.Ua);a.da=
+h(c.Xa);a.R=h(c.Za);a.vb=h(c.Va)};_gat.Z=function(){var d=this,a=_gat,c={},h="k",o="v",k=[h,o],l="(",s=")",q="*",f="!",n="'",w={};w[n]="'0";w[s]="'1";w[q]="'2";w[f]="'3";var x=1;function g(m,r,i,b){if(a.b==c[m])c[m]={};if(a.b==c[m][r])c[m][r]=[];c[m][r][i]=b}function z(m,r,i){return a.b!=c[m]&&a.b!=c[m][r]?c[m][r][i]:a.b}function B(m,r){if(a.b!=c[m]&&a.b!=c[m][r]){c[m][r]=a.b;var i=true,b;for(b=0;b<k[a.c];b++)if(a.b!=c[m][k[b]]){i=false;break}if(i)c[m]=a.b}}function A(m){var r="",i=false,b,e;for(b=0;b<k[a.c];b++){e=m[k[b]];if(a.b!=
+e){if(i)r+=k[b];r+=p(e);i=false}else i=true}return r}function p(m){var r=[],i,b;for(b=0;b<m[a.c];b++)if(a.b!=m[b]){i="";if(b!=x&&a.b==m[b-1]){i+=b.toString();i+=f}i+=u(m[b]);a.h(r,i)}return l+r.join(q)+s}function u(m){var r="",i,b,e;for(i=0;i<m[a.c];i++){b=m.charAt(i);e=w[b];r+=a.b!=e?e:b}return r}d.Kc=function(m){return a.b!=c[m]};d.N=function(){var m=[],r;for(r in c)if(a.b!=c[r])a.h(m,r.toString()+A(c[r]));return m.join("")};d.Sc=function(m){if(m==a.b)return d.N();var r=[m.N()],i;for(i in c)if(a.b!=
+c[i]&&!m.Kc(i))a.h(r,i.toString()+A(c[i]));return r.join("")};d._setKey=function(m,r,i){if(typeof i!="string")return false;g(m,h,r,i);return true};d._setValue=function(m,r,i){if(typeof i!="number"&&(a.b==Number||!(i instanceof Number)))return false;if(Math.round(i)!=i||i==NaN||i==Infinity)return false;g(m,o,r,i.toString());return true};d._getKey=function(m,r){return z(m,h,r)};d._getValue=function(m,r){return z(m,o,r)};d._clearKey=function(m){B(m,h)};d._clearValue=function(m){B(m,o)}};_gat.ic=function(d,a){var c=this;c.jd=a;c.Pc=d;c._trackEvent=function(h,o,k){return a._trackEvent(c.Pc,h,o,k)}};_gat.kc=function(d){var a=this,c=_gat,h=c.b,o=c.q,k=c.w,l=c.F,s=c.C,q=c.P,f=c.z,n="location",w=c.c,x=h,g=new c.hc,z=false;a.a=document;a.e=window;a.ja=Math.round((new Date).getTime()/1000);a.H=d;a.yb=a.a.referrer;a.va=h;a.j=h;a.A=h;a.M=false;a.aa=h;a.rb="";a.l=h;a.Ab=h;a.f=h;a.u=h;function B(){if("auto"==g.g){var b=a.a.domain;if("www."==l(b,0,4))b=l(b,4);g.g=b}g.g=c.T(g.g)}function A(){var b=g.g,e=k(b,"www.google.")*k(b,".google.")*k(b,"google.");return e||"/"!=g.p||k(b,"google.org")>-1}function p(b,
+e,j){if(o(b)||o(e)||o(j))return"-";var t=s(b,c.r+a.f+".",e),v;if(!o(t)){v=f(t,".");v[5]=v[5]?v[5]*1+1:1;v[3]=v[4];v[4]=j;t=v.join(".")}return t}function u(){return"file:"!=a.a[n].protocol&&A()}function m(b){if(!b||""==b)return"";while(c.Lb(b.charAt(0)))b=l(b,1);while(c.Lb(b.charAt(b[w]-1)))b=l(b,0,b[w]-1);return b}function r(b,e,j){if(!o(b())){e(c.J(b()));if(!q(b(),";"))j()}}function i(b){var e,j=""!=b&&a.a[n].host!=b;if(j)for(e=0;e<g.B[w];e++)j=j&&k(c.T(b),c.T(g.B[e]))==-1;return j}a.Bc=function(){if(!g.g||
+""==g.g||"none"==g.g){g.g="";return 1}B();return g.pb?c.t(g.g):1};a.tc=function(b,e){if(o(b))b="-";else{e+=g.p&&"/"!=g.p?g.p:"";var j=k(b,e);b=j>=0&&j<=8?"0":("["==b.charAt(0)&&"]"==b.charAt(b[w]-1)?"-":b)}return b};a.Ia=function(b){var e="",j=a.a;e+=a.aa?a.aa.Xc():"";e+=g.qa?a.rb:"";e+=g.ta&&!o(j.title)?"&utmdt="+c.d(j.title):"";e+="&utmhid="+c.uc()+"&utmr="+a.va+"&utmp="+a.Tc(b);return e};a.Tc=function(b){var e=a.a[n];b=h!=b&&""!=b?c.d(b,true):c.d(e.pathname+unescape(e.search),true);return b};a.$c=
+function(b){if(a.Q()){var e="";if(a.l!=h&&a.l.N().length>0)e+="&utme="+c.d(a.l.N());e+=a.Ia(b);x.O(e,a.H,a.a,a.f)}};a.qc=function(){var b=new c.Y(a.a,g);return b.Ha(a.f)?b.Wc():h};a._getLinkerUrl=function(b,e){var j=f(b,"#"),t=b,v=a.qc();if(v)if(e&&1>=j[w])t+="#"+v;else if(!e||1>=j[w])if(1>=j[w])t+=(q(b,"?")?"&":"?")+v;else t=j[0]+(q(b,"?")?"&":"?")+v+"#"+j[1];return t};a.Zb=function(){var b;if(a.A&&a.A[w]>=10&&!q(a.A,"=")){a.u.Uc(a.A);a.u.cd();c._gasoDomain=g.g;c._gasoCPath=g.p;b=a.a.createElement("script");
+b.type="text/javascript";b.id="_gasojs";b.src="https://www.google.com/analytics/reporting/overlay_js?gaso="+a.A+"&"+c.wa();a.a.getElementsByTagName("head")[0].appendChild(b)}};a.Jc=function(){var b=a.a[c.m],e=a.ja,j=a.u,t=a.f+"",v=a.e,y=v?v.gaGlobal:h,E,F=q(b,c.r+t+"."),I=q(b,c.W+t),G=q(b,c.ma+t),C,D=[],H="",K=false,J;b=o(b)?"":b;if(g.I){E=c.Db(a.a[n]);if(g.pa&&!o(E))H=E+"&";H+=a.a[n].search;if(!o(H)&&q(H,c.r)){j.Rc(H);if(!j.Jb())j.pc();C=j.ya()}r(j.Ba,j.Wb,j.fc);r(j.Aa,j.Na,j.Qa)}if(!o(C))if(o(j.K())||
+o(j.za())){C=p(H,"&",e);a.M=true}else{D=f(j.K(),".");t=D[0]}else if(F)if(!I||!G){C=p(b,";",e);a.M=true}else{C=s(b,c.r+t+".",";");D=f(s(b,c.W+t,";"),".")}else{C=[t,c.Gc(),e,e,e,1].join(".");a.M=true;K=true}C=f(C,".");if(v&&y&&y.dh==t){C[4]=y.sid?y.sid:C[4];if(K){C[3]=y.sid?y.sid:C[4];if(y.vid){J=f(y.vid,".");C[1]=J[0];C[2]=J[1]}}}j.Ub(C.join("."));D[0]=t;D[1]=D[1]?D[1]:0;D[2]=undefined!=D[2]?D[2]:g.Yc;D[3]=D[3]?D[3]:C[4];j.La(D.join("."));j.Vb(t);if(!o(j.Hc()))j.Ma(j.t());j.dc();j.Pa();j.ec()};a.Lc=
+function(){x=new c.jc(g)};a._initData=function(){var b;if(!z){a.Lc();a.f=a.Bc();a.u=new c.Y(a.a,g)}if(u())a.Jc();if(!z){if(u()){a.va=a.tc(a.Ac(),a.a.domain);if(g.sa){a.aa=new c.gc(g.ua);a.aa.xc()}if(g.qa){b=new c.n(a.f,a.a,a.va,a.ja,g);a.rb=b.yc(a.u,a.M)}}a.l=new c.Z;a.Ab=new c.Z;z=true}if(!c.Hb)a.Mc()};a._visitCode=function(){a._initData();var b=s(a.a[c.m],c.r+a.f+".",";"),e=f(b,".");return e[w]<4?"":e[1]};a._cookiePathCopy=function(b){a._initData();if(a.u)a.u.bd(a.f,b)};a.Mc=function(){var b=a.a[n].hash,
+e;e=b&&""!=b&&0==k(b,"#gaso=")?s(b,"gaso=","&"):s(a.a[c.m],c.Sa,";");if(e[w]>=10){a.A=e;if(a.e.addEventListener)a.e.addEventListener("load",a.Zb,false);else a.e.attachEvent("onload",a.Zb)}c.Hb=true};a.Q=function(){return a._visitCode()%10000<g.ha*100};a.Vc=function(){var b,e,j=a.a.links;if(!g.Kb){var t=a.a.domain;if("www."==l(t,0,4))t=l(t,4);g.B.push("."+t)}for(b=0;b<j[w]&&(g.Ga==-1||b<g.Ga);b++){e=j[b];if(i(e.host))if(!e.gatcOnclick){e.gatcOnclick=e.onclick?e.onclick:a.Qc;e.onclick=function(v){var y=
+!this.target||this.target=="_self"||this.target=="_top"||this.target=="_parent";y=y&&!a.oc(v);a.ad(v,this,y);return y?false:(this.gatcOnclick?this.gatcOnclick(v):true)}}}};a.Qc=function(){};a._trackPageview=function(b){if(u()){a._initData();if(g.B)a.Vc();a.$c(b);a.M=false}};a._trackTrans=function(){var b=a.f,e=[],j,t,v,y;a._initData();if(a.j&&a.Q()){for(j=0;j<a.j.la[w];j++){t=a.j.la[j];c.h(e,t.S());for(v=0;v<t.ca[w];v++)c.h(e,t.ca[v].S())}for(y=0;y<e[w];y++)x.O(e[y],a.H,a.a,b,true)}};a._setTrans=
+function(){var b=a.a,e,j,t,v,y=b.getElementById?b.getElementById("utmtrans"):(b.utmform&&b.utmform.utmtrans?b.utmform.utmtrans:h);a._initData();if(y&&y.value){a.j=new c.i;v=f(y.value,"UTM:");g.G=!g.G||""==g.G?"|":g.G;for(e=0;e<v[w];e++){v[e]=m(v[e]);j=f(v[e],g.G);for(t=0;t<j[w];t++)j[t]=m(j[t]);if("T"==j[0])a._addTrans(j[1],j[2],j[3],j[4],j[5],j[6],j[7],j[8]);else if("I"==j[0])a._addItem(j[1],j[2],j[3],j[4],j[5],j[6])}}};a._addTrans=function(b,e,j,t,v,y,E,F){a.j=a.j?a.j:new c.i;return a.j.nb(b,e,
+j,t,v,y,E,F)};a._addItem=function(b,e,j,t,v,y){var E;a.j=a.j?a.j:new c.i;E=a.j.xa(b);if(!E)E=a._addTrans(b,"","","","","","","");E.mb(e,j,t,v,y)};a._setVar=function(b){if(b&&""!=b&&A()){a._initData();var e=new c.Y(a.a,g),j=a.f;e.Na(j+"."+c.d(b));e.Qa();if(a.Q())x.O("&utmt=var",a.H,a.a,a.f)}};a._link=function(b,e){if(g.I&&b){a._initData();a.a[n].href=a._getLinkerUrl(b,e)}};a._linkByPost=function(b,e){if(g.I&&b&&b.action){a._initData();b.action=a._getLinkerUrl(b.action,e)}};a._setXKey=function(b,e,
+j){a.l._setKey(b,e,j)};a._setXValue=function(b,e,j){a.l._setValue(b,e,j)};a._getXKey=function(b,e){return a.l._getKey(b,e)};a._getXValue=function(b,e){return a.l.getValue(b,e)};a._clearXKey=function(b){a.l._clearKey(b)};a._clearXValue=function(b){a.l._clearValue(b)};a._createXObj=function(){a._initData();return new c.Z};a._sendXEvent=function(b){var e="";a._initData();if(a.Q()){e+="&utmt=event&utme="+c.d(a.l.Sc(b))+a.Ia();x.O(e,a.H,a.a,a.f,false,true)}};a._createEventTracker=function(b){a._initData();
+return new c.ic(b,a)};a._trackEvent=function(b,e,j,t){var v=true,y=a.Ab;if(h!=b&&h!=e&&""!=b&&""!=e){y._clearKey(5);y._clearValue(5);v=y._setKey(5,1,b)?v:false;v=y._setKey(5,2,e)?v:false;v=h==j||y._setKey(5,3,j)?v:false;v=h==t||y._setValue(5,1,t)?v:false;if(v)a._sendXEvent(y)}else v=false;return v};a.ad=function(b,e,j){a._initData();if(a.Q()){var t=new c.Z;t._setKey(6,1,e.href);var v=j?function(){a.rc(b,e)}:undefined;x.O("&utmt=event&utme="+c.d(t.N())+a.Ia(),a.H,a.a,a.f,false,true,v)}};a.rc=function(b,
+e){if(!b)b=a.e.event;var j=true;if(e.gatcOnclick)j=e.gatcOnclick(b);if(j||typeof j=="undefined")if(!e.target||e.target=="_self")a.e.location=e.href;else if(e.target=="_top")a.e.top.document.location=e.href;else if(e.target=="_parent")a.e.parent.document.location=e.href};a.oc=function(b){if(!b)b=a.e.event;var e=b.shiftKey||b.ctrlKey||b.altKey;if(!e)if(b.modifiers&&a.e.Event)e=b.modifiers&a.e.Event.CONTROL_MASK||b.modifiers&a.e.Event.SHIFT_MASK||b.modifiers&a.e.Event.ALT_MASK;return e};a._setDomainName=
+function(b){g.g=b};a.dd=function(){return g.g};a._addOrganic=function(b,e){c.h(g.fa,new c.cb(b,e))};a._clearOrganic=function(){g.fa=[]};a.hd=function(){return g.fa};a._addIgnoredOrganic=function(b){c.h(g.ea,b)};a._clearIgnoredOrganic=function(){g.ea=[]};a.ed=function(){return g.ea};a._addIgnoredRef=function(b){c.h(g.ga,b)};a._clearIgnoredRef=function(){g.ga=[]};a.fd=function(){return g.ga};a._setAllowHash=function(b){g.pb=b?1:0};a._setCampaignTrack=function(b){g.qa=b?1:0};a._setClientInfo=function(b){g.sa=
+b?1:0};a._getClientInfo=function(){return g.sa};a._setCookiePath=function(b){g.p=b};a._setTransactionDelim=function(b){g.G=b};a._setCookieTimeout=function(b){g.wb=b};a._setDetectFlash=function(b){g.ua=b?1:0};a._getDetectFlash=function(){return g.ua};a._setDetectTitle=function(b){g.ta=b?1:0};a._getDetectTitle=function(){return g.ta};a._setLocalGifPath=function(b){g.Da=b};a._getLocalGifPath=function(){return g.Da};a._setLocalServerMode=function(){g.D=0};a._setRemoteServerMode=function(){g.D=1};a._setLocalRemoteServerMode=
+function(){g.D=2};a.gd=function(){return g.D};a._getServiceMode=function(){return g.D};a._setSampleRate=function(b){g.ha=b};a._setSessionTimeout=function(b){g.Tb=b};a._setAllowLinker=function(b){g.I=b?1:0};a._setAllowAnchor=function(b){g.pa=b?1:0};a._setCampNameKey=function(b){g.db=b};a._setCampContentKey=function(b){g.eb=b};a._setCampIdKey=function(b){g.fb=b};a._setCampMediumKey=function(b){g.gb=b};a._setCampNOKey=function(b){g.hb=b};a._setCampSourceKey=function(b){g.ib=b};a._setCampTermKey=function(b){g.jb=
+b};a._setCampCIdKey=function(b){g.kb=b};a._getAccount=function(){return a.H};a._getVersion=function(){return _gat.lb};a.kd=function(b){g.B=[];if(b)g.B=b};a.md=function(b){g.Kb=b};a.ld=function(b){g.Ga=b};a._setReferrerOverride=function(b){a.yb=b};a.Ac=function(){return a.yb}};_gat._getTracker=function(d){var a=new _gat.kc(d);return a};
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/header.png b/ipojo/runtime/core/doc/apache-felix-ipojo_files/header.png
new file mode 100644
index 0000000..977712b
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/header.png
Binary files differ
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/hoverIntent.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/hoverIntent.js
new file mode 100644
index 0000000..91da57b
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/hoverIntent.js
@@ -0,0 +1,84 @@
+(function($){
+	/* hoverIntent by Brian Cherne */
+	$.fn.hoverIntent = function(f,g) {
+		// default configuration options
+		var cfg = {
+			sensitivity: 7,
+			interval: 100,
+			timeout: 0
+		};
+		// override configuration options with user supplied object
+		cfg = $.extend(cfg, g ? { over: f, out: g } : f );
+
+		// instantiate variables
+		// cX, cY = current X and Y position of mouse, updated by mousemove event
+		// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
+		var cX, cY, pX, pY;
+
+		// A private function for getting mouse position
+		var track = function(ev) {
+			cX = ev.pageX;
+			cY = ev.pageY;
+		};
+
+		// A private function for comparing current and previous mouse position
+		var compare = function(ev,ob) {
+			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
+			// compare mouse positions to see if they've crossed the threshold
+			if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
+				$(ob).unbind("mousemove",track);
+				// set hoverIntent state to true (so mouseOut can be called)
+				ob.hoverIntent_s = 1;
+				return cfg.over.apply(ob,[ev]);
+			} else {
+				// set previous coordinates for next time
+				pX = cX; pY = cY;
+				// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
+				ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
+			}
+		};
+
+		// A private function for delaying the mouseOut function
+		var delay = function(ev,ob) {
+			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
+			ob.hoverIntent_s = 0;
+			return cfg.out.apply(ob,[ev]);
+		};
+
+		// A private function for handling mouse 'hovering'
+		var handleHover = function(e) {
+			// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
+			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
+			while ( p && p != this ) { try { p = p.parentNode; } catch(e) { p = this; } }
+			if ( p == this ) { return false; }
+
+			// copy objects to be passed into t (required for event object to be passed in IE)
+			var ev = jQuery.extend({},e);
+			var ob = this;
+
+			// cancel hoverIntent timer if it exists
+			if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
+
+			// else e.type == "onmouseover"
+			if (e.type == "mouseover") {
+				// set "previous" X and Y position based on initial entry point
+				pX = ev.pageX; pY = ev.pageY;
+				// update "current" X and Y position based on mousemove
+				$(ob).bind("mousemove",track);
+				// start polling interval (self-calling timeout) to compare mouse coordinates over time
+				if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
+
+			// else e.type == "onmouseout"
+			} else {
+				// unbind expensive mousemove event
+				$(ob).unbind("mousemove",track);
+				// if hoverIntent state is true, then call the mouseOut function after the specified delay
+				if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
+			}
+		};
+
+		// bind the function to the two event listeners
+		return this.mouseover(handleHover).mouseout(handleHover);
+	};
+	
+})(jQuery);
\ No newline at end of file
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/ipojo.png b/ipojo/runtime/core/doc/apache-felix-ipojo_files/ipojo.png
new file mode 100644
index 0000000..8f8d89e
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/ipojo.png
Binary files differ
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/jquery-1.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/jquery-1.js
new file mode 100644
index 0000000..b1ae21d
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/jquery-1.js
@@ -0,0 +1,19 @@
+/*
+ * jQuery JavaScript Library v1.3.2
+ * http://jquery.com/
+ *
+ * Copyright (c) 2009 John Resig
+ * Dual licensed under the MIT and GPL licenses.
+ * http://docs.jquery.com/License
+ *
+ * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
+ * Revision: 6246
+ */
+(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F<J;F++){var G=M[F];if(G.selected){K=o(G).val();if(H){return K}L.push(K)}}return L}return(E.value||"").replace(/\r/g,"")}return g}if(typeof K==="number"){K+=""}return this.each(function(){if(this.nodeType!=1){return}if(o.isArray(K)&&/radio|checkbox/.test(this.type)){this.checked=(o.inArray(this.value,K)>=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G<E;G++){L.call(K(this[G],H),this.length>1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H<I;H++){if((G=arguments[H])!=null){for(var F in G){var K=J[F],L=G[F];if(J===L){continue}if(E&&L&&typeof L==="object"&&!L.nodeType){J[F]=o.extend(E,K||(L.length!=null?[]:{}),L)}else{if(L!==g){J[F]=L}}}}}return J};var b=/z-?index|font-?weight|opacity|zoom|line-?height/i,q=document.defaultView||{},s=Object.prototype.toString;o.extend({noConflict:function(E){l.$=p;if(E){l.jQuery=y}return o},isFunction:function(E){return s.call(E)==="[object Function]"},isArray:function(E){return s.call(E)==="[object Array]"},isXMLDoc:function(E){return E.nodeType===9&&E.documentElement.nodeName!=="HTML"||!!E.ownerDocument&&o.isXMLDoc(E.ownerDocument)},globalEval:function(G){if(G&&/\S/.test(G)){var F=document.getElementsByTagName("head")[0]||document.documentElement,E=document.createElement("script");E.type="text/javascript";if(o.support.scriptEval){E.appendChild(document.createTextNode(G))}else{E.text=G}F.insertBefore(E,F.firstChild);F.removeChild(E)}},nodeName:function(F,E){return F.nodeName&&F.nodeName.toUpperCase()==E.toUpperCase()},each:function(G,K,F){var E,H=0,I=G.length;if(F){if(I===g){for(E in G){if(K.apply(G[E],F)===false){break}}}else{for(;H<I;){if(K.apply(G[H++],F)===false){break}}}}else{if(I===g){for(E in G){if(K.call(G[E],E,G[E])===false){break}}}else{for(var J=G[0];H<I&&K.call(J,H,J)!==false;J=G[++H]){}}}return G},prop:function(H,I,G,F,E){if(o.isFunction(I)){I=I.call(H,F)}return typeof I==="number"&&G=="curCSS"&&!b.test(E)?I+"px":I},className:{add:function(E,F){o.each((F||"").split(/\s+/),function(G,H){if(E.nodeType==1&&!o.className.has(E.className,H)){E.className+=(E.className?" ":"")+H}})},remove:function(E,F){if(E.nodeType==1){E.className=F!==g?o.grep(E.className.split(/\s+/),function(G){return !o.className.has(F,G)}).join(" "):""}},has:function(F,E){return F&&o.inArray(E,(F.className||F).toString().split(/\s+/))>-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+"></"+T+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!O.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!O.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!O.indexOf("<td")||!O.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!O.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||!o.support.htmlSerialize&&[1,"div<div>","</div>"]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/<tbody/i.test(S),N=!O.indexOf("<table")&&!R?L.firstChild&&L.firstChild.childNodes:Q[1]=="<table>"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E<F;E++){if(H[E]===G){return E}}return -1},merge:function(H,E){var F=0,G,I=H.length;if(!o.support.getAll){while((G=E[F++])!=null){if(G.nodeType!=8){H[I++]=G}}}else{while((G=E[F++])!=null){H[I++]=G}}return H},unique:function(K){var F=[],E={};try{for(var G=0,H=K.length;G<H;G++){var J=o.data(K[G]);if(!E[J]){E[J]=true;F.push(K[G])}}}catch(I){F=K}return F},grep:function(F,J,E){var G=[];for(var H=0,I=F.length;H<I;H++){if(!E!=!J(F[H],H)){G.push(F[H])}}return G},map:function(E,J){var F=[];for(var G=0,H=E.length;G<H;G++){var I=J(E[G],G);if(I!=null){F[F.length]=I}}return F.concat.apply([],F)}});var C=navigator.userAgent.toLowerCase();o.browser={version:(C.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[0,"0"])[1],safari:/webkit/.test(C),opera:/opera/.test(C),msie:/msie/.test(C)&&!/opera/.test(C),mozilla:/mozilla/.test(C)&&!/(compatible|webkit)/.test(C)};o.each({parent:function(E){return E.parentNode},parents:function(E){return o.dir(E,"parentNode")},next:function(E){return o.nth(E,2,"nextSibling")},prev:function(E){return o.nth(E,2,"previousSibling")},nextAll:function(E){return o.dir(E,"nextSibling")},prevAll:function(E){return o.dir(E,"previousSibling")},siblings:function(E){return o.sibling(E.parentNode.firstChild,E)},children:function(E){return o.sibling(E.firstChild)},contents:function(E){return o.nodeName(E,"iframe")?E.contentDocument||E.contentWindow.document:o.makeArray(E.childNodes)}},function(E,F){o.fn[E]=function(G){var H=o.map(this,F);if(G&&typeof G=="string"){H=o.multiFilter(G,H)}return this.pushStack(o.unique(H),E,G)}});o.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(E,F){o.fn[E]=function(G){var J=[],L=o(G);for(var K=0,H=L.length;K<H;K++){var I=(K>0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}});
+/*
+ * Sizzle CSS Selector Engine - v0.9.3
+ *  Copyright 2009, The Dojo Foundation
+ *  Released under the MIT, BSD, and GPL Licenses.
+ *  More information: http://sizzlejs.com/
+ */
+(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa<ab.length;aa++){if(ab[aa]===ab[aa-1]){ab.splice(aa--,1)}}}}}return ab};F.matches=function(T,U){return F(T,null,null,U)};F.find=function(aa,T,ab){var Z,X;if(!aa){return[]}for(var W=0,V=I.order.length;W<V;W++){var Y=I.order[W],X;if((X=I.match[Y].exec(aa))){var U=RegExp.leftContext;if(U.substr(U.length-1)!=="\\"){X[1]=(X[1]||"").replace(/\\/g,"");Z=I.find[Y](X,T,ab);if(Z!=null){aa=aa.replace(I.match[Y],"");break}}}}if(!Z){Z=T.getElementsByTagName("*")}return{set:Z,expr:aa}};F.filter=function(ad,ac,ag,W){var V=ad,ai=[],aa=ac,Y,T,Z=ac&&ac[0]&&Q(ac[0]);while(ad&&ac.length){for(var ab in I.filter){if((Y=I.match[ab].exec(ad))!=null){var U=I.filter[ab],ah,af;T=false;if(aa==ai){ai=[]}if(I.preFilter[ab]){Y=I.preFilter[ab](Y,aa,ag,ai,W,Z);if(!Y){T=ah=true}else{if(Y===true){continue}}}if(Y){for(var X=0;(af=aa[X])!=null;X++){if(af){ah=U(af,Y,X,aa);var ae=W^!!ah;if(ag&&ah!=null){if(ae){T=true}else{aa[X]=false}}else{if(ae){ai.push(af);T=true}}}}}if(ah!==g){if(!ag){aa=ai}ad=ad.replace(I.match[ab],"");if(!T){return[]}break}}}if(ad==V){if(T==null){throw"Syntax error, unrecognized expression: "+ad}else{break}}V=ad}return aa};var I=F.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF_-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF_-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(T){return T.getAttribute("href")}},relative:{"+":function(aa,T,Z){var X=typeof T==="string",ab=X&&!/\W/.test(T),Y=X&&!ab;if(ab&&!Z){T=T.toUpperCase()}for(var W=0,V=aa.length,U;W<V;W++){if((U=aa[W])){while((U=U.previousSibling)&&U.nodeType!==1){}aa[W]=Y||U&&U.nodeName===T?U||false:U===T}}if(Y){F.filter(T,aa,true)}},">":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){var W=Y.parentNode;Z[V]=W.nodeName===U?W:false}}}else{for(var V=0,T=Z.length;V<T;V++){var Y=Z[V];if(Y){Z[V]=X?Y.parentNode:Y.parentNode===U}}if(X){F.filter(U,Z,true)}}},"":function(W,U,Y){var V=L++,T=S;if(!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("parentNode",U,V,W,X,Y)},"~":function(W,U,Y){var V=L++,T=S;if(typeof U==="string"&&!U.match(/\W/)){var X=U=Y?U:U.toUpperCase();T=P}T("previousSibling",U,V,W,X,Y)}},find:{ID:function(U,V,W){if(typeof V.getElementById!=="undefined"&&!W){var T=V.getElementById(U[1]);return T?[T]:[]}},NAME:function(V,Y,Z){if(typeof Y.getElementsByName!=="undefined"){var U=[],X=Y.getElementsByName(V[1]);for(var W=0,T=X.length;W<T;W++){if(X[W].getAttribute("name")===V[1]){U.push(X[W])}}return U.length===0?null:U}},TAG:function(T,U){return U.getElementsByTagName(T[1])}},preFilter:{CLASS:function(W,U,V,T,Z,aa){W=" "+W[1].replace(/\\/g,"")+" ";if(aa){return W}for(var X=0,Y;(Y=U[X])!=null;X++){if(Y){if(Z^(Y.className&&(" "+Y.className+" ").indexOf(W)>=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return U<T[3]-0},gt:function(V,U,T){return U>T[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W<T;W++){if(Y[W]===Z){return false}}return true}}}},CHILD:function(T,W){var Z=W[1],U=T;switch(Z){case"only":case"first":while(U=U.previousSibling){if(U.nodeType===1){return false}}if(Z=="first"){return true}U=T;case"last":while(U=U.nextSibling){if(U.nodeType===1){return false}}return true;case"nth":var V=W[2],ac=W[3];if(V==1&&ac==0){return true}var Y=W[0],ab=T.parentNode;if(ab&&(ab.sizcache!==Y||!T.nodeIndex)){var X=0;for(U=ab.firstChild;U;U=U.nextSibling){if(U.nodeType===1){U.nodeIndex=++X}}ab.sizcache=Y}var aa=T.nodeIndex-ac;if(V==0){return aa==0}else{return(aa%V==0&&aa/V>=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V<T;V++){U.push(X[V])}}else{for(var V=0;X[V];V++){U.push(X[V])}}}return U}}var G;if(document.documentElement.compareDocumentPosition){G=function(U,T){var V=U.compareDocumentPosition(T)&4?-1:U===T?0:1;if(V===0){hasDuplicate=true}return V}}else{if("sourceIndex" in document.documentElement){G=function(U,T){var V=U.sourceIndex-T.sourceIndex;if(V===0){hasDuplicate=true}return V}}else{if(document.createRange){G=function(W,U){var V=W.ownerDocument.createRange(),T=U.ownerDocument.createRange();V.selectNode(W);V.collapse(true);T.selectNode(U);T.collapse(true);var X=V.compareBoundaryPoints(Range.START_TO_END,T);if(X===0){hasDuplicate=true}return X}}}}(function(){var U=document.createElement("form"),V="script"+(new Date).getTime();U.innerHTML="<input name='"+V+"'/>";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="<a href='#'></a>";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="<p class='TEST'></p>";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="<div class='test e'></div><div class='test'></div>";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1&&!ac){T.sizcache=Y;T.sizset=W}if(T.nodeName===Z){X=T;break}T=T[U]}ad[W]=X}}}function S(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W<V;W++){var T=ad[W];if(T){if(ab&&T.nodeType===1){T.sizcache=Y;T.sizset=W}T=T[U];var X=false;while(T){if(T.sizcache===Y){X=ad[T.sizset];break}if(T.nodeType===1){if(!ac){T.sizcache=Y;T.sizset=W}if(typeof Z!=="string"){if(T===Z){X=true;break}}else{if(F.filter(Z,[T]).length>0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z<U;Z++){F(T,V[Z],W)}return F.filter(X,W)};o.find=F;o.filter=F.filter;o.expr=F.selectors;o.expr[":"]=o.expr.filters;F.selectors.filters.hidden=function(T){return T.offsetWidth===0||T.offsetHeight===0};F.selectors.filters.visible=function(T){return T.offsetWidth>0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F<E.length){o.event.proxy(G,E[F++])}return this.click(o.event.proxy(G,function(H){this.lastToggle=(this.lastToggle||0)%F;H.preventDefault();return E[this.lastToggle++].apply(this,arguments)||false}))},hover:function(E,F){return this.mouseenter(E).mouseleave(F)},ready:function(E){B();if(o.isReady){E.call(document,o)}else{o.readyList.push(E)}return this},live:function(G,F){var E=o.event.proxy(F);E.guid+=this.selector+G;o(document).bind(i(G,this.selector),this.selector,E);return this},die:function(F,E){o(document).unbind(i(F,this.selector),E?{guid:E.guid+this.selector+F}:null);return this}});function c(H){var E=RegExp("(^|\\.)"+H.type+"(\\.|$)"),G=true,F=[];o.each(o.data(this,"events").live||[],function(I,J){if(E.test(J.type)){var K=o(H.target).closest(J.data)[0];if(K){F.push({elem:K,fn:J})}}});F.sort(function(J,I){return o.data(J.elem,"closest")-o.data(I.elem,"closest")});o.each(F,function(){if(this.fn.call(this.elem,H,this.fn.data)===false){return(G=false)}});return G}function i(F,E){return["live",F,E.replace(/\./g,"`").replace(/ /g,"|")].join(".")}o.extend({isReady:false,readyList:[],ready:function(){if(!o.isReady){o.isReady=true;if(o.readyList){o.each(o.readyList,function(){this.call(document,o)});o.readyList=null}o(document).triggerHandler("ready")}}});var x=false;function B(){if(x){return}x=true;if(document.addEventListener){document.addEventListener("DOMContentLoaded",function(){document.removeEventListener("DOMContentLoaded",arguments.callee,false);o.ready()},false)}else{if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);o.ready()}});if(document.documentElement.doScroll&&l==l.top){(function(){if(o.isReady){return}try{document.documentElement.doScroll("left")}catch(E){setTimeout(arguments.callee,0);return}o.ready()})()}}}o.event.add(l,"load",o.ready)}o.each(("blur,focus,load,resize,scroll,unload,click,dblclick,mousedown,mouseup,mousemove,mouseover,mouseout,mouseenter,mouseleave,change,select,submit,keydown,keypress,keyup,error").split(","),function(F,E){o.fn[E]=function(G){return G?this.bind(E,G):this.trigger(E)}});o(l).bind("unload",function(){for(var E in o.cache){if(E!=1&&o.cache[E].handle){o.event.remove(o.cache[E].handle.elem)}}});(function(){o.support={};var F=document.documentElement,G=document.createElement("script"),K=document.createElement("div"),J="script"+(new Date).getTime();K.style.display="none";K.innerHTML='   <link/><table></table><a href="/a" style="color:red;float:left;opacity:.5;">a</a><select><option>text</option></select><object><param/></object>';var H=K.getElementsByTagName("*"),E=K.getElementsByTagName("a")[0];if(!H||!H.length||!E){return}o.support={leadingWhitespace:K.firstChild.nodeType==3,tbody:!K.getElementsByTagName("tbody").length,objectAll:!!K.getElementsByTagName("object")[0].getElementsByTagName("*").length,htmlSerialize:!!K.getElementsByTagName("link").length,style:/red/.test(E.getAttribute("style")),hrefNormalized:E.getAttribute("href")==="/a",opacity:E.style.opacity==="0.5",cssFloat:!!E.style.cssFloat,scriptEval:false,noCloneEvent:true,boxModel:null};G.type="text/javascript";try{G.appendChild(document.createTextNode("window."+J+"=1;"))}catch(I){}F.insertBefore(G,F.firstChild);if(l[J]){o.support.scriptEval=true;delete l[J]}F.removeChild(G);if(K.attachEvent&&K.fireEvent){K.attachEvent("onclick",function(){o.support.noCloneEvent=false;K.detachEvent("onclick",arguments.callee)});K.cloneNode(true).fireEvent("onclick")}o(function(){var L=document.createElement("div");L.style.width=L.style.paddingLeft="1px";document.body.appendChild(L);o.boxModel=o.support.boxModel=L.offsetWidth===2;document.body.removeChild(L).style.display="none"})})();var w=o.support.cssFloat?"cssFloat":"styleFloat";o.props={"for":"htmlFor","class":"className","float":w,cssFloat:w,styleFloat:w,readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",tabindex:"tabIndex"};o.fn.extend({_load:o.fn.load,load:function(G,J,K){if(typeof G!=="string"){return this._load(G)}var I=G.indexOf(" ");if(I>=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("<div/>").append(M.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H<F;H++){var E=o.data(this[H],"olddisplay");this[H].style.display=E||"";if(o.css(this[H],"display")==="none"){var G=this[H].tagName,K;if(m[G]){K=m[G]}else{var I=o("<"+G+" />").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H<F;H++){this[H].style.display=o.data(this[H],"olddisplay")||""}return this}},hide:function(H,I){if(H){return this.animate(t("hide",3),H,I)}else{for(var G=0,F=this.length;G<F;G++){var E=o.data(this[G],"olddisplay");if(!E&&E!=="none"){o.data(this[G],"olddisplay",o.css(this[G],"display"))}}for(var G=0,F=this.length;G<F;G++){this[G].style.display="none"}return this}},_toggle:o.fn.toggle,toggle:function(G,F){var E=typeof G==="boolean";return o.isFunction(G)&&o.isFunction(F)?this._toggle.apply(this,arguments):G==null||E?this.each(function(){var H=E?G:o(this).is(":hidden");o(this)[H?"show":"hide"]()}):this.animate(t("toggle",3),G,F)},fadeTo:function(E,G,F){return this.animate({opacity:G},E,F)},animate:function(I,F,H,G){var E=o.speed(F,H,G);return this[E.queue===false?"each":"queue"](function(){var K=o.extend({},E),M,L=this.nodeType==1&&o(this).is(":hidden"),J=this;for(M in I){if(I[M]=="hide"&&L||I[M]=="show"&&!L){return K.complete.call(this)}if((M=="height"||M=="width")&&this.style){K.display=o.css(this,"display");K.overflow=this.style.overflow}}if(K.overflow!=null){this.style.overflow="hidden"}K.curAnim=o.extend({},I);o.each(I,function(O,S){var R=new o.fx(J,K,O);if(/toggle|show|hide/.test(S)){R[S=="toggle"?L?"show":"hide":S](I)}else{var Q=S.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),T=R.cur(true)||0;if(Q){var N=parseFloat(Q[2]),P=Q[3]||"px";if(P!="px"){J.style[O]=(N||1)+P;T=((N||1)/R.cur(true))*T;J.style[O]=T+P}if(Q[1]){N=((Q[1]=="-="?-1:1)*N)+T}R.custom(T,N,P)}else{R.custom(T,S,"")}}});return true})},stop:function(F,E){var G=o.timers;if(F){this.queue([])}this.each(function(){for(var H=G.length-1;H>=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J<K.length;J++){if(!K[J]()){K.splice(J--,1)}}if(!K.length){clearInterval(n);n=g}},13)}},show:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.show=true;this.custom(this.prop=="width"||this.prop=="height"?1:0,this.cur());o(this.elem).show()},hide:function(){this.options.orig[this.prop]=o.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(H){var G=e();if(H||G>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='<div style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;"><div></div></div><table style="position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})();
\ No newline at end of file
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/logo.png b/ipojo/runtime/core/doc/apache-felix-ipojo_files/logo.png
new file mode 100644
index 0000000..dccbddc
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/logo.png
Binary files differ
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushCSharp.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushCSharp.js
new file mode 100644
index 0000000..f45540f
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushCSharp.js
@@ -0,0 +1,30 @@
+dp.sh.Brushes.CSharp = function()
+{
+	var keywords =	'abstract as base bool break byte case catch char checked class const ' +
+					'continue decimal default delegate do double else enum event explicit ' +
+					'extern false finally fixed float for foreach get goto if implicit in int ' +
+					'interface internal is lock long namespace new null object operator out ' +
+					'override params private protected public readonly ref return sbyte sealed set ' +
+					'short sizeof stackalloc static string struct switch this throw true try ' +
+					'typeof uint ulong unchecked unsafe ushort using virtual void while';
+
+	this.regexList = [
+		// There's a slight problem with matching single line comments and figuring out
+		// a difference between // and ///. Using lookahead and lookbehind solves the
+		// problem, unfortunately JavaScript doesn't support lookbehind. So I'm at a 
+		// loss how to translate that regular expression to JavaScript compatible one.
+//		{ regex: new RegExp('(?<!/)//(?!/).*$|(?<!/)////(?!/).*$|/\\*[^\\*]*(.)*?\\*/', 'gm'),	css: 'comment' },			// one line comments starting with anything BUT '///' and multiline comments
+//		{ regex: new RegExp('(?<!/)///(?!/).*$', 'gm'),											css: 'comments' },		// XML comments starting with ///
+
+		{ regex: new RegExp('//.*$', 'gm'),							css: 'comment' },			// one line comments
+		{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'),				css: 'comment' },			// multiline comments
+		{ regex: new RegExp('"(?:\\.|[^\\""])*"', 'g'),				css: 'string' },			// strings
+		{ regex: new RegExp('^\\s*#.*', 'gm'),						css: 'preprocessor' },		// preprocessor tags like #region and #endregion
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// c# keyword
+		];
+
+	this.CssClass = 'dp-c';
+}
+
+dp.sh.Brushes.CSharp.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.CSharp.Aliases	= ['c#', 'c-sharp', 'csharp'];
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushDelphi.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushDelphi.js
new file mode 100644
index 0000000..efeb2f7
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushDelphi.js
@@ -0,0 +1,31 @@
+/* Delphi brush is contributed by Eddie Shipman */
+dp.sh.Brushes.Delphi = function()
+{
+	var keywords =	'abs addr and ansichar ansistring array as asm begin boolean byte cardinal ' +
+					'case char class comp const constructor currency destructor div do double ' +
+					'downto else end except exports extended false file finalization finally ' +
+					'for function goto if implementation in inherited int64 initialization ' +
+					'integer interface is label library longint longword mod nil not object ' +
+					'of on or packed pansichar pansistring pchar pcurrency pdatetime pextended ' + 
+					'pint64 pointer private procedure program property pshortstring pstring ' + 
+					'pvariant pwidechar pwidestring protected public published raise real real48 ' +
+					'record repeat set shl shortint shortstring shr single smallint string then ' +
+					'threadvar to true try type unit until uses val var varirnt while widechar ' +
+					'widestring with word write writeln xor';
+
+	this.regexList = [
+		{ regex: new RegExp('\\(\\*[\\s\\S]*?\\*\\)', 'gm'),		css: 'comment' },  			// multiline comments (* *)
+		{ regex: new RegExp('{(?!\\$)[\\s\\S]*?}', 'gm'),			css: 'comment' },  			// multiline comments { }
+		{ regex: new RegExp('//.*$', 'gm'),							css: 'comment' },  			// one line
+		{ regex: new RegExp('\'(?:\\.|[^\\\'\'])*\'', 'g'),			css: 'string' },			// strings
+		{ regex: new RegExp('\\{\\$[a-zA-Z]+ .+\\}', 'g'),			css: 'directive' },			// Compiler Directives and Region tags
+		{ regex: new RegExp('\\b[\\d\\.]+\\b', 'g'),				css: 'number' },			// numbers 12345
+		{ regex: new RegExp('\\$[a-zA-Z0-9]+\\b', 'g'),				css: 'number' },			// numbers $F5D3
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// keyword
+		];
+
+	this.CssClass = 'dp-delphi';
+}
+
+dp.sh.Brushes.Delphi.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Delphi.Aliases	= ['delphi', 'pascal'];
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushJScript.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushJScript.js
new file mode 100644
index 0000000..4ef8b9b
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushJScript.js
@@ -0,0 +1,22 @@
+dp.sh.Brushes.JScript = function()
+{
+	var keywords =	'abstract boolean break byte case catch char class const continue debugger ' +
+					'default delete do double else enum export extends false final finally float ' +
+					'for function goto if implements import in instanceof int interface long native ' +
+					'new null package private protected public return short static super switch ' +
+					'synchronized this throw throws transient true try typeof var void volatile while with';
+
+	this.regexList = [
+		{ regex: new RegExp('//.*$', 'gm'),							css: 'comment' },			// one line comments
+		{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'),				css: 'comment' },			// multiline comments
+		{ regex: new RegExp('"(?:[^"\n]|[\"])*?"', 'g'),			css: 'string' },			// double quoted strings
+		{ regex: new RegExp("'(?:[^'\n]|[\'])*?'", 'g'),			css: 'string' },			// single quoted strings
+		{ regex: new RegExp('^\\s*#.*', 'gm'),						css: 'preprocessor' },		// preprocessor tags like #region and #endregion
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// keywords
+		];
+
+	this.CssClass = 'dp-c';
+}
+
+dp.sh.Brushes.JScript.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.JScript.Aliases	= ['js', 'jscript', 'javascript'];
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushJava.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushJava.js
new file mode 100644
index 0000000..b75d334
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushJava.js
@@ -0,0 +1,22 @@
+dp.sh.Brushes.Java = function()
+{
+	var keywords =	'abstract assert boolean break byte case catch char class const' +
+                    'continue default do double else enum extends false final finally float' +
+                    'for goto if implements import instanceof inst interface log native' +
+                    'new null package private protected public return short static strictfp super' +
+                    'switch synchronized this throw throws transient true try void volatile while';
+
+    this.regexList = [
+		{ regex: new RegExp('//.*$', 'gm'),							css: 'comment' },			// one line comments
+		{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'),				css: 'comment' },			// multiline comments
+		{ regex: new RegExp('"(?:[^"\n]|[\"])*?"', 'g'),			css: 'string' },			// double quoted strings
+		{ regex: new RegExp("'(?:[^'\n]|[\'])*?'", 'g'),			css: 'string' },			// single quoted strings
+		{ regex: new RegExp('^\\s*@.*', 'gm'),						css: 'preprocessor' },		// preprocessor tags like @see
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// keywords
+		];
+
+	this.CssClass = 'dp-c';
+}
+
+dp.sh.Brushes.Java.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Java.Aliases	    = ['java'];
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushPhp.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushPhp.js
new file mode 100644
index 0000000..57c85d4
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushPhp.js
@@ -0,0 +1,23 @@
+dp.sh.Brushes.Php = function()
+{
+	var keywords =	'and or xor __FILE__ __LINE__ array as break case ' +
+					'cfunction class const continue declare default die do echo else ' +
+					'elseif empty enddeclare endfor endforeach endif endswitch endwhile eval exit ' +
+					'extends for foreach function global if include include_once isset list ' +
+					'new old_function print require require_once return static switch unset use ' +
+					'var while __FUNCTION__ __CLASS__';
+
+	this.regexList = [
+		{ regex: new RegExp('//.*$', 'gm'),							css: 'comment' },			// one line comments
+		{ regex: new RegExp('/\\*[\\s\\S]*?\\*/', 'g'),				css: 'comment' },			// multiline comments
+		{ regex: new RegExp('"(?:[^"\n]|[\"])*?"', 'g'),			css: 'string' },			// double quoted strings
+		{ regex: new RegExp("'(?:[^'\n]|[\'])*?'", 'g'),			css: 'string' },			// single quoted strings
+		{ regex: new RegExp('\\$\\w+', 'g'),						css: 'vars' },				// variables
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// keyword
+		];
+
+	this.CssClass = 'dp-c';
+}
+
+dp.sh.Brushes.Php.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Php.Aliases	= ['php'];
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushPython.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushPython.js
new file mode 100644
index 0000000..1d61339
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushPython.js
@@ -0,0 +1,71 @@
+/* Python 2.3 syntax contributed by Gheorghe Milas */
+dp.sh.Brushes.Python = function()
+{
+	var keywords =		'and assert break class continue def del elif else except exec ' +
+						'finally for from global if import in is lambda not or object pass print ' +
+						'raise return try yield while';
+	
+	var builtins =		'self __builtin__ __dict__ __future__ __methods__ __members__ __author__ __email__ __version__' +
+						'__class__ __bases__ __import__ __main__ __name__ __doc__ __self__ __debug__ __slots__ ' +
+						'abs append apply basestring bool buffer callable chr classmethod clear close cmp coerce compile complex ' +
+						'conjugate copy count delattr dict dir divmod enumerate Ellipsis eval execfile extend False file fileno filter float flush ' +
+						'get getattr globals has_key hasarttr hash hex id index input insert int intern isatty isinstance isubclass ' +
+						'items iter keys len list locals long map max min mode oct open ord pop pow property range ' +
+						'raw_input read readline readlines reduce reload remove repr reverse round seek setattr slice sum ' +
+						'staticmethod str super tell True truncate tuple type unichr unicode update values write writelines xrange zip';
+	
+	var magicmethods =	'__abs__ __add__ __and__ __call__ __cmp__ __coerce__ __complex__ __concat__ __contains__ __del__ __delattr__ __delitem__ ' +
+						'__delslice__ __div__ __divmod__ __float__ __getattr__ __getitem__ __getslice__ __hash__ __hex__ __eq__ __le__ __lt__ __gt__ __ge__ ' +
+						'__iadd__ __isub__ __imod__ __idiv__ __ipow__ __iand__ __ior__ __ixor__ __ilshift__ __irshift__ ' +
+						'__invert__ __init__ __int__ __inv__ __iter__ __len__ __long__ __lshift__ __mod__ __mul__ __new__ __neg__ __nonzero__ __oct__ __or__ ' +
+						'__pos__ __pow__ __radd__ __rand__ __rcmp__ __rdiv__ __rdivmod__ __repeat__ __repr__ __rlshift__ __rmod__ __rmul__ ' +
+						'__ror__ __rpow__ __rrshift__ __rshift__ __rsub__ __rxor__ __setattr__ __setitem__ __setslice__ __str__ __sub__ __xor__';
+	
+	var exceptions =	'Exception StandardError ArithmeticError LookupError EnvironmentError AssertionError AttributeError EOFError ' +
+						'FutureWarning IndentationError OverflowWarning PendingDeprecationWarning ReferenceError RuntimeWarning ' +
+						'SyntaxWarning TabError UnicodeDecodeError UnicodeEncodeError UnicodeTranslateError UserWarning Warning ' +
+						'IOError ImportError IndexError KeyError KeyboardInterrupt MemoryError NameError NotImplementedError OSError ' +
+						'RuntimeError StopIteration SyntaxError SystemError SystemExit TypeError UnboundLocalError UnicodeError ValueError ' +
+						'FloatingPointError OverflowError WindowsError ZeroDivisionError';
+	
+	var types =			'NoneType TypeType IntType LongType FloatType ComplexType StringType UnicodeType BufferType TupleType ListType ' +
+						'DictType FunctionType LambdaType CodeType ClassType UnboundMethodType InstanceType MethodType BuiltinFunctionType BuiltinMethodType ' +
+						'ModuleType FileType XRangeType TracebackType FrameType SliceType EllipsisType';
+	
+	var commonlibs =	'anydbm array asynchat asyncore AST base64 binascii binhex bisect bsddb buildtools bz2 ' +
+						'BaseHTTPServer Bastion calendar cgi cmath cmd codecs codeop commands compiler copy copy_reg ' +
+						'cPickle crypt cStringIO csv curses Carbon CGIHTTPServer ConfigParser Cookie datetime dbhash ' +
+						'dbm difflib dircache distutils doctest DocXMLRPCServer email encodings errno exceptions fcntl ' +
+						'filecmp fileinput ftplib gc gdbm getopt getpass glob gopherlib gzip heapq htmlentitydefs ' +
+						'htmllib httplib HTMLParser imageop imaplib imgfile imghdr imp inspect itertools jpeg keyword ' +
+						'linecache locale logging mailbox mailcap marshal math md5 mhlib mimetools mimetypes mimify mmap ' +
+						'mpz multifile mutex MimeWriter netrc new nis nntplib nsremote operator optparse os parser pickle pipes ' +
+						'popen2 poplib posix posixfile pprint preferences profile pstats pwd pydoc pythonprefs quietconsole ' +
+						'quopri Queue random re readline resource rexec rfc822 rgbimg sched select sets sgmllib sha shelve shutil ' +
+						'signal site smtplib socket stat statcache string struct symbol sys syslog SimpleHTTPServer ' +
+						'SimpleXMLRPCServer SocketServer StringIO tabnanny tarfile telnetlib tempfile termios textwrap ' +
+						'thread threading time timeit token tokenize traceback tty types Tkinter unicodedata unittest ' +
+						'urllib urllib2 urlparse user UserDict UserList UserString warnings weakref webbrowser whichdb ' +
+						'xml xmllib xmlrpclib xreadlines zipfile zlib';
+
+	this.regexList = [
+		{ regex: new RegExp('#.*$', 'gm'),								css: 'comment' },			// comments
+		{ regex: new RegExp('^\\s*"""(.|\n)*?"""\\s*$', 'gm'),			css: 'docstring' },			// documentation string "
+		{ regex: new RegExp('^\\s*\'\'\'(.|\n)*?\'\'\'\\s*$', 'gm'),	css: 'docstring' },			// documentation string '
+		{ regex: new RegExp('"""(.|\n)*?"""', 'g'),						css: 'string' },			// multi-line strings "
+		{ regex: new RegExp('\'\'\'(.|\n)*?\'\'\'', 'g'),				css: 'string' },			// multi-line strings '
+		{ regex: new RegExp('"(?:\\.|[^\\""])*"', 'g'),					css: 'string' },			// strings "
+		{ regex: new RegExp('\'(?:\\.|[^\\\'\'])*\'', 'g'),				css: 'string' },			// strings '
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),			css: 'keyword' },			// keywords
+		{ regex: new RegExp(this.GetKeywords(builtins), 'gm'),			css: 'builtins' },			// builtin objects, functions, methods, magic attributes
+		{ regex: new RegExp(this.GetKeywords(magicmethods), 'gm'),		css: 'magicmethods' },		// special methods
+		{ regex: new RegExp(this.GetKeywords(exceptions), 'gm'),		css: 'exceptions' },		// standard exception classes
+		{ regex: new RegExp(this.GetKeywords(types), 'gm'),				css: 'types' },				// types from types.py
+		{ regex: new RegExp(this.GetKeywords(commonlibs), 'gm'),		css: 'commonlibs' }			// common standard library modules
+		];
+
+	this.CssClass = 'dp-py';
+}
+
+dp.sh.Brushes.Python.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Python.Aliases	= ['py', 'python'];
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushShell.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushShell.js
new file mode 100644
index 0000000..5e7c2ef
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushShell.js
@@ -0,0 +1,27 @@
+dp.sh.Brushes.Shell = function()
+{
+	var keywords =	'alias array autor base basename break ' +
+                    'cat catv cd chdir cmpv continue conv copy ' +
+                    'crc ctime cut dirname echo env eval exec else if elif then ' +
+                    'export expr extern false fmode fork fprint ' +
+                    'fsize fstat fullname global goend goto grep ifdef ' +
+                    'ifset ifenv inv kill line link list ' +
+                    'local localset mkdirs mktemp move mtime nop print ' +
+                    'prints pwd read readc readl readonly rel ' +
+                    'remove return seek set shift sleep sortl ' +
+                    'static stime sum system systime tee test times ' +
+                    'tr trap true type typeset tz umask unalias ' +
+                    'unexport unset unsetenv ver wait wc whence ' +
+                    'sane exit prompt let';
+
+
+	this.regexList = [
+		{ regex: new RegExp('#.*$', 'gm'),							css: 'comment' },  			// one line
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// keyword
+		];
+
+	this.CssClass = 'dp-shell';
+}
+
+dp.sh.Brushes.Shell.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Shell.Aliases	= ['shell'];
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushSql.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushSql.js
new file mode 100644
index 0000000..4855d0c
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushSql.js
@@ -0,0 +1,40 @@
+dp.sh.Brushes.Sql = function()
+{
+	var funcs	=	'abs avg case cast coalesce convert count current_timestamp ' +
+					'current_user day isnull left lower month nullif replace right ' +
+					'session_user space substring sum system_user upper user year';
+
+	var keywords =	'absolute action add after alter as asc at authorization begin bigint ' +
+					'binary bit by cascade char character check checkpoint close collate ' +
+					'column commit committed connect connection constraint contains continue ' +
+					'create cube current current_date current_time cursor database date ' +
+					'deallocate dec decimal declare default delete desc distinct double drop ' +
+					'dynamic else end end-exec escape except exec execute false fetch first ' +
+					'float for force foreign forward free from full function global goto grant ' +
+					'group grouping having hour ignore index inner insensitive insert instead ' +
+					'int integer intersect into is isolation key last level load local max min ' +
+					'minute modify move name national nchar next no numeric of off on only ' +
+					'open option order out output partial password precision prepare primary ' +
+					'prior privileges procedure public read real references relative repeatable ' +
+					'restrict return returns revoke rollback rollup rows rule schema scroll ' +
+					'second section select sequence serializable set size smallint static ' +
+					'statistics table temp temporary then time timestamp to top transaction ' +
+					'translation trigger true truncate uncommitted union unique update values ' +
+					'varchar varying view when where with work';
+
+	var operators =	'all and any between cross in join like not null or outer some';
+
+	this.regexList = [
+		{ regex: new RegExp('--(.*)$', 'gm'),						css: 'comment' },			// one line and multiline comments
+		{ regex: new RegExp('"(?:\\.|[^\\""])*"', 'g'),				css: 'string' },			// strings
+		{ regex: new RegExp('\'(?:\\.|[^\\\'\'])*\'', 'g'),			css: 'string' },			// strings
+		{ regex: new RegExp(this.GetKeywords(funcs), 'gmi'),		css: 'func' },				// functions
+		{ regex: new RegExp(this.GetKeywords(operators), 'gmi'),	css: 'op' },				// operators and such
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gmi'),		css: 'keyword' }			// keyword
+		];
+
+	this.CssClass = 'dp-sql';
+}
+
+dp.sh.Brushes.Sql.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Sql.Aliases	= ['sql'];
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushVb.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushVb.js
new file mode 100644
index 0000000..431e16f
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushVb.js
@@ -0,0 +1,29 @@
+dp.sh.Brushes.Vb = function()
+{
+	var keywords =	'AddHandler AddressOf AndAlso Alias And Ansi As Assembly Auto ' +
+					'Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate ' +
+					'CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType ' +
+					'Date Decimal Declare Default Delegate Dim DirectCast Do Double Each ' +
+					'Else ElseIf End Enum Erase Error Event Exit False Finally For Friend ' +
+					'Function Get GetType GoSub GoTo Handles If Implements Imports In ' +
+					'Inherits Integer Interface Is Let Lib Like Long Loop Me Mod Module ' +
+					'MustInherit MustOverride MyBase MyClass Namespace New Next Not Nothing ' +
+					'NotInheritable NotOverridable Object On Option Optional Or OrElse ' +
+					'Overloads Overridable Overrides ParamArray Preserve Private Property ' +
+					'Protected Public RaiseEvent ReadOnly ReDim REM RemoveHandler Resume ' +
+					'Return Select Set Shadows Shared Short Single Static Step Stop String ' +
+					'Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until ' +
+					'Variant When While With WithEvents WriteOnly Xor';
+
+	this.regexList = [
+		{ regex: new RegExp('\'.*$', 'gm'),							css: 'comment' },			// one line comments
+		{ regex: new RegExp('"(?:\\.|[^\\""])*"', 'g'),				css: 'string' },			// strings
+		{ regex: new RegExp('^\\s*#.*', 'gm'),						css: 'preprocessor' },		// preprocessor tags like #region and #endregion
+		{ regex: new RegExp(this.GetKeywords(keywords), 'gm'),		css: 'keyword' }			// c# keyword
+		];
+
+	this.CssClass = 'dp-vb';
+}
+
+dp.sh.Brushes.Vb.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Vb.Aliases	= ['vb', 'vb.net'];
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushXml.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushXml.js
new file mode 100644
index 0000000..941ad57
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shBrushXml.js
@@ -0,0 +1,61 @@
+dp.sh.Brushes.Xml = function()
+{
+	this.CssClass = 'dp-xml';
+}
+
+dp.sh.Brushes.Xml.prototype	= new dp.sh.Highlighter();
+dp.sh.Brushes.Xml.Aliases	= ['xml', 'xhtml', 'xslt', 'html', 'xhtml'];
+
+dp.sh.Brushes.Xml.prototype.ProcessRegexList = function()
+{
+	function push(array, value)
+	{
+		array[array.length] = value;
+	}
+	
+	/* If only there was a way to get index of a group within a match, the whole XML
+	   could be matched with the expression looking something like that:
+	
+	   (<!\[CDATA\[\s*.*\s*\]\]>)
+	   | (<!--\s*.*\s*?-->)
+	   | (<)*(\w+)*\s*(\w+)\s*=\s*(".*?"|'.*?'|\w+)(/*>)*
+	   | (</?)(.*?)(/?>)
+	*/
+	var index	= 0;
+	var match	= null;
+	var regex	= null;
+
+	// Match CDATA in the following format <![ ... [ ... ]]>
+	// <\!\[[\w\s]*?\[(.|\s)*?\]\]>
+	this.GetMatches(new RegExp('<\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\]>', 'gm'), 'cdata');
+	
+	// Match comments
+	// <!--\s*.*\s*?-->
+	this.GetMatches(new RegExp('<!--\\s*.*\\s*?-->', 'gm'), 'comments');
+
+	// Match attributes and their values
+	// (\w+)\s*=\s*(".*?"|\'.*?\'|\w+)*
+	regex = new RegExp('([\\w-\.]+)\\s*=\\s*(".*?"|\'.*?\'|\\w+)*', 'gm');
+	while((match = regex.exec(this.code)) != null)
+	{
+		push(this.matches, new dp.sh.Match(match[1], match.index, 'attribute'));
+	
+		// if xml is invalid and attribute has no property value, ignore it	
+		if(match[2] != undefined)
+		{
+			push(this.matches, new dp.sh.Match(match[2], match.index + match[0].indexOf(match[2]), 'attribute-value'));
+		}
+	}
+
+	// Match opening and closing tag brackets
+	// </*\?*(?!\!)|/*\?*>
+	this.GetMatches(new RegExp('</*\\?*(?!\\!)|/*\\?*>', 'gm'), 'tag');
+
+	// Match tag names
+	// </*\?*\s*(\w+)
+	regex = new RegExp('</*\\?*\\s*([\\w-\.]+)', 'gm');
+	while((match = regex.exec(this.code)) != null)
+	{
+		push(this.matches, new dp.sh.Match(match[1], match.index + match[0].indexOf(match[1]), 'tag-name'));
+	}
+}
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/shCore.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shCore.js
new file mode 100644
index 0000000..b27395e
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/shCore.js
@@ -0,0 +1,622 @@
+/**
+ * Code Syntax Highlighter.
+ * Version 1.3.0
+ * Copyright (C) 2004 Alex Gorbatchev.
+ * http://www.dreamprojections.com/syntaxhighlighter/
+ * 
+ * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General 
+ * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) 
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 
+ * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to 
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
+ */
+
+//
+// create namespaces
+//
+var dp = {
+	sh :					// dp.sh
+	{
+		Utils	: {},		// dp.sh.Utils
+		Brushes	: {},		// dp.sh.Brushes
+		Strings : {},
+		Version : '1.3.0'
+	}
+};
+
+dp.sh.Strings = {
+	AboutDialog : '<html><head><title>About...</title></head><body class="dp-about"><table cellspacing="0"><tr><td class="copy"><p class="title">dp.SyntaxHighlighter</div><div class="para">Version: {V}</p><p><a href="http://www.dreamprojections.com/syntaxhighlighter/?ref=about" target="_blank">http://www.dreamprojections.com/SyntaxHighlighter</a></p>&copy;2004-2005 Alex Gorbatchev. All right reserved.</td></tr><tr><td class="footer"><input type="button" class="close" value="OK" onClick="window.close()"/></td></tr></table></body></html>',
+	
+	// tools
+	ExpandCode : '+ expand code',
+	ViewPlain : 'view plain',
+	Print : 'print',
+	CopyToClipboard : 'copy to clipboard',
+	About : '?',
+	
+	CopiedToClipboard : 'The code is in your clipboard now.'
+};
+
+dp.SyntaxHighlighter = dp.sh;
+
+//
+// Dialog and toolbar functions
+//
+
+dp.sh.Utils.Expand = function(sender)
+{
+	var table = sender;
+	var span = sender;
+
+	// find the span in which the text label and pipe contained so we can hide it
+	while(span != null && span.tagName != 'SPAN')
+		span = span.parentNode;
+
+	// find the table
+	while(table != null && table.tagName != 'TABLE')
+		table = table.parentNode;
+	
+	// remove the 'expand code' button
+	span.parentNode.removeChild(span);
+	
+	table.tBodies[0].className = 'show';
+	table.parentNode.style.height = '100%'; // containing div isn't getting updated properly when the TBODY is shown
+}
+
+// opens a new windows and puts the original unformatted source code inside.
+dp.sh.Utils.ViewSource = function(sender)
+{
+	var code = sender.parentNode.originalCode;
+	var wnd = window.open('', '_blank', 'width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=1');
+	
+	code = code.replace(/</g, '&lt;');
+	
+	wnd.document.write('<pre>' + code + '</pre>');
+	wnd.document.close();
+}
+
+// copies the original source code in to the clipboard (IE only)
+dp.sh.Utils.ToClipboard = function(sender)
+{
+	var code = sender.parentNode.originalCode;
+	
+	// This works only for IE. There's a way to make it work with Mozilla as well,
+	// but it requires security settings changed on the client, which isn't by
+	// default, so 99% of users won't have it working anyways.
+	if(window.clipboardData)
+	{
+		window.clipboardData.setData('text', code);
+		
+		alert(dp.sh.Strings.CopiedToClipboard);
+	}
+}
+
+// creates an invisible iframe, puts the original source code inside and prints it
+dp.sh.Utils.PrintSource = function(sender)
+{
+	var td		= sender.parentNode;
+	var code	= td.processedCode;
+	var iframe	= document.createElement('IFRAME');
+	var doc		= null;
+	var wnd		= 
+
+	// this hides the iframe
+	iframe.style.cssText = 'position:absolute; width:0px; height:0px; left:-5px; top:-5px;';
+	
+	td.appendChild(iframe);
+	
+	doc = iframe.contentWindow.document;
+	code = code.replace(/</g, '&lt;');
+	
+	doc.open();
+	doc.write('<pre>' + code + '</pre>');
+	doc.close();
+	
+	iframe.contentWindow.focus();
+	iframe.contentWindow.print();
+	
+	td.removeChild(iframe);
+}
+
+dp.sh.Utils.About = function()
+{
+	var wnd	= window.open('', '_blank', 'dialog,width=320,height=150,scrollbars=0');
+	var doc	= wnd.document;
+	
+	var styles = document.getElementsByTagName('style');
+	var links = document.getElementsByTagName('link');
+	
+	doc.write(dp.sh.Strings.AboutDialog.replace('{V}', dp.sh.Version));
+	
+	// copy over ALL the styles from the parent page
+	for(var i = 0; i < styles.length; i++)
+		doc.write('<style>' + styles[i].innerHTML + '</style>');
+
+	for(var i = 0; i < links.length; i++)
+		if(links[i].rel.toLowerCase() == 'stylesheet')
+			doc.write('<link type="text/css" rel="stylesheet" href="' + links[i].href + '"></link>');
+	
+	doc.close();
+	wnd.focus();
+}
+
+//
+// Match object
+//
+dp.sh.Match = function(value, index, css)
+{
+	this.value		= value;
+	this.index		= index;
+	this.length		= value.length;
+	this.css		= css;
+}
+
+//
+// Highlighter object
+//
+dp.sh.Highlighter = function()
+{
+	this.addGutter = true;
+	this.addControls = true;
+	this.collapse = false;
+	this.tabsToSpaces = true;
+}
+
+// static callback for the match sorting
+dp.sh.Highlighter.SortCallback = function(m1, m2)
+{
+	// sort matches by index first
+	if(m1.index < m2.index)
+		return -1;
+	else if(m1.index > m2.index)
+		return 1;
+	else
+	{
+		// if index is the same, sort by length
+		if(m1.length < m2.length)
+			return -1;
+		else if(m1.length > m2.length)
+			return 1;
+	}
+	return 0;
+}
+
+// gets a list of all matches for a given regular expression
+dp.sh.Highlighter.prototype.GetMatches = function(regex, css)
+{
+	var index = 0;
+	var match = null;
+
+	while((match = regex.exec(this.code)) != null)
+	{
+		this.matches[this.matches.length] = new dp.sh.Match(match[0], match.index, css);
+	}
+}
+
+dp.sh.Highlighter.prototype.AddBit = function(str, css)
+{
+	var span = document.createElement('span');
+	
+	str = str.replace(/&/g, '&amp;');
+	str = str.replace(/ /g, '&nbsp;');
+	str = str.replace(/</g, '&lt;');
+	str = str.replace(/\n/gm, '&nbsp;<br>');
+
+	// when adding a piece of code, check to see if it has line breaks in it 
+	// and if it does, wrap individual line breaks with span tags
+	if(css != null)
+	{
+		var regex = new RegExp('<br>', 'gi');
+		
+		if(regex.test(str))
+		{
+			var lines = str.split('&nbsp;<br>');
+			
+			str = '';
+			
+			for(var i = 0; i < lines.length; i++)
+			{
+				span			= document.createElement('SPAN');
+				span.className	= css;
+				span.innerHTML	= lines[i];
+				
+				this.div.appendChild(span);
+				
+				// don't add a <BR> for the last line
+				if(i + 1 < lines.length)
+					this.div.appendChild(document.createElement('BR'));
+			}
+		}
+		else
+		{
+			span.className = css;
+			span.innerHTML = str;
+			this.div.appendChild(span);
+		}
+	}
+	else
+	{
+		span.innerHTML = str;
+		this.div.appendChild(span);
+	}
+}
+
+// checks if one match is inside any other match
+dp.sh.Highlighter.prototype.IsInside = function(match)
+{
+	if(match == null || match.length == 0)
+		return;
+	
+	for(var i = 0; i < this.matches.length; i++)
+	{
+		var c = this.matches[i];
+		
+		if(c == null)
+			continue;
+		
+		if((match.index > c.index) && (match.index <= c.index + c.length))
+			return true;
+	}
+	
+	return false;
+}
+
+dp.sh.Highlighter.prototype.ProcessRegexList = function()
+{
+	for(var i = 0; i < this.regexList.length; i++)
+		this.GetMatches(this.regexList[i].regex, this.regexList[i].css);
+}
+
+dp.sh.Highlighter.prototype.ProcessSmartTabs = function(code)
+{
+	var lines	= code.split('\n');
+	var result	= '';
+	var tabSize	= 4;
+	var tab		= '\t';
+
+	// This function inserts specified amount of spaces in the string
+	// where a tab is while removing that given tab. 
+	function InsertSpaces(line, pos, count)
+	{
+		var left	= line.substr(0, pos);
+		var right	= line.substr(pos + 1, line.length);	// pos + 1 will get rid of the tab
+		var spaces	= '';
+		
+		for(var i = 0; i < count; i++)
+			spaces += ' ';
+		
+		return left + spaces + right;
+	}
+
+	// This function process one line for 'smart tabs'
+	function ProcessLine(line, tabSize)
+	{
+		if(line.indexOf(tab) == -1)
+			return line;
+
+		var pos = 0;
+
+		while((pos = line.indexOf(tab)) != -1)
+		{
+			// This is pretty much all there is to the 'smart tabs' logic.
+			// Based on the position within the line and size of a tab, 
+			// calculate the amount of spaces we need to insert.
+			var spaces = tabSize - pos % tabSize;
+			
+			line = InsertSpaces(line, pos, spaces);
+		}
+		
+		return line;
+	}
+
+	// Go through all the lines and do the 'smart tabs' magic.
+	for(var i = 0; i < lines.length; i++)
+		result += ProcessLine(lines[i], tabSize) + '\n';
+	
+	return result;
+}
+
+dp.sh.Highlighter.prototype.SwitchToTable = function()
+{
+	// thanks to Lachlan Donald from SitePoint.com for this <br/> tag fix.
+	var html	= this.div.innerHTML.replace(/<(br)\/?>/gi, '\n');
+	var lines	= html.split('\n');
+	var row		= null;
+	var cell	= null;
+	var tBody	= null;
+	var html	= '';
+	var pipe	= ' | ';
+
+	// creates an anchor to a utility
+	function UtilHref(util, text)
+	{
+		return '<a href="#" onclick="dp.sh.Utils.' + util + '(this); return false;">' + text + '</a>';
+	}
+	
+	tBody = document.createElement('TBODY');	// can be created and all others go to tBodies collection.
+
+	this.table.appendChild(tBody);
+		
+	if(this.addGutter == true)
+	{
+		row = tBody.insertRow(-1);
+		cell = row.insertCell(-1);
+		cell.className = 'tools-corner';
+	}
+
+	if(this.addControls == true)
+	{
+		var tHead = document.createElement('THEAD');	// controls will be placed in here
+		this.table.appendChild(tHead);
+
+		row = tHead.insertRow(-1);
+
+		// add corner if there's a gutter
+		if(this.addGutter == true)
+		{
+			cell = row.insertCell(-1);
+			cell.className = 'tools-corner';
+		}
+		
+		cell = row.insertCell(-1);
+		
+		// preserve some variables for the controls
+		cell.originalCode = this.originalCode;
+		cell.processedCode = this.code;
+		cell.className = 'tools';
+		
+		if(this.collapse == true)
+		{
+			tBody.className = 'hide';
+			cell.innerHTML += '<span><b>' + UtilHref('Expand', dp.sh.Strings.ExpandCode) + '</b>' + pipe + '</span>';
+		}
+
+		cell.innerHTML += UtilHref('ViewSource', dp.sh.Strings.ViewPlain) + pipe + UtilHref('PrintSource', dp.sh.Strings.Print);
+		
+		// IE has this clipboard object which is easy enough to use
+		if(window.clipboardData)
+			cell.innerHTML += pipe + UtilHref('ToClipboard', dp.sh.Strings.CopyToClipboard);
+		
+		cell.innerHTML += pipe + UtilHref('About', dp.sh.Strings.About);
+	}
+
+	for(var i = 0, lineIndex = this.firstLine; i < lines.length - 1; i++, lineIndex++)
+	{
+		row = tBody.insertRow(-1);
+		
+		if(this.addGutter == true)
+		{
+			cell = row.insertCell(-1);
+			cell.className = 'gutter';
+			cell.innerHTML = lineIndex;
+		}
+
+		cell = row.insertCell(-1);
+		cell.className = 'line' + (i % 2 + 1);		// uses .line1 and .line2 css styles for alternating lines
+		cell.innerHTML = lines[i];
+	}
+	
+	this.div.innerHTML	= '';
+}
+
+dp.sh.Highlighter.prototype.Highlight = function(code)
+{
+	function Trim(str)
+	{
+		return str.replace(/^\s*(.*?)[\s\n]*$/g, '$1');
+	}
+	
+	function Chop(str)
+	{
+		return str.replace(/\n*$/, '').replace(/^\n*/, '');
+	}
+
+	function Unindent(str)
+	{
+		var lines = str.split('\n');
+		var indents = new Array();
+		var regex = new RegExp('^\\s*', 'g');
+		var min = 1000;
+
+		// go through every line and check for common number of indents
+		for(var i = 0; i < lines.length && min > 0; i++)
+		{
+			if(Trim(lines[i]).length == 0)
+				continue;
+				
+			var matches = regex.exec(lines[i]);
+
+			if(matches != null && matches.length > 0)
+				min = Math.min(matches[0].length, min);
+		}
+
+		// trim minimum common number of white space from the begining of every line
+		if(min > 0)
+			for(var i = 0; i < lines.length; i++)
+				lines[i] = lines[i].substr(min);
+
+		return lines.join('\n');
+	}
+	
+	// This function returns a portions of the string from pos1 to pos2 inclusive
+	function Copy(string, pos1, pos2)
+	{
+		return string.substr(pos1, pos2 - pos1);
+	}
+
+	var pos	= 0;
+	
+	this.originalCode = code;
+	this.code = Chop(Unindent(code));
+	this.div = document.createElement('DIV');
+	this.table = document.createElement('TABLE');
+	this.matches = new Array();
+
+	if(this.CssClass != null)
+		this.table.className = this.CssClass;
+
+	// replace tabs with spaces
+	if(this.tabsToSpaces == true)
+		this.code = this.ProcessSmartTabs(this.code);
+
+	this.table.border = 0;
+	this.table.cellSpacing = 0;
+	this.table.cellPadding = 0;
+
+	this.ProcessRegexList();	
+
+	// if no matches found, add entire code as plain text
+	if(this.matches.length == 0)
+	{
+		this.AddBit(this.code, null);
+		this.SwitchToTable();
+		return;
+	}
+
+	// sort the matches
+	this.matches = this.matches.sort(dp.sh.Highlighter.SortCallback);
+
+	// The following loop checks to see if any of the matches are inside
+	// of other matches. This process would get rid of highligting strings
+	// inside comments, keywords inside strings and so on.
+	for(var i = 0; i < this.matches.length; i++)
+		if(this.IsInside(this.matches[i]))
+			this.matches[i] = null;
+
+	// Finally, go through the final list of matches and pull the all
+	// together adding everything in between that isn't a match.
+	for(var i = 0; i < this.matches.length; i++)
+	{
+		var match = this.matches[i];
+
+		if(match == null || match.length == 0)
+			continue;
+		
+		this.AddBit(Copy(this.code, pos, match.index), null);
+		this.AddBit(match.value, match.css);
+		
+		pos = match.index + match.length;
+	}
+	
+	this.AddBit(this.code.substr(pos), null);
+
+	this.SwitchToTable();
+}
+
+dp.sh.Highlighter.prototype.GetKeywords = function(str) 
+{
+	return '\\b' + str.replace(/ /g, '\\b|\\b') + '\\b';
+}
+
+// highlightes all elements identified by name and gets source code from specified property
+dp.sh.HighlightAll = function(name, showGutter /* optional */, showControls /* optional */, collapseAll /* optional */, firstLine /* optional */)
+{
+	function FindValue()
+	{
+		var a = arguments;
+		
+		for(var i = 0; i < a.length; i++)
+		{
+			if(a[i] == null)
+				continue;
+				
+			if(typeof(a[i]) == 'string' && a[i] != '')
+				return a[i] + '';
+		
+			if(typeof(a[i]) == 'object' && a[i].value != '')
+				return a[i].value + '';
+		}
+		
+		return null;
+	}
+	
+	function IsOptionSet(value, list)
+	{
+		for(var i = 0; i < list.length; i++)
+			if(list[i] == value)
+				return true;
+		
+		return false;
+	}
+	
+	function GetOptionValue(name, list, defaultValue)
+	{
+		var regex = new RegExp('^' + name + '\\[(\\w+)\\]$', 'gi');
+		var matches = null;
+
+		for(var i = 0; i < list.length; i++)
+			if((matches = regex.exec(list[i])) != null)
+				return matches[1];
+		
+		return defaultValue;
+	}
+
+	var elements = document.getElementsByName(name);
+	var highlighter = null;
+	var registered = new Object();
+	var propertyName = 'value';
+	
+	// if no code blocks found, leave
+	if(elements == null)
+		return;
+
+	// register all brushes
+	for(var brush in dp.sh.Brushes)
+	{
+		var aliases = dp.sh.Brushes[brush].Aliases;
+		
+		if(aliases == null)
+			continue;
+		
+		for(var i = 0; i < aliases.length; i++)
+			registered[aliases[i]] = brush;
+	}
+
+	for(var i = 0; i < elements.length; i++)
+	{
+		var element = elements[i];
+		var options = FindValue(
+				element.attributes['class'], element.className, 
+				element.attributes['language'], element.language
+				);
+		var language = '';
+		
+		if(options == null)
+			continue;
+		
+		options = options.split(':');
+		
+		language = options[0].toLowerCase();
+		
+		if(registered[language] == null)
+			continue;
+		
+		// instantiate a brush
+		highlighter = new dp.sh.Brushes[registered[language]]();
+		
+		// hide the original element
+		element.style.display = 'none';
+
+		highlighter.addGutter = (showGutter == null) ? !IsOptionSet('nogutter', options) : showGutter;
+		highlighter.addControls = (showControls == null) ? !IsOptionSet('nocontrols', options) : showControls;
+		highlighter.collapse = (collapseAll == null) ? IsOptionSet('collapse', options) : collapseAll;
+		
+		// first line idea comes from Andrew Collington, thanks!
+		highlighter.firstLine = (firstLine == null) ? parseInt(GetOptionValue('firstline', options, 1)) : firstLine;
+
+		highlighter.Highlight(element[propertyName]);
+
+		// place the result table inside a div
+		var div = document.createElement('DIV');
+		
+		div.className = 'dp-highlighter';
+		div.appendChild(highlighter.table);
+
+		element.parentNode.insertBefore(div, element);		
+	}	
+}
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/site.css b/ipojo/runtime/core/doc/apache-felix-ipojo_files/site.css
new file mode 100644
index 0000000..959ab0a
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/site.css
@@ -0,0 +1,25 @@
+/* @override http://felix.apache.org/site/media.data/site.css */
+
+body { background-color: #ffffff; color: #3b3b3b; font-family: Tahoma, Arial, sans-serif; font-size: 10pt; line-height: 140% }
+h1, h2, h3, h4, h5, h6 { font-weight: normal; color: #000000; line-height: 100%; margin-top: 0px}
+h1 { font-size: 200% }
+h2 { font-size: 175% }
+h3 { font-size: 150% }
+h4 { font-size: 140% }
+h5 { font-size: 130% }
+h6 { font-size: 120% }
+a { color: #1980af }
+a:visited { color: #1980af }
+a:hover { color: #1faae9 }
+.title { position: absolute; left: 1px; right: 1px; top:25px; height: 81px; background: url(http://felix.apache.org/site/media.data/gradient.png) repeat-x; background-position: bottom; }
+.logo { position: absolute; width: 15em; height: 81px; text-align: center; }
+.header { text-align: right; margin-right: 20pt; margin-top: 30pt;}
+.menu { border-top: 10px solid #f9bb00; position: absolute; top: 107px; left: 1px; width: 15em; bottom: 0px; padding: 0px; background-color: #fcfcfc }
+.menu ul { background-color: #fdf5d9; list-style: none; padding-left: 4em; margin-top: 0px; padding-top: 2em; padding-bottom: 2em; margin-left: 0px; color: #4a4a43}
+.menu a { text-decoration: none; color: #4a4a43 }
+.main { position: absolute; border-top: 10px solid #cde0ea; top: 107px; left: 15em; right: 1px; margin-left: 2px; padding-right: 4em; padding-left: 1em; padding-top: 1em;}
+.code { background-color: #eeeeee; border: solid 1px black; padding: 0.5em }
+.code-keyword { color: #880000 }
+.code-quote { color: #008800 }
+.code-object { color: #0000dd }
+.code-java { margin: 0em }
\ No newline at end of file
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/status_online.png b/ipojo/runtime/core/doc/apache-felix-ipojo_files/status_online.png
new file mode 100644
index 0000000..947bd4b
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/status_online.png
Binary files differ
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/superfish.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/superfish.js
new file mode 100644
index 0000000..c6a9c7d
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/superfish.js
@@ -0,0 +1,121 @@
+
+/*
+ * Superfish v1.4.8 - jQuery menu widget
+ * Copyright (c) 2008 Joel Birch
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * 	http://www.opensource.org/licenses/mit-license.php
+ * 	http://www.gnu.org/licenses/gpl.html
+ *
+ * CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
+ */
+
+;(function($){
+	$.fn.superfish = function(op){
+
+		var sf = $.fn.superfish,
+			c = sf.c,
+			$arrow = $(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
+			over = function(){
+				var $$ = $(this), menu = getMenu($$);
+				clearTimeout(menu.sfTimer);
+				$$.showSuperfishUl().siblings().hideSuperfishUl();
+			},
+			out = function(){
+				var $$ = $(this), menu = getMenu($$), o = sf.op;
+				clearTimeout(menu.sfTimer);
+				menu.sfTimer=setTimeout(function(){
+					o.retainPath=($.inArray($$[0],o.$path)>-1);
+					$$.hideSuperfishUl();
+					if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
+				},o.delay);	
+			},
+			getMenu = function($menu){
+				var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
+				sf.op = sf.o[menu.serial];
+				return menu;
+			},
+			addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
+			
+		return this.each(function() {
+			var s = this.serial = sf.o.length;
+			var o = $.extend({},sf.defaults,op);
+			o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
+				$(this).addClass([o.hoverClass,c.bcClass].join(' '))
+					.filter('li:has(ul)').removeClass(o.pathClass);
+			});
+			sf.o[s] = sf.op = o;
+			
+			$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
+				if (o.autoArrows) addArrow( $('>a:first-child',this) );
+			})
+			.not('.'+c.bcClass)
+				.hideSuperfishUl();
+			
+			var $a = $('a',this);
+			$a.each(function(i){
+				var $li = $a.eq(i).parents('li');
+				$a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
+			});
+			o.onInit.call(this);
+			
+		}).each(function() {
+			var menuClasses = [c.menuClass];
+			if (sf.op.dropShadows  && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass);
+			$(this).addClass(menuClasses.join(' '));
+		});
+	};
+
+	var sf = $.fn.superfish;
+	sf.o = [];
+	sf.op = {};
+	sf.IE7fix = function(){
+		var o = sf.op;
+		if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined)
+			this.toggleClass(sf.c.shadowClass+'-off');
+		};
+	sf.c = {
+		bcClass     : 'sf-breadcrumb',
+		menuClass   : 'sf-js-enabled',
+		anchorClass : 'sf-with-ul',
+		arrowClass  : 'sf-sub-indicator',
+		shadowClass : 'sf-shadow'
+	};
+	sf.defaults = {
+		hoverClass	: 'sfHover',
+		pathClass	: 'overideThisToUse',
+		pathLevels	: 1,
+		delay		: 800,
+		animation	: {opacity:'show'},
+		speed		: 'normal',
+		autoArrows	: true,
+		dropShadows : true,
+		disableHI	: false,		// true disables hoverIntent detection
+		onInit		: function(){}, // callback functions
+		onBeforeShow: function(){},
+		onShow		: function(){},
+		onHide		: function(){}
+	};
+	$.fn.extend({
+		hideSuperfishUl : function(){
+			var o = sf.op,
+				not = (o.retainPath===true) ? o.$path : '';
+			o.retainPath = false;
+			var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
+					.find('>ul').hide().css('visibility','hidden');
+			o.onHide.call($ul);
+			return this;
+		},
+		showSuperfishUl : function(){
+			var o = sf.op,
+				sh = sf.c.shadowClass+'-off',
+				$ul = this.addClass(o.hoverClass)
+					.find('>ul:hidden').css('visibility','visible');
+			sf.IE7fix.call($ul);
+			o.onBeforeShow.call($ul);
+			$ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
+			return this;
+		}
+	});
+
+})(jQuery);
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/supersubs.js b/ipojo/runtime/core/doc/apache-felix-ipojo_files/supersubs.js
new file mode 100644
index 0000000..4522151
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/supersubs.js
@@ -0,0 +1,90 @@
+
+/*
+ * Supersubs v0.2b - jQuery plugin
+ * Copyright (c) 2008 Joel Birch
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * 	http://www.opensource.org/licenses/mit-license.php
+ * 	http://www.gnu.org/licenses/gpl.html
+ *
+ *
+ * This plugin automatically adjusts submenu widths of suckerfish-style menus to that of
+ * their longest list item children. If you use this, please expect bugs and report them
+ * to the jQuery Google Group with the word 'Superfish' in the subject line.
+ *
+ */
+
+;(function($){ // $ will refer to jQuery within this closure
+
+	$.fn.supersubs = function(options){
+		var opts = $.extend({}, $.fn.supersubs.defaults, options);
+		// return original object to support chaining
+		return this.each(function() {
+			// cache selections
+			var $$ = $(this);
+			// support metadata
+			var o = $.meta ? $.extend({}, opts, $$.data()) : opts;
+			// get the font size of menu.
+			// .css('fontSize') returns various results cross-browser, so measure an em dash instead
+			var fontsize = $('<li id="menu-fontsize">&#8212;</li>').css({
+				'padding' : 0,
+				'position' : 'absolute',
+				'top' : '-999em',
+				'width' : 'auto'
+			}).appendTo($$).width(); //clientWidth is faster, but was incorrect here
+			// remove em dash
+			$('#menu-fontsize').remove();
+			// cache all ul elements
+			$ULs = $$.find('ul');
+			// loop through each ul in menu
+			$ULs.each(function(i) {	
+				// cache this ul
+				var $ul = $ULs.eq(i);
+				// get all (li) children of this ul
+				var $LIs = $ul.children();
+				// get all anchor grand-children
+				var $As = $LIs.children('a');
+				// force content to one line and save current float property
+				var liFloat = $LIs.css('white-space','nowrap').css('float');
+				// remove width restrictions and floats so elements remain vertically stacked
+				var emWidth = $ul.add($LIs).add($As).css({
+					'float' : 'none',
+					'width'	: 'auto'
+				})
+				// this ul will now be shrink-wrapped to longest li due to position:absolute
+				// so save its width as ems. Clientwidth is 2 times faster than .width() - thanks Dan Switzer
+				.end().end()[0].clientWidth / fontsize;
+				// add more width to ensure lines don't turn over at certain sizes in various browsers
+				emWidth += o.extraWidth;
+				// restrict to at least minWidth and at most maxWidth
+				if (emWidth > o.maxWidth)		{ emWidth = o.maxWidth; }
+				else if (emWidth < o.minWidth)	{ emWidth = o.minWidth; }
+				emWidth += 'em';
+				// set ul to width in ems
+				$ul.css('width',emWidth);
+				// restore li floats to avoid IE bugs
+				// set li width to full width of this ul
+				// revert white-space to normal
+				$LIs.css({
+					'float' : liFloat,
+					'width' : '100%',
+					'white-space' : 'normal'
+				})
+				// update offset position of descendant ul to reflect new width of parent
+				.each(function(){
+					var $childUl = $('>ul',this);
+					var offsetDirection = $childUl.css('left')!==undefined ? 'left' : 'right';
+					$childUl.css(offsetDirection,emWidth);
+				});
+			});
+			
+		});
+	};
+	// expose defaults
+	$.fn.supersubs.defaults = {
+		minWidth		: 9,		// requires em unit.
+		maxWidth		: 25,		// requires em unit.
+		extraWidth		: 0			// extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values
+	};
+	
+})(jQuery); // plugin code ends
diff --git a/ipojo/runtime/core/doc/apache-felix-ipojo_files/user_edit.png b/ipojo/runtime/core/doc/apache-felix-ipojo_files/user_edit.png
new file mode 100644
index 0000000..c1974cd
--- /dev/null
+++ b/ipojo/runtime/core/doc/apache-felix-ipojo_files/user_edit.png
Binary files differ
diff --git a/ipojo/runtime/core/doc/changelog.txt b/ipojo/runtime/core/doc/changelog.txt
new file mode 100644
index 0000000..bb0f693
--- /dev/null
+++ b/ipojo/runtime/core/doc/changelog.txt
@@ -0,0 +1,150 @@
+Changes from the 1.6.8 to 1.8.0
+-------------------------------
+** Bug
+    * [FELIX-2694] - Instance state not recomputed after reconfiguration when the instance is stopped
+    * [FELIX-2716] - [iPOJO] Failure when creating proxies for classes in java.* packages
+
+** Improvement
+    * [FELIX-2781] - Expose the implementation class as service when no interfaces are found in the hierarchy
+    * [FELIX-1424] - Constructor Injection
+    * [FELIX-1428] - Constructor injection of Configuration properties
+    * [FELIX-2461] - Allow specifying the targeted service interface in the @ServiceController
+    * [FELIX-2620] - Change iPojo annotation parameters to follow java naming conventions
+    * [FELIX-2621] - Rename annotations to remove collisions
+    * [FELIX-2622] - Support static service properties that are not mirrored into fields
+    * [FELIX-2688] - iPojo "requires.filters" - Array object instead of Dictionary object
+    * [FELIX-2705] - Provide a way to extend the logger strategy
+    * [FELIX-2742] - Constructor injection of service dependencies
+    * [FELIX-2744] - Add annotations to the maven-ipojo-plugin archetype
+
+Changes from the 1.6.6 to 1.6.8
+-------------------------------
+** Improvement
+ * [FELIX-2688] - iPojo "requires.filters" - Array object instead of Dictionary object
+ * [FELIX-2705] - Provide a way to extend the logger strategy
+
+** Bug
+ * [FELIX-2685] - Wrong Element name when XML namespace contains ':'
+ * [FELIX-2694] - Instance state not recomputed after reconfiguration when the instance is stopped
+
+Changes from the 1.6.4 to 1.6.6
+-------------------------------
+** Improvement
+ * [FELIX-2594] - Have a way to create new custom iPojo handler without having to specify a handler usage
+ * [FELIX-2623] - @Update annotated methods should not require a Dictionary parameter
+
+** Bug
+ * [FELIX-2580] - iPOJO failed to create proxies on service which are not interface
+ * [FELIX-2596] - DependencyHandler.onObjectCreation throws NPE when bundle is refreshed
+ * [FELIX-2603] - wrong behavior of InstanceManager.onSet(..) method
+ * [FELIX-2636] - Cannot control the validity of an iPOJO instance using a configuration property
+
+Changes from the 1.6.2 to 1.6.4
+-------------------------------
+** Improvement
+    * [FELIX-2420] - Enum support for @Property annotation
+    * [FELIX-2461] - Allow specifying the targeted service interface in the @ServiceController
+    * [FELIX-2472] - Proxies should throw a runtime exception instead of a null pointer exception
+
+** Bug
+	* [FELIX-2561] - Properties set as required instead of optional in  the component type descriptions
+
+Changes from the 1.6.0 to 1.6.2
+-------------------------------
+** Bug
+    * [FELIX-2308] - getService is called during the unregistration of a service.
+    * [FELIX-2309] - Potential NPE when a service has abruptly in the smart proxies.
+    * [FELIX-2323] - Unbind method should not be called during the invalidation process if the invalidation does not come from a service departure.
+
+** Improvement
+    * [FELIX-2296] - Access to ServiceReference in iPOJO service.
+
+Changes from the 1.4.0 to 1.6.0
+-------------------------------
+** Bug
+    * [FELIX-1533] - Potential deadlock when stopping the underlying OSGi framework
+    * [FELIX-1965] - iPojo component is made available regardless of exception during validate
+    * [FELIX-2014] - Potential ClassCastException when a service property does not receive a value and is used in the constructor
+    * [FELIX-2019] - The Property value is 'null' in the Architecture description, while the value is well assigned to the component's field.
+    * [FELIX-2052] - Handler require callback are not called if the service (required) is registered before the instance of the handler has been started.
+    * [FELIX-2093] - iPOJO doesn't always use the correct class loader
+
+** Improvement
+    * [FELIX-1425] - Service Proxy Mode
+    * [FELIX-1426] - Service injection with Dynamic Proxies
+    * [FELIX-1427] - Service injection with Smart Proxies
+    * [FELIX-1532] - Be able to set the iPOJO Log Level from BND
+    * [FELIX-1741] - Allows the configuration handler description to retrieve the managed service PID
+    * [FELIX-1854] - Allows instances to directly declares service.* properties (pid, ranking, vendor, description)
+    * [FELIX-1885] - Ease CreationStrategy & iPOJOServiceFactory usage
+    * [FELIX-1906] - Allow calling a method when service properties of an already injected service are modified
+
+** New Feature
+    * [FELIX-2132] - Provides a way to control service exposition from the implementation class
+
+
+Changes from 1.2.0 to 1.4.0
+---------------------------
+** Bug
+    * [FELIX-985] - iPOJO analyzes already installed bundle by holding a lock
+    * [FELIX-1002] - iPOJO Static binding policy is not compliant with the Declarative Service static binding policy.
+    * [FELIX-1318] - Case mismatch problem of iPOJO custom handler name
+** Improvement
+    * Update parent pom
+    * [FELIX-936] - Allowing publishing class as services
+    * [FELIX-966] - iPOJO: Better error reporting when getPojoObject return null
+    * [FELIX-982] - Declare iPOJO as a singleton bundle to avoid multiple version of the runtime at the same time
+    * [FELIX-1114] - callback after configuration change needed
+    * [FELIX-1163] - Improve error message when an array cannot be created due to a classloading issue
+    * [FELIX-1182] - iPOJO - reconfiguration : get all properties with the update callback
+
+
+Changes from 1.0.0 to 1.2.0
+---------------------------
+** Bug
+    * [FELIX-797] - Composite Architecture contains duplicate instances
+    * [FELIX-803] - iPOJO Core schema needs to be fixed
+    * [FELIX-805] - Instance not created if the factory becomes valid later
+    * [FELIX-866] - iPOJO Provides 'interface' attribute should be 'specifications'
+
+** Improvement
+    * [FELIX-787] - iPOJO logger log messages inside the log service and print them
+    * [FELIX-796] - Allows enabling/disabling the internal event dispatcher
+    * [FELIX-801] - Support service properties injection in bind/unbind callbacks
+    * [FELIX-815] - Support optional properties
+    * [FELIX-816] - Support comparator attribute with any service binding policy
+    * [FELIX-818] - Implement the ServiceReference compareTo method
+    * [FELIX-853] - Provide new service object creation strategies
+    * New introspection API
+
+Changes from 0.8.0 to 1.0.0
+---------------------------
+** Bug
+    * [FELIX-557] - Factories still living when a primitive component does not have its manipulation metadata
+    * [FELIX-632] - Component are set to immediate despite they are already immediate
+    * [FELIX-635] - Simplify factory name computation
+    * [FELIX-628] - Architecture service should not publish the instance.name property
+    * [FELIX-621] - Instances not disposed when instances creation failed
+
+** Improvement
+    * [FELIX-552] - ClassCastException when using services as dynamic proxies
+    * [FELIX-555] - Error message in the iPOJO Extender could be more accurate when failing to get the bundle context
+    * [FELIX-558] - Non caught NoClassDefFoundError when the instantiation of a Nullable object failed
+    * [FELIX-603] - Improve iPOJO Arch service dependency description
+    * [FELIX-626] - Allow specifying instance configuration containing empty dictionaries
+    * [FELIX-629] - Allows instance configuration to declares complex properties
+    * [FELIX-631] - Immediate Component Detection
+    * [FELIX-633] - Factory creation should be done in another thread
+    * [FELIX-634] - Improve error handling
+    * [FELIX-655] - Add a 'from' attribute in the service dependencies
+    * [FELIX-673] - Provide OBR description to iPOJO bundles
+    * [FELIX-683] - Supporting lists and vectors in the service dependency management
+    * [FELIX-686] - Supporting collections and set in the service dependency management
+    * [FELIX-688] - Better error reporting when an instance creation failed
+    * [FELIX-689] - Instance 'name' property should become 'instance.name'
+    * [FELIX-716] - Provide XML schemas for iPOJO descriptors
+    * [FELIX-732] - Duplicate instance created of a managed service
+
+Version 0.8.0
+-------------
+    * Initial release
diff --git a/ipojo/runtime/core/obr.xml b/ipojo/runtime/core/obr.xml
new file mode 100644
index 0000000..00a9cea
--- /dev/null
+++ b/ipojo/runtime/core/obr.xml
@@ -0,0 +1,44 @@
+<!--
+	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.
+-->
+<obr>
+	<capability name="ipojo.handler">
+		<p n="name" v="controller"/>
+		<p n="namespace" v="org.apache.felix.ipojo"/>
+	</capability>
+	<capability name="ipojo.handler">
+		<p n="name" v="callback"/>
+		<p n="namespace" v="org.apache.felix.ipojo"/>
+	</capability>
+	<capability name="ipojo.handler">
+		<p n="name" v="requires"/>
+		<p n="namespace" v="org.apache.felix.ipojo"/>
+	</capability>
+	<capability name="ipojo.handler">
+		<p n="name" v="provides"/>
+		<p n="namespace" v="org.apache.felix.ipojo"/>
+	</capability>
+	<capability name="ipojo.handler">
+		<p n="name" v="properties"/>
+		<p n="namespace" v="org.apache.felix.ipojo"/>
+	</capability>
+		<capability name="ipojo.handler">
+		<p n="name" v="architecture"/>
+		<p n="namespace" v="org.apache.felix.ipojo"/>
+	</capability>
+</obr>
\ No newline at end of file
diff --git a/ipojo/runtime/core/pom.xml b/ipojo/runtime/core/pom.xml
new file mode 100644
index 0000000..0169f41
--- /dev/null
+++ b/ipojo/runtime/core/pom.xml
@@ -0,0 +1,228 @@
+<!--
+  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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix-parent</artifactId>
+    <version>1.2.1</version>
+    <relativePath>../../../pom/pom.xml</relativePath>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>bundle</packaging>
+  <name>Apache Felix iPOJO</name>
+  <artifactId>org.apache.felix.ipojo</artifactId>
+  <version>1.9.0-SNAPSHOT</version>
+
+  <properties>
+    <!--
+        1.8.1:
+        * change in the MethodInterceptor interface (FELIX-3144)
+        * change in the Factory interface (FELIX-3190)
+     -->
+    <ipojo.package.version>1.8.1</ipojo.package.version>
+
+    <!-- Embedded manipulator version -->
+    <ipojo.manipulator.version>1.8.0</ipojo.manipulator.version>
+  </properties>
+
+  <description>
+  iPOJO Core bundle
+  </description>
+  <url>
+  http://ipojo.org
+  </url>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>4.3.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>4.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.ipojo.metadata</artifactId>
+      <version>1.5.0-SNAPSHOT</version>
+    </dependency>
+     <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.ipojo.manipulator</artifactId>
+      <version>${ipojo.manipulator.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm-all</artifactId>
+      <version>3.3.1</version>
+      <exclusions>
+        <exclusion>
+          <groupId>asm</groupId>
+          <artifactId>asm-tree</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <target>jsr14</target>
+          <source>1.5</source>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <version>1.4.3</version>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Name>Apache Felix iPOJO</Bundle-Name>
+            <Bundle-Vendor> The Apache Software Foundation </Bundle-Vendor>
+            <Bundle-SymbolicName>org.apache.felix.ipojo;singleton:=true</Bundle-SymbolicName>
+            <Bundle-Description> iPOJO Core Framework </Bundle-Description>
+            <Bundle-Activator> org.apache.felix.ipojo.Extender
+            </Bundle-Activator>
+            <Bundle-DocURL>
+              http://felix.apache.org/site/apache-felix-ipojo.html
+            </Bundle-DocURL>
+            <IPOJO-Extension>
+              component:org.apache.felix.ipojo.ComponentFactory,
+              handler:org.apache.felix.ipojo.HandlerManagerFactory
+            </IPOJO-Extension>
+            <Import-Package>
+              org.osgi.framework;version=1.3, <!-- To support KF 2 -->
+              org.osgi.service.cm,
+              org.osgi.service.log,
+              !org.objectweb.asm.tree,
+              !sun.io,
+              !net.sourceforge.cobertura.*, <!--  To support code coverage -->
+
+              <!--
+                Packages used for the online-manipulator.
+                They are optionals
+              -->
+              javax.xml.parsers;resolution:=optional,
+              org.osgi.service.url;resolution:=optional,
+              org.w3c.dom;resolution:=optional,
+              org.xml.sax;resolution:=optional,
+              org.xml.sax.helpers;resolution:=optional
+            </Import-Package>
+            <Private-Package>
+              org.apache.felix.ipojo.handlers.architecture,
+              org.apache.felix.ipojo.handlers.lifecycle.callback,
+              org.apache.felix.ipojo.handlers.lifecycle.controller,
+              <!-- ASM (Manipulator dependencies) -->
+              org.objectweb.asm.commons,
+              org.objectweb.asm.signature,
+              org.objectweb.asm
+            </Private-Package>
+            <Export-Package>
+              org.apache.felix.ipojo; version="${ipojo.package.version}",
+              org.apache.felix.ipojo.metadata; version="${ipojo.package.version}",
+              org.apache.felix.ipojo.architecture; version="${ipojo.package.version}",
+              org.apache.felix.ipojo.parser; version="${ipojo.package.version}",
+              org.apache.felix.ipojo.util; version="${ipojo.package.version}",
+              org.apache.felix.ipojo.handlers.dependency; version="${ipojo.package.version}",
+              org.apache.felix.ipojo.handlers.providedservice.*; version="${ipojo.package.version}",
+              org.apache.felix.ipojo.handlers.configuration; version="${ipojo.package.version}",
+              org.apache.felix.ipojo.context; version="${ipojo.package.version}",
+              <!-- Embedded manipulator -->
+              org.apache.felix.ipojo.manipulator; version="${ipojo.manipulator.version}",
+              org.apache.felix.ipojo.xml.parser; version="${ipojo.manipulator.version}",
+              org.apache.felix.ipojo.*; version="${ipojo.manipulator.version}",
+              <!-- Compendium packages -->
+              org.osgi.service.cm,
+              org.osgi.service.log,
+            </Export-Package>
+            <Include-Resource>
+              META-INF/LICENSE=LICENSE,
+              META-INF/NOTICE=NOTICE, META-INF/LICENSE.asm=LICENSE.asm,
+              META-INF/DEPENDENCIES=DEPENDENCIES
+            </Include-Resource>
+            <_donotcopy> (CVS|.svn|.+.bak|~.+|metadata.xml) </_donotcopy>
+          </instructions>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-ipojo-plugin</artifactId>
+        <version>1.8.0</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>ipojo-bundle</goal>
+            </goals>
+            <configuration>
+              <ignoreAnnotations>true</ignoreAnnotations>
+            </configuration>
+          </execution>
+        </executions>
+      </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>
+            <param>DEPENDENCIES</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>
+
+    <resources>
+    <resource>
+      <directory>src/main/resources</directory>
+    </resource>
+    <resource>
+      <directory>.</directory>
+      <targetPath>META-INF</targetPath>
+      <includes>
+        <include>LICENSE*</include>
+        <include>NOTICE*</include>
+        <include>DEPENDENCIES*</include>
+      </includes>
+    </resource>
+  </resources>
+
+  </build>
+</project>
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
new file mode 100644
index 0000000..fdfc223
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentFactory.java
@@ -0,0 +1,723 @@
+/*
+ * 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;
+
+import java.net.URL;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ParseUtils;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Tracker;
+import org.apache.felix.ipojo.util.TrackerCustomizer;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The component factory manages component instance objects. This management
+ * consists to create and manage component instances build with the current
+ * component factory. This class could export Factory and ManagedServiceFactory
+ * services.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ * @see IPojoFactory
+ * @see TrackerCustomizer
+ */
+public class ComponentFactory extends IPojoFactory implements TrackerCustomizer {
+
+    /**
+     * System property set to automatically attach primitive handlers to primitive
+     * component types.
+     * The value is a String parsed as a list (comma separated). Each element is
+     * the fully qualified name of the handler <code>namespace:name</code>.
+     */
+    public static final String HANDLER_AUTO_PRIMITIVE = "org.apache.felix.ipojo.handler.auto.primitive";
+
+
+    /**
+     * The tracker used to track required handler factories.
+     * Immutable once set.
+     */
+    protected Tracker m_tracker;
+
+    /**
+     * The class loader to delegate classloading.
+     * Immutable once set.
+     */
+    private FactoryClassloader m_classLoader;
+
+    /**
+     * The component implementation class.
+     * (manipulated byte array)
+     */
+    private byte[] m_clazz;
+
+    /**
+     * The component implementation qualified class name.
+     * Immutable once set.
+     * This attribute is set during the creation of the factory.
+     */
+    private String m_classname;
+
+    /**
+     * The manipulation metadata of the implementation class.
+     * Immutable once set.
+     * This attribute is set during the creation of the factory.
+     */
+    private PojoMetadata m_manipulation;
+
+    /**
+     * Creates a instance manager factory.
+     * The class is given in parameter. The component type is not a composite.
+     *
+     * @param context the bundle context
+     * @param clazz   the component class
+     * @param element the metadata of the component
+     * @throws ConfigurationException if the element describing the factory is malformed.
+     */
+    public ComponentFactory(BundleContext context, byte[] clazz, Element element) throws ConfigurationException {
+        this(context, element);
+        m_clazz = clazz;
+    }
+
+    /**
+     * Creates a instance manager factory.
+     *
+     * @param context the bundle context
+     * @param element the metadata of the component to create
+     * @throws ConfigurationException if element describing the factory is malformed.
+     */
+    public ComponentFactory(BundleContext context, Element element) throws ConfigurationException {
+        super(context, element);
+        check(element); // NOPMD. This invocation is normal.
+    }
+
+    /**
+     * Gets the component type description of the current factory.
+     *
+     * @return the description of the component type attached to this factory.
+     * @see org.apache.felix.ipojo.IPojoFactory#getComponentTypeDescription()
+     */
+    public ComponentTypeDescription getComponentTypeDescription() {
+        return new PrimitiveTypeDescription(this);
+    }
+
+    /**
+     * Allows a factory to check if the given element is well-formed.
+     * A component factory metadata is correct if they contain the 'classname' attribute.
+     * As this method is called from the (single-threaded) constructor, no synchronization is needed.
+     *
+     * @param element the metadata describing the component
+     * @throws ConfigurationException if the element describing the factory is malformed.
+     */
+    public void check(Element element) throws ConfigurationException {
+        m_classname = element.getAttribute("classname");
+        if (m_classname == null) {
+            throw new ConfigurationException("A component needs a class name : " + element);
+        }
+        m_manipulation = new PojoMetadata(m_componentMetadata);
+    }
+
+    /**
+     * Gets the class name.
+     * No synchronization needed, the classname is immutable.
+     *
+     * @return the class name.
+     * @see org.apache.felix.ipojo.IPojoFactory#getClassName()
+     */
+    public String getClassName() {
+        return m_classname;
+    }
+
+    /**
+     * Creates a primitive instance.
+     * This method is called when holding the lock.
+     *
+     * @param config   the instance configuration
+     * @param context  the service context (null if the instance has to be created in the global space).
+     * @param handlers the handlers to attach to the instance
+     * @return the created instance
+     * @throws org.apache.felix.ipojo.ConfigurationException
+     *          if the configuration process failed.
+     * @see org.apache.felix.ipojo.IPojoFactory#createInstance(java.util.Dictionary, org.apache.felix.ipojo.IPojoContext, org.apache.felix.ipojo.HandlerManager[])
+     */
+    public ComponentInstance createInstance(Dictionary config, IPojoContext context, HandlerManager[] handlers) throws org.apache.felix.ipojo.ConfigurationException {
+        InstanceManager instance = new InstanceManager(this, context, handlers);
+
+        try {
+            instance.configure(m_componentMetadata, config);
+            instance.start();
+            return instance;
+        } catch (ConfigurationException e) {
+            // An exception occurs while executing the configure or start
+            // methods.
+            if (instance != null) {
+                instance.dispose();
+                instance = null;
+            }
+            throw e;
+        } catch (Throwable e) { // All others exception are handled here.
+            if (instance != null) {
+                instance.dispose();
+                instance = null;
+            }
+            m_logger.log(Logger.ERROR, e.getMessage(), e);
+            throw new ConfigurationException(e.getMessage());
+        }
+
+    }
+
+    /**
+     * Defines a class.
+     * This method needs to be synchronized to avoid that the classloader
+     * is created twice.
+     * This method delegate the <code>define</code> method invocation to the
+     * factory classloader.
+     *
+     * @param name   the qualified name of the class
+     * @param clazz  the byte array of the class
+     * @param domain the protection domain of the class
+     * @return the defined class object
+     */
+    public synchronized Class defineClass(String name, byte[] clazz, ProtectionDomain domain) {
+        if (m_classLoader == null) {
+            m_classLoader = new FactoryClassloader();
+        }
+        return m_classLoader.defineClass(name, clazz, domain);
+    }
+
+    /**
+     * Returns the URL of a resource.
+     * This methods delegates the invocation to the
+     * {@link Bundle#getResource(String)} method.
+     *
+     * @param resName the resource name
+     * @return the URL of the resource
+     */
+    public URL getResource(String resName) {
+        //No synchronization needed, the context is immutable and
+        //the call is managed by the underlying framework.
+        return m_context.getBundle().getResource(resName);
+    }
+
+    /**
+     * Loads a class. This method checks if the class
+     * to load is the implementation class or not.
+     * If it is, the factory classloader is used, else
+     * the {@link Bundle#loadClass(String)} is called.
+     *
+     * @param className the name of the class to load
+     * @return the resulting Class object
+     * @throws ClassNotFoundException if the class is not found
+     */
+    public Class loadClass(String className) throws ClassNotFoundException {
+        if (m_clazz != null && m_classname.equals(className)) {  // Immutable fields.
+            return defineClass(className, m_clazz, null);
+        }
+        return m_context.getBundle().loadClass(className);
+    }
+
+    /**
+     * Starts the factory.
+     * This method is called when holding the monitor lock.
+     */
+    public void starting() {
+        if (m_tracker != null) {
+            return; // Already started
+        } else {
+            if (m_requiredHandlers.size() != 0) {
+                try {
+                    String filter = "(&(" + Handler.HANDLER_TYPE_PROPERTY + "=" + PrimitiveHandler.HANDLER_TYPE + ")" + "(factory.state=1)" + ")";
+                    m_tracker = new Tracker(m_context, m_context.createFilter(filter), this);
+                    m_tracker.open();
+                } catch (InvalidSyntaxException e) {
+                    m_logger.log(Logger.ERROR, "A factory filter is not valid: " + e.getMessage()); //Holding the lock should not be an issue here.
+                    stop();
+                }
+            }
+        }
+    }
+
+    /**
+     * Stops all the instance managers.
+     * This method is called when holding the lock.
+     */
+    public void stopping() {
+        if (m_tracker != null) {
+            m_tracker.close();
+            m_tracker = null;
+        }
+    }
+
+    /**
+     * Computes the factory name. The factory name is computed from
+     * the 'name' and 'classname' attributes.
+     * This method does not manipulate any non-immutable fields,
+     * so does not need to be synchronized.
+     *
+     * @return the factory name.
+     */
+    public String getFactoryName() {
+        String name = m_componentMetadata.getAttribute("name");
+        if (name == null) {
+            // No factory name, use the classname (mandatory attribute)
+            name = m_componentMetadata.getAttribute("classname");
+        }
+        return name;
+    }
+
+    /**
+     * Computes required handlers.
+     * This method does not manipulate any non-immutable fields,
+     * so does not need to be synchronized.
+     * This method checks the {@link ComponentFactory#HANDLER_AUTO_PRIMITIVE}
+     * system property to add the listed handlers to the required handler set.
+     *
+     * @return the required handler list.
+     */
+    public List getRequiredHandlerList() {
+        List list = new ArrayList();
+        Element[] elems = m_componentMetadata.getElements();
+        for (int i = 0; i < elems.length; i++) {
+            Element current = elems[i];
+            if (!"manipulation".equals(current.getName())) { // Remove the manipulation element
+                RequiredHandler req = new RequiredHandler(current.getName(), current.getNameSpace());
+                if (!list.contains(req)) {
+                    list.add(req);
+                }
+            }
+        }
+
+        // Add architecture if architecture != 'false'
+        String arch = m_componentMetadata.getAttribute("architecture");
+        if (arch == null || arch.equalsIgnoreCase("true")) {
+            list.add(new RequiredHandler("architecture", null));
+        }
+
+
+        // Determine if the component must be immediate.
+        // A component becomes immediate if it doesn't provide a service,
+        // and does not specified that the component is not immediate.
+        if (m_componentMetadata.getElements("provides") == null) {
+            String imm = m_componentMetadata.getAttribute("immediate");
+            if (imm == null) { // immediate not specified, set the immediate attribute to true
+                getLogger().log(
+                        Logger.INFO,
+                        "The component type " + getFactoryName()
+                                + " becomes immediate");
+                m_componentMetadata.addAttribute(new Attribute("immediate",
+                        "true"));
+            }
+        }
+
+        // Add lifecycle callback if immediate = true
+        RequiredHandler reqCallback = new RequiredHandler("callback", null);
+        String imm = m_componentMetadata.getAttribute("immediate");
+        if (!list.contains(reqCallback) && imm != null && imm.equalsIgnoreCase("true")) {
+            list.add(reqCallback);
+        }
+
+        // Manage auto attached handler.
+        String v = System.getProperty(HANDLER_AUTO_PRIMITIVE);
+        if (v != null && v.length() != 0) {
+            String[] hs = ParseUtils.split(v, ",");
+            for (int i = 0; i < hs.length; i++) {
+                String h = hs[i].trim();
+                String[] segments = ParseUtils.split(h, ":");
+                RequiredHandler rq = null;
+                if (segments.length == 2) { // External handler
+                    rq = new RequiredHandler(segments[1], segments[0]);
+                } else if (segments.length == 1) { // Core handler
+                    rq = new RequiredHandler(segments[1], null);
+                } // Others case are ignored.
+
+                if (rq != null) {
+                    // Check it's not already contained
+                    if (!list.contains(rq)) {
+                        list.add(rq);
+                    }
+                }
+            }
+        }
+
+
+        return list;
+    }
+
+    /**
+     * This method is called when a new handler factory is detected.
+     * Test if the factory can be used or not.
+     * This method need to be synchronized as it accesses to the content
+     * of required handlers.
+     *
+     * @param reference the new service reference.
+     * @return <code>true</code> if the given factory reference matches with a required handler.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public synchronized boolean addingService(ServiceReference reference) {
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            if (req.getReference() == null && match(req, reference)) {
+                int oldP = req.getLevel();
+                req.setReference(reference);
+                // If the priority has changed, sort the list.
+                if (oldP != req.getLevel()) {
+                    // Manipulate the list.
+                    Collections.sort(m_requiredHandlers);
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * This method is called when a matching service has been added to the tracker,
+     * we can no compute the factory state. This method is synchronized to avoid
+     * concurrent calls to method modifying the factory state.
+     *
+     * @param reference the added service reference.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public synchronized void addedService(ServiceReference reference) {
+        if (m_state == INVALID) {
+            computeFactoryState();
+        }
+    }
+
+    /**
+     * This method is called when a used handler factory disappears.
+     * This method is synchronized to avoid concurrent calls to method modifying
+     * the factory state.
+     *
+     * @param reference the leaving service reference.
+     * @param service   the handler factory object.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public synchronized void removedService(ServiceReference reference, Object service) {
+        // Look for the implied reference and invalid the handler identifier
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            if (reference.equals(req.getReference())) {
+                req.unRef(); // This method will unget the service.
+                computeFactoryState();
+                return; // The factory can be used only once.
+            }
+        }
+    }
+
+    /**
+     * This method is called when a used handler factory is modified.
+     * However, handler factory modification is not possible, so this method
+     * is never called.
+     *
+     * @param reference the service reference
+     * @param service   the Factory object (if already get)
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference reference, Object service) {
+        // Noting to do
+    }
+
+    /**
+     * Returns manipulation metadata of this component type.
+     *
+     * @return manipulation metadata of this component type.
+     */
+    public PojoMetadata getPojoMetadata() {
+        return m_manipulation;
+    }
+
+    /**
+     * Gets the version of the component type.
+     *
+     * @return the version of <code>null</code> if not set.
+     * @see org.apache.felix.ipojo.Factory#getVersion()
+     */
+    public String getVersion() {
+        return m_version;
+    }
+
+    public ClassLoader getBundleClassLoader() {
+        return m_classLoader;
+    }
+
+    /**
+     * this class defines the classloader attached to a factory.
+     * This class loader is used to load the implementation (e.g. manipulated)
+     * class.
+     *
+     * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+     * @see ClassLoader
+     */
+    private class FactoryClassloader extends ClassLoader {
+
+        /**
+         * The map of defined classes [Name, Class Object].
+         */
+        private final Map m_definedClasses = new HashMap();
+
+        /**
+         * The defineClass method.
+         *
+         * @param name   name of the class
+         * @param clazz  the byte array of the class
+         * @param domain the protection domain
+         * @return the defined class.
+         */
+        public Class defineClass(String name, byte[] clazz, ProtectionDomain domain) {
+            if (m_definedClasses.containsKey(name)) {
+                return (Class) m_definedClasses.get(name);
+            }
+            Class clas = super.defineClass(name, clazz, 0, clazz.length, domain);
+            m_definedClasses.put(name, clas);
+            return clas;
+        }
+
+        /**
+         * Returns the URL of the required resource.
+         *
+         * @param arg the name of the resource to find.
+         * @return the URL of the resource.
+         * @see java.lang.ClassLoader#getResource(java.lang.String)
+         */
+        public URL getResource(String arg) {
+            return m_context.getBundle().getResource(arg);
+        }
+
+        /**
+         * Loads the given class.
+         *
+         * @param name    the name of the class
+         * @param resolve should be the class resolve now ?
+         * @return the loaded class object
+         * @throws ClassNotFoundException if the class to load is not found
+         * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+         * @see java.lang.ClassLoader#loadClass(String, boolean)
+         */
+        protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+            return m_context.getBundle().loadClass(name);
+        }
+    }
+
+    /**
+     * This class defines the description of primitive (non-composite) component
+     * types. An instance of this class will be returned when invoking the
+     * {@link ComponentFactory#getComponentDescription()} method.
+     *
+     * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+     */
+    private final class PrimitiveTypeDescription extends ComponentTypeDescription {
+
+        /*
+           * Set to keep component's all super-class class-names.
+           */
+        private Set m_superClasses = new HashSet();
+
+        /*
+           * Set to keep component's all interface class-names.
+           */
+        private Set m_interfaces = new HashSet();
+
+        /**
+         * Creates a PrimitiveTypeDescription object.
+         *
+         * @param factory the factory attached to this component type description.
+         */
+        public PrimitiveTypeDescription(IPojoFactory factory) {
+            super(factory);
+
+            try {
+                // The inspection can be done only for primitive components
+                if (m_classname != null) {
+                    // Read inherited classes and interfaces into given Sets.
+                    new InheritanceInspector(getPojoMetadata(), getBundleContext().getBundle()).
+                            computeInterfacesAndSuperClasses(m_interfaces, m_superClasses);
+                }
+            } catch (ClassNotFoundException e) {
+                m_interfaces.clear();
+                m_superClasses.clear();
+            }
+
+        }
+
+        /**
+         * Computes the properties to publish.
+         * The <code>component.class</code> property contains the implementation class name.
+         *
+         * @return the dictionary of properties to publish
+         * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getPropertiesToPublish()
+         */
+        public Dictionary getPropertiesToPublish() {
+            Dictionary dict = super.getPropertiesToPublish();
+            if (m_classname != null) {
+                dict.put("component.class", m_classname);
+            }
+            return dict;
+        }
+
+        /**
+         * Adds the "implementation-class" attribute to the type description.
+         *
+         * @return the component type description.
+         * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getDescription()
+         */
+        public Element getDescription() {
+            Element elem = super.getDescription();
+            elem.addAttribute(new Attribute("Implementation-Class", m_classname));
+
+            /* Adding interfaces and super-classes of component into description */
+            Element inheritance = new Element("Inherited", "");
+
+            inheritance.addAttribute(new Attribute("Interfaces", m_interfaces.toString()));
+            inheritance.addAttribute(new Attribute("SuperClasses", m_superClasses.toString()));
+
+            elem.addElement(inheritance);
+
+            return elem;
+        }
+
+        /**
+         * This class is used to collect interfaces and super-classes of given component in specified Sets.
+         *
+         * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+         */
+        private final class InheritanceInspector {
+            /*
+                * PojoMetadata of target Component.
+                */
+            private PojoMetadata m_pojoMetadata;
+
+            /*
+                * Bundle exposing target component.
+                */
+            private Bundle m_bundle;
+
+
+            /**
+             * Creates a TypeCollector object
+             *
+             * @param pojoMetadata PojoMetadata describing Component.
+             * @param bundle       Bundle which has been exposed the intended Component.
+             */
+            public InheritanceInspector(PojoMetadata pojoMetadata, Bundle bundle) {
+                m_pojoMetadata = pojoMetadata;
+                m_bundle = bundle;
+            }
+
+            /**
+             * Collect interfaces implemented by the POJO into given Sets.
+             *
+             * @param interfaces : the set of implemented interfaces
+             * @param classes    : the set of extended classes
+             * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
+             */
+            public void computeInterfacesAndSuperClasses(Set interfaces, Set classes) throws ClassNotFoundException {
+                String[] immediateInterfaces = m_pojoMetadata.getInterfaces();
+                String parentClass = m_pojoMetadata.getSuperClass();
+
+                // First iterate on found specification in manipulation metadata
+                for (int i = 0; i < immediateInterfaces.length; i++) {
+                    interfaces.add(immediateInterfaces[i]);
+                    // Iterate on interfaces implemented by the current interface
+                    Class clazz = m_bundle.loadClass(immediateInterfaces[i]);
+                    collectInterfaces(clazz, interfaces, m_bundle);
+                }
+
+                // Look for parent class.
+                if (parentClass != null) {
+                    Class clazz = m_bundle.loadClass(parentClass);
+                    collectInterfacesFromClass(clazz, interfaces, m_bundle);
+                    classes.add(parentClass);
+                    collectParentClassesFromClass(clazz, classes, m_bundle);
+                }
+
+                // Removing Object Class from the inherited classes list.
+                classes.remove(Object.class.getName());
+            }
+
+            /**
+             * Look for inherited interfaces.
+             *
+             * @param clazz  : interface name to explore (class object)
+             * @param acc    : set (accumulator)
+             * @param bundle : bundle
+             * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
+             */
+            private void collectInterfaces(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+                Class[] clazzes = clazz.getInterfaces();
+                for (int i = 0; i < clazzes.length; i++) {
+                    acc.add(clazzes[i].getName());
+                    collectInterfaces(clazzes[i], acc, bundle);
+                }
+            }
+
+            /**
+             * Collect interfaces for the given class.
+             * This method explores super class to.
+             *
+             * @param clazz  : class object.
+             * @param acc    : set of implemented interface (accumulator)
+             * @param bundle : bundle.
+             * @throws ClassNotFoundException : occurs if an interface cannot be load.
+             */
+            private void collectInterfacesFromClass(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+                Class[] clazzes = clazz.getInterfaces();
+                for (int i = 0; i < clazzes.length; i++) {
+                    acc.add(clazzes[i].getName());
+                    collectInterfaces(clazzes[i], acc, bundle);
+                }
+                // Iterate on parent classes
+                Class sup = clazz.getSuperclass();
+                if (sup != null) {
+                    collectInterfacesFromClass(sup, acc, bundle);
+                }
+            }
+
+            /**
+             * Collect parent classes for the given class.
+             *
+             * @param clazz  : class object.
+             * @param acc    : set of extended classes (accumulator)
+             * @param bundle : bundle.
+             * @throws ClassNotFoundException : occurs if an interface cannot be load.
+             */
+            private void collectParentClassesFromClass(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+                Class parent = clazz.getSuperclass();
+                if (parent != null) {
+                    acc.add(parent.getName());
+                    collectParentClassesFromClass(parent, acc, bundle);
+                }
+            }
+        }
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
new file mode 100644
index 0000000..4f2ca74
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ComponentInstance.java
@@ -0,0 +1,128 @@
+/* 
+ * 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;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This class defines the iPOJO's component instance concept.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ComponentInstance {
+
+    /**
+     * Component Instance State : DISPOSED. The component instance was disposed.
+     */
+    int DISPOSED = -1;
+    
+    /**
+     * Component Instance State : STOPPED. The component instance is not
+     * started.
+     */
+    int STOPPED = 0;
+
+    /**
+     * Component Instance State : INVALID. The component instance is invalid when it
+     * starts or when a component dependency is invalid.
+     */
+    int INVALID = 1;
+
+    /**
+     * Component Instance State : VALID. The component instance is resolved when it is
+     * running and all its attached handlers are valid.
+     */
+    int VALID = 2;
+
+    /**
+     * Starts the component instance.
+     */
+    void start();
+
+    /**
+     * Stops the component instance.
+     * A stopped instance can be re-started.
+     */
+    void stop();
+    
+    /**
+     * Disposes the component instance.
+     * A disposed instance cannot be re-started.
+     */
+    void dispose();
+
+    /**
+     * Returns the actual state of the instance. 
+     * @return the actual state of the component instance.
+     */
+    int getState();
+
+    /**
+     * Returns the instance description.
+     * @return the instance description of the current instance
+     */
+    InstanceDescription getInstanceDescription();
+
+    /**
+     * Returns the factory who created this instance.
+     * @return the factory of the component instance.
+     */
+    ComponentFactory getFactory();
+
+    /**
+     * Returns the bundle context of this instance.
+     * @return the context of the component instance
+     */
+    BundleContext getContext();
+
+    /**
+     * Returns the name of the instance.
+     * @return the name of the component instance
+     */
+    String getInstanceName();
+
+    /**
+     * Checks if the instance is started.
+     * @return <code>true</code> if {@link ComponentInstance#getState()} 
+     * returns {@link ComponentInstance#INVALID} or {@link ComponentInstance#VALID}.
+     */
+    boolean isStarted();
+
+    /**
+     * Re-configures an instance. Do nothing if the instance does not support
+     * dynamic reconfiguration. The reconfiguration does not stop the instance.
+     * @param configuration the new configuration.
+     */
+    void reconfigure(Dictionary configuration);
+    
+    /**
+     * Adds an instance state listener on the current instance.
+     * @param listener the listener to add.
+     */
+    void addInstanceStateListener(InstanceStateListener listener);
+    
+    /**
+     * Removes an instance state listener on the current instance.
+     * @param listener the listener to remove.
+     */
+    void removeInstanceStateListener(InstanceStateListener listener);
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
new file mode 100644
index 0000000..0bed6f4
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConfigurationException.java
@@ -0,0 +1,73 @@
+/* 
+ * 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;
+
+/**
+ * This class defines the exception thrown when an instance cannot be configured correctly.
+ * This exception occurs when component metadata are not correct.
+ * @see Exception
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ConfigurationException extends Exception {
+    
+    /**
+     * Serialization Id.
+     */
+    private static final long serialVersionUID = 1L;
+    
+    /**
+     * The component type on which the error occurs.
+     * Uses the factory name.
+     */
+    private String m_type;
+    
+    /**
+     * Creates a new configuration exception.
+     * @param mes the error message
+     * @param typ the component type
+     * @see Exception#Exception(String)
+     */
+    ConfigurationException(String mes, String typ) {
+        super(mes);
+        m_type = typ;
+    }
+    
+    /**
+     * Creates a new configuration exception.
+     * @param mes the error message
+     * @see Exception#Exception(String)
+     */
+    public ConfigurationException(String mes) {
+        super(mes);
+    }
+    
+    /**
+     * Gets the error message.
+     * @return the error message.
+     * @see java.lang.Throwable#getMessage()
+     */
+    public String getMessage() {
+        if (m_type == null) {
+            return super.getMessage();
+        } else {
+            return "The configuration is not correct for the type " + m_type + " : " + super.getMessage();
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConstructorInjector.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConstructorInjector.java
new file mode 100644
index 0000000..dffd3bc
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ConstructorInjector.java
@@ -0,0 +1,53 @@
+/*
+ * 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;
+
+/**
+ * Interface implemented to support constructor parameter injection.
+ * When a new POJO object has to be created, all constructor injectors are
+ * called to gets the objects to injects as well as the type (to discover
+ * the constructor).
+ * Handlers willing to inject constructor parameters must register themselves
+ * using {@link InstanceManager#register(int, ConstructorInjector)} where
+ * the integer is the parameter index. Only one injector can inject a value
+ * for a specific index. If several injectors are registered for the same index,
+ * the component type is declared as invalid.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ConstructorInjector {
+
+   /**
+    * Gets the type of the object to inject in the constructor parameter.
+    * This is the type looked into the Pojo class, so it must match.
+    * Returning <code>null</code> will try to get the class from the
+    * injected object, however this can be wrong (implementation instead of interface,
+    * boxed objects...) and error-prone.
+    * @param index the parameter index
+    * @return the Class object (must fit for primitive type)
+    */
+	Object getConstructorParameter(int index);
+
+	/**
+	 * Gets the type of the object to
+	 * @param index
+	 * @return
+	 */
+	Class getConstructorParameterType(int index);
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ContextListener.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ContextListener.java
new file mode 100644
index 0000000..a2d0fa0
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ContextListener.java
@@ -0,0 +1,38 @@
+/* 
+ * 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;
+
+
+/**
+ * Context Source Listener interface.
+ * A context source listener is notified when a monitored context 
+ * property value changed.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ContextListener {
+    
+    /**
+     * A monitored value has been modified.
+     * @param source the context source containing the property
+     * @param property the modified property name
+     * @param value the new value of the property
+     */
+    void update(ContextSource source, String property, Object value);
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ContextSource.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ContextSource.java
new file mode 100644
index 0000000..de9a8eb
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ContextSource.java
@@ -0,0 +1,58 @@
+/* 
+ * 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;
+
+import java.util.Dictionary;
+
+
+/**
+ * Context Source service interface.
+ * A context source advertises of context changes.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ContextSource {
+    
+    /**
+     * Gets the current value of the given property.
+     * @param property property name
+     * @return the property value (<code>null</code> if unknown)
+     */
+    Object getProperty(String property);
+    
+    /**
+     * Gets the entire context.
+     * @return the dictionary [Property, Value]
+     */
+    Dictionary getContext();
+    
+    /**
+     * Registers a context listener on the given set of properties.
+     * The listener will be notified of every changes made on monitored properties.
+     * @param listener the context listener to register.
+     * @param properties property set monitored by the listener.
+     */
+    void registerContextListener(ContextListener listener, String[] properties);
+    
+    /**
+     * Unregisters the given context listener.
+     * @param listener the listener to unregister.
+     */
+    void unregisterContextListener(ContextListener listener);
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ErrorHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ErrorHandler.java
new file mode 100644
index 0000000..4792594
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ErrorHandler.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+/**
+ * Error Handler Service Definition.
+ * When exposed, this service is invoked when iPOJO throws a warning
+ * or an error. It's a hook on the internal iPOJO logger.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ErrorHandler {
+
+	/**
+	 * Method invokes when an error occurred.
+	 * @param instance the instance (can be <code>null</null>)
+	 * @param message the error message
+	 * @param error the error itself (can be <code>null</code>)
+	 */
+	public void onError(ComponentInstance instance, String message, Throwable error);
+
+	/**
+	 * Method invokes when a warning occurred.
+	 * @param instance the instance (can be <code>null</null>)
+	 * @param message the error message
+	 * @param error the error itself (can be <code>null</code>)
+	 */
+	public void onWarning(ComponentInstance instance, String message, Throwable error);
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/EventDispatcher.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/EventDispatcher.java
new file mode 100644
index 0000000..8219422
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/EventDispatcher.java
@@ -0,0 +1,181 @@
+/* 
+ * 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;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+
+/**
+ * iPOJO Internal event dispatcher.
+ * This class provides an internal service event dispatcher in order to tackle the
+ * event storm that can happen when starting large-scale applications.
+ * @see Extender
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public final class EventDispatcher implements ServiceListener {
+    
+    /**
+     * The internal event dispatcher.
+     * This dispatcher is a singleton.
+     */
+    private static EventDispatcher DISPATCHER;
+    
+    /**
+     * The list of listeners.
+     * Service interface -> List of {@link ServiceListener}
+     */
+    private Map m_listeners;
+    /**
+     * The global bundle context.
+     * This is the bundle context from iPOJO.
+     */
+    private BundleContext m_context;
+    
+    /**
+     * Creates the EventDispatcher.
+     * @param bc the bundle context used to register and unregister
+     * {@link ServiceListener}.
+     */
+    private EventDispatcher(BundleContext bc) {
+        m_context = bc;
+        m_listeners = new HashMap();
+        // Only one thread can call the start method.
+        m_context.addServiceListener(this);
+    }
+    
+    /**
+     * Creates the internal event
+     * dispatcher.
+     * @param bc the iPOJO bundle context to send to the 
+     * internal event dispatcher.
+     */
+    public static void create(BundleContext bc) {
+        DISPATCHER = new EventDispatcher(bc);
+    }
+    
+    /**
+     * Stops and delete the internal event dispatcher.
+     * This method must be call only
+     * if iPOJO is stopping.
+     */
+    public static void dispose() {
+        DISPATCHER.stop();
+        DISPATCHER = null;
+    }
+    
+    
+    /**
+     * Gets the iPOJO event dispatcher.
+     * @return the event dispatcher or
+     * <code>null</code> if not created.
+     */
+    public static EventDispatcher getDispatcher() {
+        return DISPATCHER;
+    }
+    
+    
+    /**
+     * Stops the event dispatcher.
+     * This method unregisters the {@link ServiceListener}.
+     * This methods must be called only when the iPOJO bundle
+     * stops.
+     */
+    private void stop() {
+        synchronized (this) {
+            m_context.removeServiceListener(this);
+            m_listeners.clear();
+        }
+    }
+
+    /**
+     * Method called when a {@link ServiceEvent} is
+     * fired by the OSGi framework. 
+     * According to the event, this method dispatches
+     * to interested registered listers from
+     * the {@link EventDispatcher#m_listeners} map.
+     * @param event the service event
+     * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+     */
+    public void serviceChanged(ServiceEvent event) {
+        String[] itfs = (String[]) event.getServiceReference().getProperty(Constants.OBJECTCLASS);
+        for (int s = 0; s < itfs.length; s++) {
+            List list;
+            synchronized (this) {
+                List stored = (List) m_listeners.get(itfs[s]);
+                if (stored == null) { 
+                    return; // Nothing to do
+                }
+                // Creates a new list (stack confinement)
+                list = new ArrayList(stored);
+            }
+            for (int i = 0; i < list.size(); i++) {
+                ((ServiceListener) list.get(i)).serviceChanged(event);
+            }
+        }
+    }
+    
+    /**
+     * Adds a new service listener to the {@link EventDispatcher#m_listeners}
+     * map. This method specifies the listen service interface
+     * @param itf the service interface
+     * @param listener the service listener
+     */
+    public void addListener(String itf, ServiceListener listener) {
+        synchronized (this) {
+            List list = (List) m_listeners.get(itf);
+            if (list == null) {
+                list = new ArrayList(1);
+                list.add(listener);
+                m_listeners.put(itf, list);
+            } else {
+                list.add(listener);
+            }
+        }
+    }
+    
+    /**
+     * Removes a service listener.
+     * @param listener the service listener to remove
+     * @return <code>true</code> if the listener is 
+     * successfully removed.
+     */
+    public boolean removeListener(ServiceListener listener) {
+        boolean removed = false;
+        synchronized (this) {
+            Set keys = m_listeners.keySet();
+            Iterator it = keys.iterator();
+            while (it.hasNext()) {
+                String itf = (String) it.next();
+                List list = (List) m_listeners.get(itf);
+                removed = removed || list.remove(listener);
+            }
+        }
+        return removed;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Extender.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Extender.java
new file mode 100644
index 0000000..146f06e
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Extender.java
@@ -0,0 +1,782 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+import org.apache.felix.ipojo.parser.ParseUtils;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.SynchronousBundleListener;
+
+/**
+ * iPOJO Extender.
+ * This class listens bundle arrivals and departures in order to detect and manage
+ * iPOJO powered bundles. This class creates factories and ask for instance creation.
+ * @see SynchronousBundleListener
+ * @see BundleActivator
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Extender implements SynchronousBundleListener, BundleActivator {
+
+    /**
+     * Enables the iPOJO internal dispatcher.
+     * This internal dispatcher helps the OSGi framework to support large
+     * scale applications. The internal dispatcher is disabled by default.
+     */
+    static boolean DISPATCHER_ENABLED = true;
+
+    /**
+     * Disables the iPOJO asynchronous processing.
+     * When set to false, the bundles are processed in the listener thread
+     * making iPOJO usable on Google App Engine. By default, the processing
+     * is asynchronous.
+     */
+    static boolean SYNCHRONOUS_PROCESSING_ENABLED = false;
+
+    /**
+     * Property allowing to set if the internal dispatcher is enabled or disabled.
+     * Possible value are either <code>true</code> or <code>false</code>.
+     */
+    private static final String ENABLING_DISPATCHER = "ipojo.internal.dispatcher";
+
+    /**
+     * Property allowing to disable the asynchronous process (and so enables the
+     * synchronous processing).
+     * Possible value are either <code>true</code> or <code>false</code>.
+     */
+    private static final String SYNCHRONOUS_PROCESSING = "ipojo.processing.synchronous";
+
+    /**
+     * iPOJO Component Type and Instance declaration header.
+     */
+    private static final String IPOJO_HEADER = "iPOJO-Components";
+
+    /**
+     * iPOJO Component Type and Instance declaration header
+     * (alternative).
+     * This header was introduced because of BND supporting only header
+     * starting with an uppercase.
+     */
+    private static final String IPOJO_HEADER_ALT = "IPOJO-Components";
+
+    /**
+     * iPOJO Extension declaration header.
+     */
+    private static final String IPOJO_EXTENSION = "IPOJO-Extension";
+
+    /**
+     * The Bundle Context of the iPOJO Core bundle.
+     */
+    private static BundleContext m_context;
+
+    /**
+     * The iPOJO Extender logger.
+     */
+    private Logger m_logger;
+
+    /**
+     * The instance creator used to create instances.
+     * (Singleton)
+     */
+    private InstanceCreator m_creator;
+
+    /**
+     * The iPOJO Bundle.
+     */
+    private Bundle m_bundle;
+
+    /**
+     * The list of factory types.
+     */
+    private List m_factoryTypes = new ArrayList();
+
+    /**
+     * The list of unbound types.
+     * A type is unbound if the matching extension is not deployed.
+     */
+    private final List m_unboundTypes = new ArrayList();
+
+    /**
+     * The processor analyzing arriving bundles and creating iPOJO contributions.
+     */
+    private final CreatorThread m_processor = new CreatorThread();
+
+    /**
+     * Bundle Listener Notification.
+     * @param event the bundle event.
+     * @see org.osgi.framework.BundleListener#bundleChanged(org.osgi.framework.BundleEvent)
+     */
+    public void bundleChanged(final BundleEvent event) {
+        if (event.getBundle() == m_bundle) { return; }
+
+        switch (event.getType()) {
+            case BundleEvent.STARTED:
+                // Put the bundle in the queue
+                m_processor.addBundle(event.getBundle());
+                break;
+            case BundleEvent.STOPPING:
+                m_processor.removeBundle(event.getBundle());
+                //TODO Should be done in another thread in the asynchronous case.
+                closeManagementFor(event.getBundle());
+                break;
+            default:
+                break;
+        }
+
+    }
+
+    /**
+     * Ends the iPOJO Management for the given bundle.
+     * Generally the bundle is leaving. This method
+     * stops every factories declared is the bundle and
+     * disposed every declared instances.
+     * @param bundle the bundle.
+     */
+    private void closeManagementFor(Bundle bundle) {
+        List toRemove = new ArrayList();
+        // Delete instances declared in the leaving bundle.
+        m_creator.removeInstancesFromBundle(bundle.getBundleId());
+        for (int k = 0; k < m_factoryTypes.size(); k++) {
+            ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) m_factoryTypes.get(k);
+
+            // Look for component type created from this bundle.
+            if (mft.m_created != null) {
+                List cfs = (List) mft.m_created.remove(bundle);
+                for (int i = 0; cfs != null && i < cfs.size(); i++) {
+                    IPojoFactory factory = (IPojoFactory) cfs.get(i);
+                    m_creator.removeFactory(factory);
+                    factory.stop();
+                }
+            }
+
+            // If the leaving bundle has declared mft : destroy all created factories.
+            if (mft.m_bundle == bundle) {
+                if (mft.m_created != null) {
+                    Iterator iterator = mft.m_created.keySet().iterator();
+                    while (iterator.hasNext()) {
+                        Bundle key = (Bundle) iterator.next();
+                        List list = (List) mft.m_created.get(key);
+                        for (int i = 0; i < list.size(); i++) {
+                            IPojoFactory factory = (IPojoFactory) list.get(i);
+                            factory.stop();
+                            m_unboundTypes.add(new UnboundComponentType(mft.m_type, factory.m_componentMetadata, factory.getBundleContext()
+                                    .getBundle()));
+                        }
+                    }
+                }
+                toRemove.add(mft);
+            }
+        }
+
+        for (int i = 0; i < toRemove.size(); i++) {
+            ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) toRemove.get(i);
+            m_logger.log(Logger.INFO, "The factory type: " + mft.m_type + " is no more available");
+            mft.m_bundle = null;
+            mft.m_clazz = null;
+            mft.m_created = null;
+            mft.m_type = null;
+            m_factoryTypes.remove(mft);
+        }
+    }
+
+    /**
+     * Checks if the given bundle is an iPOJO bundle, and begin
+     * the iPOJO management is true.
+     * @param bundle the bundle to check.
+     */
+    private void startManagementFor(Bundle bundle) {
+        Dictionary dict = bundle.getHeaders();
+        // Check for abstract factory type
+        String typeHeader = (String) dict.get(IPOJO_EXTENSION);
+        if (typeHeader != null) {
+            parseAbstractFactoryType(bundle, typeHeader);
+        }
+
+        // Check bundle
+        String header = (String) dict.get(IPOJO_HEADER);
+        // Check the alternative header
+        if (header == null) {
+            header = (String) dict.get(IPOJO_HEADER_ALT);
+        }
+
+        if (header != null) {
+            try {
+                parse(bundle, header);
+            } catch (IOException e) {
+                m_logger.log(Logger.ERROR, "An exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);
+            } catch (ParseException e) {
+                m_logger.log(Logger.ERROR, "A parse exception occurs during the parsing of the bundle " + bundle.getBundleId(), e);
+            }
+        }
+    }
+
+    /**
+     * Parses an IPOJO-Extension manifest header and then creates
+     * iPOJO extensions (factory types).
+     * @param bundle the bundle containing the header.
+     * @param header the header to parse.
+     */
+    private void parseAbstractFactoryType(Bundle bundle, String header) {
+        String[] arr = ParseUtils.split(header, ",");
+        for (int i = 0; arr != null && i < arr.length; i++) {
+            String[] arr2 = ParseUtils.split(arr[i], ":");
+            
+            /*
+             * Get the fully qualified type name.
+             * type = [namespace] name  
+             */
+            String[] nameparts = ParseUtils.split(arr2[0].trim(), " \t");
+            String type = nameparts.length == 1 ? nameparts[0] : nameparts[0]+":"+nameparts[1];
+            
+            Class clazz;
+            try {
+                clazz = bundle.loadClass(arr2[1]);
+            } catch (ClassNotFoundException e) {
+                m_logger.log(Logger.ERROR, "Cannot load the extension " + type, e);
+                return;
+            }
+            ManagedAbstractFactoryType mft = new ManagedAbstractFactoryType(clazz, type, bundle);
+            m_factoryTypes.add(mft);
+            m_logger.log(Logger.DEBUG, "New factory type available: " + type);
+
+            for (int j = m_unboundTypes.size() - 1; j >= 0; j--) {
+                UnboundComponentType unbound = (UnboundComponentType) m_unboundTypes.get(j);
+                if (unbound.m_type.equals(type)) {
+                    createAbstractFactory(unbound.m_bundle, unbound.m_description);
+                    m_unboundTypes.remove(unbound);
+                }
+            }
+        }
+    }
+
+    /**
+     * Parses the internal metadata (from the manifest
+     * (in the iPOJO-Components property)). This methods
+     * creates factories and add instances to the instance creator.
+     * @param bundle the owner bundle.
+     * @param components The iPOJO Header String.
+     * @throws IOException if the manifest can not be found
+     * @throws ParseException if the parsing process failed
+     */
+    private void parse(Bundle bundle, String components) throws IOException, ParseException {
+        ManifestMetadataParser parser = new ManifestMetadataParser();
+        parser.parseHeader(components);
+
+        // Get the component type declaration
+        Element[] metadata = parser.getComponentsMetadata();
+        for (int i = 0; i < metadata.length; i++) {
+            createAbstractFactory(bundle, metadata[i]);
+        }
+
+        Dictionary[] instances = parser.getInstances();
+        for (int i = 0; instances != null && i < instances.length; i++) {
+            m_creator.addInstance(instances[i], bundle.getBundleId());
+        }
+    }
+
+    /**
+     * iPOJO Start method.
+     * @param context the iPOJO bundle context.
+     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+     */
+    public void start(BundleContext context) {
+        m_context = context;
+        m_bundle = context.getBundle();
+        m_creator = new InstanceCreator(context);
+
+        m_logger = new Logger(m_context, "IPOJO-Extender");
+
+        enablingDispatcher(context, m_logger);
+        enablingSynchronousProcessing(context, m_logger);
+
+        // Create the dispatcher only if required.
+        if (DISPATCHER_ENABLED) {
+            EventDispatcher.create(context);
+        }
+
+        // Begin by initializing core handlers
+        startManagementFor(m_bundle);
+
+        if (! SYNCHRONOUS_PROCESSING_ENABLED) {
+            new Thread(m_processor).start();
+        }
+
+        synchronized (this) {
+            // listen to any changes in bundles.
+            m_context.addBundleListener(this);
+            // compute already started bundles.
+            for (int i = 0; i < context.getBundles().length; i++) {
+                if (context.getBundles()[i].getState() == Bundle.ACTIVE) {
+                    m_processor.addBundle(context.getBundles()[i]); // Bundles are processed in another thread.
+                }
+            }
+        }
+
+        m_logger.log(Logger.INFO, "iPOJO Runtime started");
+    }
+
+    /**
+     * Stops the iPOJO Bundle.
+     * @param context the bundle context.
+     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop(BundleContext context) {
+        m_processor.stop(); // Stop the thread processing bundles.
+        m_context.removeBundleListener(this);
+
+        if (DISPATCHER_ENABLED) {
+            EventDispatcher.dispose();
+        }
+
+        for (int k = 0; k < m_factoryTypes.size(); k++) {
+            ManagedAbstractFactoryType mft = (ManagedAbstractFactoryType) m_factoryTypes.get(k);
+
+            if (mft.m_created != null) {
+                Iterator iterator = mft.m_created.keySet().iterator();
+                while (iterator.hasNext()) {
+                    Bundle key = (Bundle) iterator.next();
+                    List list = (List) mft.m_created.get(key);
+                    for (int i = 0; i < list.size(); i++) {
+                        IPojoFactory factory = (IPojoFactory) list.get(i);
+                        m_creator.removeFactory(factory);
+                        factory.dispose();
+                    }
+                }
+            }
+        }
+
+        m_factoryTypes = null;
+        m_creator = null;
+
+        m_logger.log(Logger.INFO, "iPOJO Runtime stopped");
+        m_context = null;
+    }
+
+    /**
+     * Gets iPOJO bundle context.
+     * @return the iPOJO Bundle Context
+     */
+    public static BundleContext getIPOJOBundleContext() {
+        return m_context;
+    }
+
+    /**
+     * Enables or disables the internal dispatcher, so sets the
+     * {@link Extender#DISPATCHER_ENABLED} flag.
+     * This method checks if the {@link Extender#ENABLING_DISPATCHER}
+     * property is set to <code>true</code>. Otherwise, the internal
+     * dispatcher is disabled. The property can be set as a system
+     * property (<code>ipojo.internal.dispatcher</code>) or inside the
+     * iPOJO bundle manifest (<code>ipojo-internal-dispatcher</code>).
+     * @param context the bundle context.
+     * @param logger the logger to indicates if the internal dispatcher is set.
+     */
+    private static void enablingDispatcher(BundleContext context, Logger logger) {
+        // First check in the framework and in the system properties
+        String flag = context.getProperty(ENABLING_DISPATCHER);
+
+        // If null, look in bundle manifest
+        if (flag == null) {
+            String key = ENABLING_DISPATCHER.replace('.', '-');
+            flag = (String) context.getBundle().getHeaders().get(key);
+        }
+
+        if (flag != null) {
+            if (flag.equalsIgnoreCase("true")) {
+                Extender.DISPATCHER_ENABLED = true;
+                logger.log(Logger.INFO, "iPOJO Internal Event Dispatcher enables");
+                return;
+            }
+        }
+
+        // Either l is null, or the specified value was false
+        Extender.DISPATCHER_ENABLED = false;
+        logger.log(Logger.INFO, "iPOJO Internal Event Dispatcher disables");
+
+    }
+
+    /**
+     * Enables or disables the asynchronous processing, so sets the
+     * {@link Extender#SYNCHRONOUS_PROCESSING_ENABLED} flag.
+     * Disabling asynchronous processing avoids iPOJO to create a new
+     * thread to process bundles. So, iPOJO can be used on the
+     * Google App Engine.
+     * This method checks if the {@link Extender#SYNCHRONOUS_PROCESSING}
+     * property is set to <code>true</code>. Otherwise, asynchronous processing
+     * is used (default). The property can be set as a system
+     * property (<code>ipojo.processing.synchronous</code>) or inside the
+     * iPOJO bundle manifest.
+     * @param context the bundle context.
+     * @param logger the logger to indicates if the internal dispatcher is set.
+     */
+    private static void enablingSynchronousProcessing(BundleContext context, Logger logger) {
+        String flag = context.getProperty(SYNCHRONOUS_PROCESSING);
+
+        // If null, look in bundle manifest
+        if (flag == null) {
+            String key = SYNCHRONOUS_PROCESSING.replace('.', '-');
+            flag = (String) context.getBundle().getHeaders().get(key);
+        }
+
+        if (flag != null) {
+            if (flag.equalsIgnoreCase("true")) {
+                Extender.SYNCHRONOUS_PROCESSING_ENABLED = true;
+                logger.log(Logger.INFO, "iPOJO Asynchronous processing disabled");
+                return;
+            }
+        }
+
+        // Either l is null, or the specified value was false
+        Extender.SYNCHRONOUS_PROCESSING_ENABLED = false;
+        logger.log(Logger.INFO, "iPOJO synchrnous processing disables");
+
+    }
+
+    /**
+     * Adds a component factory to the factory list.
+     * @param metadata the new component metadata.
+     * @param bundle the bundle.
+     */
+    private void createAbstractFactory(Bundle bundle, Element metadata) {
+        ManagedAbstractFactoryType factoryType = null;
+        // First, look for factory-type (component, handler, composite ...)
+        
+        // TODO : Should Element.getQualifiedName() be public ?
+        String typeName = metadata.getNameSpace() == null ? metadata.getName() : metadata.getNameSpace()+":"+metadata.getName();
+        
+        for (int i = 0; i < m_factoryTypes.size(); i++) {
+            ManagedAbstractFactoryType type = (ManagedAbstractFactoryType) m_factoryTypes.get(i);
+            if (type.m_type.equals(typeName)) {
+                factoryType = type;
+                break;
+            }
+        }
+
+        // If not found, return. It will wait for a new component type factory.
+        if (factoryType == null) {
+            m_logger.log(Logger.WARNING, "Type of component not available: " + typeName);
+            m_unboundTypes.add(new UnboundComponentType(typeName, metadata, bundle));
+            return;
+        }
+
+        // Once found, we invoke the AbstractFactory constructor to create the component factory.
+        Class clazz = factoryType.m_clazz;
+        try {
+            // Look for the constructor, and invoke it.
+            Constructor cst = clazz.getConstructor(new Class[] { BundleContext.class, Element.class });
+            IPojoFactory factory = (IPojoFactory) cst.newInstance(new Object[] { getBundleContext(bundle), metadata });
+
+            // Add the created factory in the m_createdFactories map.
+            if (factoryType.m_created == null) {
+                factoryType.m_created = new HashMap();
+                List list = new ArrayList();
+                list.add(factory);
+                factoryType.m_created.put(bundle, list);
+            } else {
+                List list = (List) factoryType.m_created.get(bundle);
+                if (list == null) {
+                    list = new ArrayList();
+                    list.add(factory);
+                    factoryType.m_created.put(bundle, list);
+                } else {
+                    list.add(factory);
+                }
+            }
+
+            // Start the created factory.
+            factory.start();
+            // Then add the factory to the instance creator.
+            m_creator.addFactory(factory);
+
+        } catch (SecurityException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);
+        } catch (NoSuchMethodException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName() + ": the given class constructor cannot be found");
+        } catch (IllegalArgumentException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);
+        } catch (InstantiationException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);
+        } catch (IllegalAccessException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e);
+        } catch (InvocationTargetException e) {
+            m_logger.log(Logger.ERROR, "Cannot instantiate an abstract factory from " + clazz.getName(), e.getTargetException());
+        }
+    }
+
+    /**
+     * Structure storing an iPOJO extension.
+     */
+    private static final class ManagedAbstractFactoryType {
+        /**
+         * The type (i.e.) name of the extension.
+         */
+        String m_type;
+
+        /**
+         * The abstract Factory class.
+         */
+        Class m_clazz;
+
+        /**
+         * The bundle object containing the declaration of the extension.
+         */
+        Bundle m_bundle;
+
+        /**
+         * The factories created by this extension.
+         */
+        private Map m_created;
+
+        /**
+         * Creates a ManagedAbstractFactoryType.
+         * @param factory the abstract factory class.
+         * @param type the name of the extension.
+         * @param bundle the bundle declaring the extension.
+         */
+        protected ManagedAbstractFactoryType(Class factory, String type, Bundle bundle) {
+            m_bundle = bundle;
+            m_clazz = factory;
+            m_type = type;
+        }
+    }
+
+    /**
+     * Structure storing unbound component type declarations.
+     * Unbound means that there is no extension able to manage the extension.
+     */
+    private static final class UnboundComponentType {
+        /**
+         * The component type description.
+         */
+        private final Element m_description;
+
+        /**
+         * The bundle declaring this type.
+         */
+        private final Bundle m_bundle;
+
+        /**
+         * The required extension name.
+         */
+        private final String m_type;
+
+        /**
+         * Creates a UnboundComponentType.
+         * @param description the description of the component type.
+         * @param bundle the bundle declaring this type.
+         * @param type the required extension name.
+         */
+        protected UnboundComponentType(String type, Element description, Bundle bundle) {
+            m_type = type;
+            m_description = description;
+            m_bundle = bundle;
+        }
+    }
+
+    /**
+     * Computes the bundle context from the bundle class by introspection.
+     * @param bundle the bundle.
+     * @return the bundle context object or <code>null</code> if not found.
+     */
+    public BundleContext getBundleContext(Bundle bundle) {
+        if (bundle == null) { return null; }
+
+        // getBundleContext (OSGi 4.1)
+        Method meth = null;
+        try {
+            meth = bundle.getClass().getMethod("getBundleContext", new Class[0]); // This method is public and is specified in the Bundle interface.
+        } catch (SecurityException e) {
+            // Nothing do to, will try the Equinox method
+        } catch (NoSuchMethodException e) {
+            // Nothing do to, will try the Equinox method
+        }
+
+        // try Equinox getContext if not found.
+        if (meth == null) {
+            try {
+                meth = bundle.getClass().getMethod("getContext", new Class[0]);
+            } catch (SecurityException e) {
+                // Nothing do to, will try field inspection
+            } catch (NoSuchMethodException e) {
+                // Nothing do to, will try field inspection
+            }
+        }
+
+        if (meth != null) {
+            if (! meth.isAccessible()) {
+                // If not accessible, try to set the accessibility.
+                meth.setAccessible(true);
+            }
+            try {
+                return (BundleContext) meth.invoke(bundle, new Object[0]);
+            } catch (IllegalArgumentException e) {
+                m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e);
+                return null;
+            } catch (IllegalAccessException e) {
+                m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e);
+                return null;
+            } catch (InvocationTargetException e) {
+                m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + meth.getName(), e.getTargetException());
+                return null;
+            }
+        }
+
+        // Else : Field inspection (KF and Prosyst)
+        Field[] fields = bundle.getClass().getDeclaredFields();
+        for (int i = 0; i < fields.length; i++) {
+            if (BundleContext.class.isAssignableFrom(fields[i].getType())) {
+                if (!fields[i].isAccessible()) {
+                    fields[i].setAccessible(true);
+                }
+                try {
+                    return (BundleContext) fields[i].get(bundle);
+                } catch (IllegalArgumentException e) {
+                    m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + fields[i].getName(), e);
+                    return null;
+                } catch (IllegalAccessException e) {
+                    m_logger.log(Logger.ERROR, "Cannot get the BundleContext by invoking " + fields[i].getName(), e);
+                    return null;
+                }
+            }
+        }
+        m_logger.log(Logger.ERROR, "Cannot find the BundleContext for " + bundle.getSymbolicName(), null);
+        return null;
+    }
+
+
+    /**
+     * The creator thread analyzes arriving bundles to create iPOJO contribution.
+     */
+    private class CreatorThread implements Runnable {
+
+        /**
+         * Is the creator thread started?
+         */
+        private boolean m_started = true;
+
+        /**
+         * The list of bundle that are going to be analyzed.
+         */
+        private List m_bundles = new ArrayList();
+
+        /**
+         * A bundle is arriving.
+         * This method is synchronized to avoid concurrent modification of the waiting list.
+         * @param bundle the new bundle
+         */
+        public synchronized void addBundle(Bundle bundle) {
+            if (SYNCHRONOUS_PROCESSING_ENABLED) {
+                m_logger.log(Logger.DEBUG, "Analyzing " + bundle.getBundleId());
+                startManagementFor(bundle);
+            } else {
+                // Asynchronous case, we add the bundle to the queue
+                m_bundles.add(bundle);
+                notifyAll(); // Notify the thread to force the process.
+                m_logger.log(Logger.DEBUG, "Creator thread is going to analyze the bundle " + bundle.getBundleId() + " List : " + m_bundles);
+            }
+        }
+
+        /**
+         * A bundle is leaving.
+         * If the bundle was not already processed, the bundle is remove from the waiting list.
+         * This method is synchronized to avoid concurrent modification of the waiting list.
+         * @param bundle the leaving bundle.
+         */
+        public synchronized void removeBundle(Bundle bundle) {
+            m_bundles.remove(bundle);
+        }
+
+        /**
+         * Stops the creator thread.
+         */
+        public synchronized void stop() {
+            m_started = false;
+            m_bundles.clear();
+            notifyAll();
+        }
+
+        /**
+         * Creator thread's run method.
+         * While the list is not empty, the thread launches the bundle analyzing on the next bundle.
+         * When the list is empty, the thread sleeps until the arrival of a new bundle
+         * or until iPOJO stops.
+         * @see java.lang.Runnable#run()
+         */
+        public void run() {
+            m_logger.log(Logger.DEBUG, "Creator thread is starting");
+            boolean started;
+            synchronized (this) {
+                started = m_started;
+            }
+            while (started) {
+                Bundle bundle;
+                synchronized (this) {
+                    while (m_started && m_bundles.isEmpty()) {
+                        try {
+                            m_logger.log(Logger.DEBUG, "Creator thread is waiting - Nothing to do");
+                            wait();
+                        } catch (InterruptedException e) {
+                            // Interruption, re-check the condition
+                        }
+                    }
+                    if (!m_started) {
+                        m_logger.log(Logger.DEBUG, "Creator thread is stopping");
+                        return; // The thread must be stopped immediately.
+                    } else {
+                        // The bundle list is not empty, get the bundle.
+                        // The bundle object is collected inside the synchronized block to avoid
+                        // concurrent modification. However the real process is made outside the
+                        // mutual exclusion area
+                        bundle = (Bundle) m_bundles.remove(0);
+                    }
+                }
+                // Process ...
+                m_logger.log(Logger.DEBUG, "Creator thread is processing " + bundle.getBundleId());
+                try {
+                    startManagementFor(bundle);
+                } catch (Throwable e) {
+                    // To be sure to not kill the thread, we catch all exceptions and errors
+                    m_logger.log(Logger.ERROR, "An error occurs when analyzing the content or starting the management of " + bundle.getBundleId(), e);
+                }
+                synchronized (this) {
+                    started = m_started;
+                }
+            }
+        }
+
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Factory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Factory.java
new file mode 100644
index 0000000..f18c1d3
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Factory.java
@@ -0,0 +1,164 @@
+/* 
+ * 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;
+
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Component Type Factory Service. This service is exposed by a instance manager factory, and allows the dynamic creation of component instance.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Factory {
+
+    /**
+     * Factory State.
+     * A valid factory is a factory where all required handlers are available.
+     */
+    int VALID = 1;
+
+    /**
+     * Factory State.
+     * An invalid factory is a factory where at least one required handler is
+     * unavailable. Creating an instance with an invalid factory failed.
+     */
+    int INVALID = 0;
+
+    /**
+     * Creates an instance manager (i.e. component type instance).
+     * @param configuration the configuration properties for this component.
+     * @return the created instance manager.
+     * @throws UnacceptableConfiguration if the given configuration is not valid.
+     * @throws MissingHandlerException if an handler is missing.
+     * @throws ConfigurationException if the instance configuration failed.
+     */
+    ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException;
+
+    /**
+     * Creates an instance manager (i.e. component type instance).
+     * The instance is created in the scope given in argument.
+     * @param configuration the configuration properties for this component.
+     * @param serviceContext the service context of the component.
+     * @return the created instance manager.
+     * @throws UnacceptableConfiguration if the given configuration is not valid.
+     * @throws MissingHandlerException if an handler is missing.
+     * @throws ConfigurationException if the instance configuration failed.
+     */
+    ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, MissingHandlerException, ConfigurationException;
+
+    /**
+     * Gets the component type information containing provided service,
+     * configuration properties ...
+     * @return the component type information.
+     */
+    Element getDescription();
+
+    /**
+     * Gets the component type description.
+     * @return the component type description object
+     */
+    ComponentTypeDescription getComponentDescription();
+
+    /**
+     * Checks if the given configuration is acceptable as a configuration
+     * of a component instance.
+     * @param conf the configuration to test
+     * @return <code>true</code> if the configuration is acceptable
+     */
+    boolean isAcceptable(Dictionary conf);
+
+    /**
+     * Returns the factory name.
+     * @return the name of the factory.
+     */
+    String getName();
+
+    /**
+     * Reconfigures an instance already created. This configuration needs to
+     * have the name property to identify the instance.
+     * @param conf the configuration to reconfigure the instance.
+     * @throws UnacceptableConfiguration  if the given configuration is not consistent for the targeted instance.
+     * @throws MissingHandlerException if an handler is missing.
+     */
+    void reconfigure(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException;
+
+    /**
+     * Adds a factory state listener on the current factory.
+     * @param listener the listener to add
+     */
+    void addFactoryStateListener(FactoryStateListener listener);
+
+    /**
+     * Removes the given factory state listener from the listener list.
+     * @param listener the listener to remove
+     */
+    void removeFactoryStateListener(FactoryStateListener listener);
+
+    /**
+     * Gets the list of missing handlers.
+     * The handlers are given under the form namespace:name
+     * @return the list containing the name of missing handlers
+     */
+    List getMissingHandlers();
+
+    /**
+     * Get the list of required handlers.
+     * The handlers are given under the form namespace:name
+     * @return the list containing the name of required handlers
+     */
+    List getRequiredHandlers();
+
+    /**
+     * Returns the class name of the component type.
+     * For factories which does not contains a class, return "composite"
+     * @return the class name of the component type or "composite"
+     * @deprecated
+     */
+    String getClassName();
+
+    /**
+     * Returns the state of the factory.
+     * @return the state of the factory
+     */
+    int getState();
+
+    /**
+     * Gets the bundle context of the factory.
+     * @return the bundle context of the factory.
+     */
+    BundleContext getBundleContext();
+
+    /**
+     * Gets the version of the component type.
+     * @return the component type version or <code>null</code> if
+     * not specified.
+     */
+    String getVersion();
+
+    /**
+     * Gets the component type metadata (Element - Attribute structure)
+     * @return the root element of the component metadata. The result must <b>not</b> be modified.
+     */
+    Element getComponentMetadata();
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java
new file mode 100644
index 0000000..3d9dadd
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FactoryStateListener.java
@@ -0,0 +1,36 @@
+/* 
+ * 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;
+
+/**
+ * A factory state listener received notification about monitored factory state changes.
+ * This listener allows anyone to be notified when the listened factory state changes. 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface FactoryStateListener {
+    
+    /**
+     * Notification listener.
+     * Each time an instance state changes, this method is called
+     * with the new factory state.
+     * @param factory the changing factory
+     * @param newState the new factory state
+     */
+    void stateChanged(Factory factory, int newState);
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FieldInterceptor.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FieldInterceptor.java
new file mode 100644
index 0000000..22e308d
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/FieldInterceptor.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.felix.ipojo;
+
+/**
+* A field interceptor is notified when a monitored field asks for a value or
+* receives a new value. A class implementing this interface is able to be 
+* notified of field accesses, and is able to inject a value to this field.
+* The listener needs to be register on the instance manager. 
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public interface FieldInterceptor {
+    
+    /**
+     * This method is called when a PUTFIELD operation is detected,
+     * e.g. an assignation.
+     * @param pojo the pojo object setting the value
+     * @param fieldName the field name
+     * @param value the value passed to the field
+     */
+    void onSet(Object pojo, String fieldName, Object value);
+
+    /**
+     * This method is called when a GETFIELD operation is detected.
+     * This method allows to inject a value to the field.
+     * @param pojo the pojo object getting the value
+     * @param fieldName the field name
+     * @param value the value passed to the field (by the previous call)
+     * @return the managed value of the field
+     */
+    Object onGet(Object pojo, String fieldName, Object value);
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Handler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Handler.java
new file mode 100644
index 0000000..9e14cd5
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Handler.java
@@ -0,0 +1,264 @@
+/* 
+ * 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;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+
+/**
+ * Handler Abstract Class.
+ * A handler is a 'piece' of 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class Handler {
+
+    /**
+     * The handler namespace property.
+     */
+    public static final String HANDLER_NAMESPACE_PROPERTY = "handler.namespace";
+
+    /**
+     * The handler name property. 
+     */
+    public static final String HANDLER_NAME_PROPERTY = "handler.name";
+
+    /**
+     * The handler type property. 
+     */
+    public static final String HANDLER_TYPE_PROPERTY = "handler.type";
+
+    /**
+     * The handler priority.
+     */
+    public static final String HANDLER_LEVEL_PROPERTY = "handler.level";
+
+    /**
+     * The current handler validity.
+     * This impacts directly the instance state.
+     */
+    protected boolean m_isValid = true;
+
+    /**
+     * The HandlerManager managing the current handler.
+     */
+    protected HandlerManager m_instance;
+
+    /**
+     * Sets the factory attached to this handler object.
+     * This method must be override to depend on each component factory type. 
+     * @param factory the factory to attach.
+     */
+    public abstract void setFactory(Factory factory);
+
+    /**
+     * Gets the logger to use in the handler.
+     * This method must be override to depend on each component factory type logging policy.
+     * @return the logger.
+     */
+    public abstract Logger getLogger();
+
+    /**
+     * Log method (warning).
+     * Log a warning message to the handler logger.
+     * @param message the message to log
+     */
+    public final void warn(String message) {
+        getLogger().log(Logger.WARNING, message);
+    }
+
+    /**
+     * Log method (error).
+     * Log an error message to the handler logger.
+     * @param message the message to log
+     */
+    public final void error(String message) {
+        getLogger().log(Logger.ERROR, message);
+    }
+
+    /**
+     * Log method (info).     
+     * Log an info message to the handler logger.
+     * @param message the message to log
+     */
+    public final void info(String message) {
+        getLogger().log(Logger.INFO, message);
+    }
+    
+    /**
+     * Log method (debug).     
+     * Log a debug message to the handler logger.
+     * @param message the message to log
+     */
+    public final void debug(String message) {
+        getLogger().log(Logger.DEBUG, message);
+    }
+
+    /**
+     * Log method (warning).
+     * Log a warning message to the handler logger.
+     * The message is sent with an attached exception.
+     * @param message the message to log
+     * @param exception the exception to attach with the message
+     */
+    public final void warn(String message, Throwable exception) {
+        getLogger().log(Logger.WARNING, message, exception);
+    }
+
+    /**
+     * Log method (error).
+     * Log an error message to the handler logger.
+     * The message is sent with an attached exception.
+     * @param message the message to log
+     * @param exception the exception to attach to the message
+     */
+    public final void error(String message, Throwable exception) {
+        getLogger().log(Logger.ERROR, message, exception);
+    }
+
+    /**
+     * Get a plugged handler of the same container.
+     * This method must be call only in the start method (or after). 
+     * In the configure method, this method can not return a consistent
+     * result as all handlers are not plugged. 
+     * @param name : name of the handler to find (class name or qualified handler name (ns:name)). 
+     * @return the handler object or null if the handler is not found.
+     */
+    public abstract Handler getHandler(String name);
+
+    /**
+     * Attaches the current handler object to the given component instance.
+     * An attached handler becomes a part of the instance container.
+     * @param instance the component instance on which the current handler will be attached.
+     */
+    protected abstract void attach(ComponentInstance instance);
+
+    /**
+     * Checks if the current handler is valid.
+     * This check tests the handler validity.
+     * This method must not be override.
+     * @return <code>true</code> if the handler is valid.
+     */
+    public final boolean isValid() {
+        return ((Pojo) this).getComponentInstance().getState() == ComponentInstance.VALID;
+    }
+
+    /**
+     * Sets the validity of the current handler.
+     * @param isValid if <code>true</code> the handler becomes valid, else it becomes invalid.
+     */
+    public final void setValidity(boolean isValid) {
+        if (m_isValid != isValid) {
+            m_isValid = isValid;
+            HandlerManager instance = getHandlerManager();
+            if (isValid) {
+                instance.stateChanged(instance, ComponentInstance.VALID);
+            } else {
+                instance.stateChanged(instance, ComponentInstance.INVALID);
+            }
+        }
+    }
+
+    /**
+     * Is the current handler valid.
+     * @return <code>true</code> if the handler is valid, <code>false</code> otherwise.
+     */
+    public final boolean getValidity() {
+        return m_isValid;
+    }
+
+    /**
+     * Gets the component instance of the current handler.
+     * @return the component instance.
+     */
+    public final HandlerManager getHandlerManager() {
+        if (m_instance != null) { return m_instance; }
+        m_instance = (HandlerManager) ((Pojo) this).getComponentInstance();
+        return m_instance;
+    }
+
+    /**
+     * Initializes the component factory.
+     * This method aims to collect component factory properties. 
+     * Each handler wanting to contribute needs to override this 
+     * method and adds properties to the given component description.
+     * By default, this method does nothing.
+     * @param typeDesc the component description.
+     * @param metadata the component type metadata.
+     * @throws ConfigurationException if the metadata are not correct (early detection).
+     */
+    public void initializeComponentFactory(ComponentTypeDescription typeDesc, Element metadata) throws ConfigurationException {
+        // The default implementation does nothing.
+    }
+
+    /**
+     * Configures the handler.
+     * @param metadata the metadata of the component
+     * @param configuration the instance configuration
+     * @throws ConfigurationException if the metadata are not correct.
+     */
+    public abstract void configure(Element metadata, Dictionary configuration) throws ConfigurationException;
+
+    /**
+     * Stops the handler
+     * This method stops the management.
+     */
+    public abstract void stop();
+
+    /**
+     * Starts the handler
+     * This method starts the management.
+     */
+    public abstract void start();
+
+    /**
+     * This method is called when the component state changed.
+     * By default, this method does nothing.
+     * @param state the new instance state {@link ComponentInstance}
+     */
+    public void stateChanged(int state) {
+        // The default implementation does nothing.
+    }
+
+    /**
+     * Returns the current handler description.
+     * The simplest description contains only the name and the validity of the handler.
+     * If the handler override this method, it can customize the description. 
+     * By default, this method returns the simplest description.
+     * @return the description of the handler.
+     */
+    public HandlerDescription getDescription() {
+        return new HandlerDescription(this);
+    }
+
+    /**
+     * Reconfigures the instance.
+     * This method is called, when the instance is under reconfiguration.
+     * The reconfiguration does not stops the instance, and so the handler supporting
+     * the reconfiguration must override this method and handles this case. 
+     * By default, this method does nothing.
+     * @param configuration the new instance configuration.
+     */
+    public void reconfigure(Dictionary configuration) {
+        // The default implementation does nothing.
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
new file mode 100644
index 0000000..c4a969c
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/HandlerFactory.java
@@ -0,0 +1,65 @@
+/* 
+ * 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;
+
+
+/**
+ * Service interface published by handler factory.
+ * This interface allows interacting the the handler factory to create
+ * {@link Handler} objects.
+ * @see Factory 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface HandlerFactory extends Factory {
+
+    /**
+     * The iPOJO Default Namespace.
+     */
+    String IPOJO_NAMESPACE = "org.apache.felix.ipojo";
+
+    /**
+     * Gets the namespace associated with this handler factory.
+     * @return the namespace used by this handler
+     */
+    String getNamespace();
+
+    /**
+     * Gets the name associated with this handler factory.
+     * @return the name used by this handler
+     */
+    String getHandlerName();
+
+    /**
+     * Gets the type of the handler factory.
+     * The handler can only be plugged on instance container with the same type.
+     * Basically, types are <code>primitive</code> and <code>composite</code>.
+     * @return the type of the handler
+     */
+    String getType();
+
+    /**
+     * Gets the start level of the handler objects created by this factory.
+     * Handlers with a low start level are configured and started before 
+     * handlers with an higher start level. Moreover, these handlers are
+     * stopped and disposed after.
+     * @return the handler's start level
+     */
+    int getStartLevel();
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
new file mode 100644
index 0000000..4472200
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/HandlerManager.java
@@ -0,0 +1,244 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The handler manager manages an handler instance.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class HandlerManager extends InstanceManager {
+
+    /**
+     * The internal handler object.
+     * Immutable once set.
+     */
+    private Handler m_handler;
+
+    /**
+     * Creates a handler manager.
+     * @param factory the handler factory
+     * @param context the bundle context
+     * @param handlers the handler array
+     */
+    public HandlerManager(ComponentFactory factory, BundleContext context, HandlerManager[] handlers) {
+        super(factory, context, handlers);
+    }
+
+    /**
+     * Gets the contained handler object.
+     * If not already created it creates the object.
+     * @return the handler object.
+     */
+    public Handler getHandler() {
+        if (m_handler == null) {
+            createHandlerObject();
+        }
+        return m_handler;
+    }
+
+    /**
+     * Creates and initializes the handler object.
+     * @param instance the component instance on which the handler will be attached.
+     * @param metadata the component metadata.
+     * @param configuration the instance configuration.
+     * @throws ConfigurationException if the handler configuration failed.
+     */
+    public void init(ComponentInstance instance, Element metadata, Dictionary configuration) throws ConfigurationException {
+        createHandlerObject();
+        m_handler.setFactory(instance.getFactory());
+        m_handler.attach(instance);
+        m_handler.configure(metadata, configuration);
+    }
+
+    /**
+     * Creates the handler object.
+     * This method does nothing if the object is already created.
+     * This method does not need locking protocol as only one thread (the creator thread) can create an instance.
+     */
+    private void createHandlerObject() {
+        if (m_handler != null) { return; }
+        m_handler = (Handler) createPojoObject();
+    }
+
+    /**
+     * Creates an instance of the content.
+     * This method needs to be called once only for singleton provided service.
+     * This methods call the {@link InstanceManager#createObject()} method, and adds
+     * the created object to the {@link InstanceManager#m_pojoObjects} list. Then,
+     * it calls the {@link PrimitiveHandler#onCreation(Object)} methods on attached
+     * handlers.
+     * @return a new instance or <code>null</code> if an error occurs during the
+     * creation.
+     */
+    public Object createPojoObject() {
+        Object instance = createObject();
+
+        // Add the new instance in the instance list.
+        synchronized (this) {
+            if (m_pojoObjects == null) {
+                m_pojoObjects = new ArrayList(1);
+            }
+            m_pojoObjects.add(instance);
+        }
+
+        //Do not call onCreation, this will be done in the start method.
+
+        return instance;
+    }
+
+    /**
+     * Starts the instance manager.
+     */
+    public void start() {
+        synchronized (this) {
+            if (m_state != STOPPED) {
+                return; // Instance already started
+            } else {
+                m_state = -2; // Temporary starting state, avoiding concurrent starts.
+            }
+        }
+
+        // Start attached handler.
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].addInstanceStateListener(this);
+            m_handlers[i].start();
+        }
+
+        // Call the onCreation method.
+        for (int i = 0; i < m_handlers.length; i++) {
+            ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(m_handler);
+        }
+
+
+        m_handler.start(); // Call the handler start method, the instance might be invalid.
+
+
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (!m_handlers[i].getHandler().isValid()) {
+                setState(INVALID);
+                return;
+            }
+        }
+        if (m_handler.getValidity()) {
+            setState(VALID);
+        } else {
+            setState(INVALID);
+        }
+
+        // Now, the state is necessary different from the temporary state.
+    }
+
+    /**
+     * Stops the instance manager.
+     */
+    public void stop() {
+        synchronized (this) {
+            if (m_state == STOPPED) {
+                return; // Instance already stopped
+            } else {
+                m_state = -2; // Temporary state avoiding concurrent stopping.
+            }
+        }
+
+        setState(INVALID);
+
+        if (m_handler != null) {
+            m_handler.stop();
+        }
+
+        // Stop all the handlers
+        for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].removeInstanceStateListener(this);
+            m_handlers[i].stop();
+        }
+
+        List listeners = null;
+        synchronized (this) {
+            m_state = STOPPED;
+            if (m_listeners != null) {
+                listeners = new ArrayList(m_listeners); // Stack confinement.
+            }
+        }
+
+        if (listeners != null) {
+            for (int i = 0; i < listeners.size(); i++) {
+                ((InstanceStateListener) listeners.get(i)).stateChanged(this, STOPPED);
+            }
+        }
+    }
+
+    /**
+     * Disposes the instance.
+     * @see org.apache.felix.ipojo.ComponentInstance#dispose()
+     */
+    public void dispose() {
+        super.dispose();
+        m_handler = null;
+    }
+
+    /**
+     * Kills the current instance.
+     * Only the factory of this instance can call this method.
+     */
+    protected void kill() {
+        super.dispose();
+        m_handler = null;
+    }
+
+    /**
+     * State Change listener callback.
+     * This method is notified at each time a plugged handler becomes invalid.
+     * @param instance the changing instance
+     * @param newState the new state
+     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
+     */
+    public void stateChanged(ComponentInstance instance, int newState) {
+        int state;
+        synchronized (this) {
+            if (m_state <= STOPPED) {
+                return;
+            } else {
+                state = m_state; // Stack confinement
+            }
+        }
+        // Update the component state if necessary
+        if (newState == INVALID && state == VALID) {
+            // Need to update the state to UNRESOLVED
+            setState(INVALID);
+            return;
+        }
+        if (newState == VALID && state == INVALID) {
+            // An handler becomes valid => check if all handlers are valid
+            if (!m_handler.getValidity()) { return; }
+            for (int i = 0; i < m_handlers.length; i++) {
+                if (m_handlers[i].getState() != VALID) { return; }
+            }
+            setState(VALID);
+            return;
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/HandlerManagerFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/HandlerManagerFactory.java
new file mode 100644
index 0000000..8cef70e
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/HandlerManagerFactory.java
@@ -0,0 +1,215 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Implementation of the handler factory interface.
+ * This factory is able to create handler manager.
+ * A handler manager is an iPOJO instance containing a handler object.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class HandlerManagerFactory extends ComponentFactory implements HandlerFactory {
+
+    /**
+     * The Handler type (<code>composite</code> or <code>primitive</code>).
+     */
+    private final String m_type;
+
+    /**
+     * The iPOJO Handler Namespace.
+     * (Uses the iPOJO default namespace is not specified)
+     */
+    private final String m_namespace;
+
+    /**
+     * The handler start level.
+     * Lower levels are priority and so are configured and started
+     * before higher levels, and are stopped after.
+     */
+    private final int m_level;
+
+    /**
+     * Creates a handler factory.
+     * @param context the bundle context
+     * @param metadata the metadata of the component to create
+     * @throws ConfigurationException if the element describing the factory is malformed.
+     */
+    public HandlerManagerFactory(BundleContext context, Element metadata) throws ConfigurationException {
+        super(context, metadata);
+
+        // Get the name
+        m_factoryName = metadata.getAttribute("name");
+        if (m_factoryName == null) { throw new ConfigurationException("An Handler needs a name"); }
+
+        // Get the type
+        String type = metadata.getAttribute("type");
+        if (type != null) {
+            m_type = type;
+        } else {
+            m_type = "primitive"; // Set to primitive if not specified.
+        }
+
+        String level = metadata.getAttribute("level");
+        if (level != null) {
+            m_level = new Integer(level).intValue();
+        } else {
+            m_level = Integer.MAX_VALUE; // Set to max if not specified.
+        }
+
+        // Get the namespace
+        String namespace = metadata.getAttribute("namespace");
+        if (namespace != null) {
+            m_namespace = namespace.toLowerCase();
+        } else {
+            m_namespace = IPOJO_NAMESPACE; // Set to the iPOJO default namespace if not specified.
+        }
+    }
+
+    public String getNamespace() {
+        return m_namespace;
+    }
+
+    public String getHandlerName() {
+        return m_namespace + ":" + getName();
+    }
+
+    public String getType() {
+        return m_type;
+    }
+
+    public int getStartLevel() {
+        return m_level;
+    }
+
+    public ComponentTypeDescription getComponentTypeDescription() {
+        return new HandlerTypeDescription(this);
+    }
+
+    /**
+     * Stops the factory.
+     * This method does not disposed created instances.
+     * These instances will be disposed by the instance managers.
+     * This method is called with the lock.
+     */
+    public void stopping() {
+        if (m_tracker != null) {
+            m_tracker.close();
+            m_tracker = null;
+        }
+    }
+
+    /**
+     * Creates an instance. The given configuration needs to contain the 'name'
+     * property. This method is called when holding the lock.
+     * @param configuration the configuration of the created instance.
+     * @param context  the service context to push for this instance.
+     * @param handlers the handler array to attach to the instance.
+     * @return the created {@link HandlerManager}.
+     * @throws org.apache.felix.ipojo.ConfigurationException if the instance configuration failed.
+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+     */
+    public ComponentInstance createInstance(Dictionary configuration, IPojoContext context, HandlerManager[] handlers) throws ConfigurationException {
+        HandlerManager instance = new HandlerManager(this, context, handlers);
+        instance.configure(m_componentMetadata, configuration);
+        return instance;
+    }
+
+
+    /**
+     * Computes required handlers. This method does not manipulate any
+     * non-immutable fields, so does not need to be synchronized.
+     * This method is overridden to avoid using the same detection rules
+     * than 'primitive' components. Indeed, architecture is disable by default,
+     * and a handler is never immediate.
+     * @return the required handler list.
+     */
+    public List getRequiredHandlerList() {
+        List list = new ArrayList();
+        Element[] elems = m_componentMetadata.getElements();
+        for (int i = 0; i < elems.length; i++) {
+            Element current = elems[i];
+            if (!"manipulation".equals(current.getName())) { // Remove the manipulation element
+                RequiredHandler req = new RequiredHandler(current.getName(),
+                        current.getNameSpace());
+                if (!list.contains(req)) {
+                    list.add(req);
+                }
+            }
+        }
+
+        // Unlike normal components, the architecture is enable only when
+        // specified.
+        String arch = m_componentMetadata.getAttribute("architecture");
+        if (arch != null && arch.equalsIgnoreCase("true")) {
+            list.add(new RequiredHandler("architecture", null));
+        }
+
+        // The auto-attached handler list is ignored for handlers to avoid loops.
+
+        return list;
+    }
+
+    /**
+     * Defines the handler type description.
+     * @see ComponentTypeDescription
+     */
+    private class HandlerTypeDescription extends ComponentTypeDescription {
+
+        /**
+         * Creates the HandlerTypeDescription.
+         * @param factory the factory.
+         */
+        public HandlerTypeDescription(IPojoFactory factory) {
+            super(factory);
+        }
+
+        /**
+         * Add properties to publish.
+         * <li>handler.name</li>
+         * <li>handler.namespace</li>
+         * <li>handler.type</li>
+         * <li>handler.level if the level is not Integer.MAX</li>
+         * @return returns the dictionary to publish.
+         * @see org.apache.felix.ipojo.architecture.ComponentTypeDescription#getPropertiesToPublish()
+         */
+        public Dictionary getPropertiesToPublish() {
+            Dictionary props = super.getPropertiesToPublish();
+
+            props.put(Handler.HANDLER_NAME_PROPERTY, m_factoryName);
+            props.put(Handler.HANDLER_NAMESPACE_PROPERTY, m_namespace);
+            props.put(Handler.HANDLER_TYPE_PROPERTY, m_type);
+            if (m_level != Integer.MAX_VALUE) {
+                props.put(Handler.HANDLER_LEVEL_PROPERTY, new Integer(m_level));
+            }
+            return props;
+        }
+
+        public String[] getFactoryInterfacesToPublish() {
+            return new String[] {HandlerFactory.class.getName()};
+        }
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPOJOServiceFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPOJOServiceFactory.java
new file mode 100644
index 0000000..a74f22d
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPOJOServiceFactory.java
@@ -0,0 +1,43 @@
+/* 
+ * 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;
+
+
+/**
+ * iPOJO Service Factory is a special service factory handling to get the 
+ * instance consuming the service. The mechanism is equivalent to the OSGi Service
+ * Factory.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface IPOJOServiceFactory {
+    
+    /**
+     * Gets a service object.
+     * @param instance the instance asking the for the service object.
+     * @return the service object.
+     */
+    Object getService(ComponentInstance instance);
+    
+    /**
+     * Un-gets a service object.
+     * @param instance the instance un-getting the service object.
+     * @param svcObject the service object used
+     */
+    void ungetService(ComponentInstance instance, Object svcObject);
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPOJOURLHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPOJOURLHandler.java
new file mode 100644
index 0000000..9a046ac
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPOJOURLHandler.java
@@ -0,0 +1,239 @@
+/* 
+ * 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;
+
+import org.apache.felix.ipojo.manipulator.Pojoization;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.url.URLStreamHandlerService;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+* iPOJO URL Handler allowing installation time manipulation.
+* When a bundle is installed with the <code>ipojo:</code> URL
+* prefix, the bundle is downloaded and manipulated by this 
+* handler.
+* The metadata.xml file can either be provided inside the bundle (root,
+* or in META-INF) or given in the URL:
+* ipojo:URL_BUNDLE!URL_METADATA.
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public class IPOJOURLHandler extends org.osgi.service.url.AbstractURLStreamHandlerService implements URLStreamHandlerService {
+    
+    /**
+     * The bundle context.
+     */
+    private BundleContext m_context;
+    
+    /**
+     * The directory storing bundles.
+     */
+    private File m_temp;
+    
+    /**
+     * Creates a IPOJOURLHandler.
+     * Gets the bundle context and create the working
+     * directory.
+     * @param bc the bundle context
+     */
+    public IPOJOURLHandler(BundleContext bc) {
+        m_context = bc;
+        m_temp = m_context.getDataFile("temp");
+        if (! m_temp.exists()) {
+            m_temp.mkdir();
+        }
+    }
+    
+    /**
+     * Stops the URL handler:
+     * Deletes the working directory.  
+     */
+    public void stop() {
+        File[] files = m_temp.listFiles();
+        if (files != null) {
+            for (int i = 0; i < files.length; i++) {
+                files[i].delete();
+            }
+        }
+        m_temp.delete();
+    }
+
+    /**
+     * Opens a connection using the ipojo url handler.
+     * This methods parses the URL and manipulate the given bundle.
+     * @param url the url.
+     * @return the URL connection on the manipulated bundle
+     * @throws java.io.IOException  occurs when the bundle cannot be either downloaded, or manipulated or
+     * installed correctly.
+     * @see org.osgi.service.url.AbstractURLStreamHandlerService#openConnection(java.net.URL)
+     */
+    public URLConnection openConnection(URL url) throws IOException {
+        System.out.println("Processing URL : " + url);
+
+       // Parse the url:
+        String full = url.toExternalForm();
+        // Remote ipojo://
+        if (full.startsWith("ipojo:")) {
+            full = full.substring(6);
+        }
+        // Remove '/' or '//'
+        while (full.startsWith("/")) {
+            full = full.substring(1);
+        }
+
+        full = full.trim();
+
+        // Now full is like : URL,URL or URL
+        String[] urls = full.split("!");
+        URL bundleURL = null;
+        URL metadataURL = null;
+        if (urls.length == 1) {
+            // URL form
+            System.out.println("Extracted URL : " + urls[0]);
+            bundleURL = new URL(urls[0]);
+        } else if (urls.length == 2) {
+            // URL,URL form
+            bundleURL = new URL(urls[0]);
+            metadataURL = new URL(urls[1]);
+        } else {
+            throw new MalformedURLException("The iPOJO url is not formatted correctly, ipojo:bundle_url[!metadata_url] expected");
+        }
+
+        File bundle = File.createTempFile("ipojo_", ".jar", m_temp);
+        save(bundleURL, bundle);
+        File metadata = null;
+        if (metadataURL != null) {
+            metadata = File.createTempFile("ipojo_", ".xml", m_temp);
+            save(metadataURL, metadata);
+        } else {
+            // Check that the metadata are in the jar file
+            JarFile jar = new JarFile(bundle);
+            metadata = findMetadata(jar);
+        }
+
+        // Pojoization
+        Pojoization pojoizator = new Pojoization();
+        File out =  new File(m_temp, bundle.getName() + "-ipojo.jar");
+        System.out.println("Pojoization " + bundle.exists() + " - " + metadata.exists());
+        try {
+            pojoizator.pojoization(bundle, out, metadata);
+        } catch (Exception e) {
+            if (! pojoizator.getErrors().isEmpty()) {
+                throw new IOException("Errors occured during the manipulation : " + pojoizator.getErrors());
+            }
+            e.printStackTrace();
+            throw new RuntimeException(e.getMessage());
+        }
+
+        if (! pojoizator.getErrors().isEmpty()) {
+            throw new IOException("Errors occured during the manipulation : " + pojoizator.getErrors());
+        }
+        if (! pojoizator.getWarnings().isEmpty()) {
+            System.err.println("Warnings occured during the manipulation : " + pojoizator.getWarnings());
+        }
+
+        System.out.println("Manipulation done : " + out.exists());
+
+        // Cleanup
+        bundle.delete();
+        if (metadata != null) {
+            metadata.delete();
+        }
+        out.deleteOnExit();
+        // Returns the URL Connection
+        return out.toURI().toURL().openConnection();
+
+
+    }
+
+    /**
+     * Downloads the content pointed by the given url to
+     * the given file.
+     * @param url   the url
+     * @param file  the file
+     * @throws java.io.IOException occurs if the content cannot be read
+     * and save inside the file
+     */
+    private void save(URL url, File file) throws IOException {
+        InputStream is = url.openStream();
+        save(is, file);
+    }
+
+    /**
+     * Saves the content of the input stream to the given file.
+     * @param is    the input stream to read
+     * @param file  the file
+     * @throws java.io.IOException  occurs if the content cannot be read
+     * and save inside the file
+     */
+    private void save(InputStream is, File file) throws IOException {
+        FileOutputStream writer = new FileOutputStream(file);
+        int cc = 0;
+        do {
+            int i = is.read();
+            if (i == -1) {
+                break;
+            }
+            cc++;
+            writer.write(i);
+        } while (true);
+        System.out.println(cc + " bytes copied");
+        is.close();
+        writer.close();
+    }
+
+    /**
+     * Looks for the metadata.xml file in the jar file.
+     * Two locations are checked:
+     * <ol>
+     * <li>the root of the jar file</li>
+     * <li>the META-INF directory</li>
+     * </ol>
+     * @param jar   the jar file
+     * @return  the founded file or <code>null</code> if not found.
+     * @throws java.io.IOException  occurs when the Jar file cannot be read.
+     */
+    private File findMetadata(JarFile jar) throws IOException {
+        JarEntry je = jar.getJarEntry("metadata.xml");
+        if (je == null) {
+            je = jar.getJarEntry("META-INF/metadata.xml");
+        }
+        
+        if (je == null) {
+            System.out.println("Metadata file not found, use annotations only.");
+            return null; // Not Found, use annotation only
+        } else {
+            System.out.println("Metadata file found: " + je.getName());
+            File metadata = File.createTempFile("ipojo_", ".xml", m_temp);
+            save(jar.getInputStream(je), metadata);
+            System.out.println("Metadata file saved to " + metadata.getAbsolutePath());
+            return metadata;
+        }
+        
+    }
+    
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
new file mode 100644
index 0000000..77cf3b3
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoContext.java
@@ -0,0 +1,497 @@
+/* 
+ * 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;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * The iPOJO Context is a BundleContext implementation allowing the separation
+ * between Bundle context and Service (Bundle) Context.
+ * This is used inside composition to differentiate the classloading context (i.e.
+ * Bundle) and the service registry access.
+ * This class delegates calls to the good internal context (either the BundleContext
+ * or the ServiceContext) according to the method. If the instance does not have a valid
+ * service context, the bundle context is always used. 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class IPojoContext implements BundleContext, ServiceContext {
+
+    /**
+     * The bundleContext used to access bundle methods.
+     */
+    private BundleContext m_bundleContext;
+
+    /**
+     * The service context used to access to the service registry.
+     */
+    private ServiceContext m_serviceContext;
+
+    /**
+     * Creates an iPOJO Context.
+     * No service context is specified.
+     * This constructor is used when the
+     * instance lives in the global context.
+     * @param context the bundle context
+     */
+    public IPojoContext(BundleContext context) {
+        m_bundleContext = context;
+    }
+
+    /**
+     * Creates an iPOJO Context.
+     * A service context is used to refer to the
+     * service registry. The service context will be 
+     * used for all service accesses.
+     * @param bundleContext the bundle context
+     * @param serviceContext the service context
+     */
+    public IPojoContext(BundleContext bundleContext, ServiceContext serviceContext) {
+        m_bundleContext = bundleContext;
+        m_serviceContext = serviceContext;
+    }
+
+    /**
+     * Adds a bundle listener.
+     * @param listener the listener to add
+     * @see org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void addBundleListener(BundleListener listener) {
+        m_bundleContext.addBundleListener(listener);
+    }
+
+    /**
+     * Adds a framework listener.
+     * @param listener the listener object to add
+     * @see org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void addFrameworkListener(FrameworkListener listener) {
+        m_bundleContext.addFrameworkListener(listener);
+    }
+
+    /**
+     * Adds a service listener.
+     * This methods registers the listener on the service context
+     * if it specified. Otherwise, if the internal dispatcher is enabled,
+     * it registers the listener inside the internal dispatcher (if
+     * the filter match against the iPOJO Filter format 
+     * {@link IPojoContext#match(String)}). Finally, if the internal 
+     * dispatcher is disabled, it uses the "regular" bundle context.
+     * @param listener the service listener to add.
+     * @param filter the LDAP filter
+     * @throws InvalidSyntaxException if LDAP filter is malformed
+     * @see org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener, java.lang.String)
+     */
+    public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException {
+        if (m_serviceContext == null) {
+            EventDispatcher dispatcher = EventDispatcher.getDispatcher();
+            if (dispatcher != null) { // getDispatcher returns null if not enable.
+                String itf = match(filter);
+                if (itf != null) {
+                    dispatcher.addListener(itf, listener);
+                } else {
+                    m_bundleContext.addServiceListener(listener, filter);
+                }
+            } else {
+                m_bundleContext.addServiceListener(listener, filter);
+            }
+        } else {
+            m_serviceContext.addServiceListener(listener, filter);
+        }
+    }
+
+    /**
+     * Add a service listener.
+     * This methods registers the listener on the service context
+     * if it specified. Otherwise, it uses the "regular" bundle context.
+     * @param listener the service listener to add.
+     * @see org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener)
+     */
+    public void addServiceListener(ServiceListener listener) {
+        if (m_serviceContext == null) {
+            m_bundleContext.addServiceListener(listener);
+        } else {
+            m_serviceContext.addServiceListener(listener);
+        }
+    }
+    
+    /**
+     * This method checks if the filter matches with the iPOJO
+     * filter format: <code>(OBJECTCLASS=$ITF)</code>. It tries
+     * to extract the required interface (<code>$ITF</code>).
+     * @param filter the filter to analyze
+     * @return the required interface or <code>null</code>
+     * if the filter doesn't match with the iPOJO format.
+     */
+    private String match(String filter) {
+        if (filter != null && filter.startsWith("(" + Constants.OBJECTCLASS + "=") // check the beginning (OBJECTCLASS
+            && filter.lastIndexOf(')') == filter.indexOf(')')) { // check that there is only one )
+            return filter.substring(("(" + Constants.OBJECTCLASS + "=").length(), filter.length() - 1);
+        }
+        return null;
+    }
+    
+    
+
+    /**
+     * Creates a filter objects.
+     * This method always uses the bundle context.
+     * @param filter the string form of the LDAP filter to create
+     * @return the filter object.
+     * @throws InvalidSyntaxException if the given filter is malformed
+     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
+     */
+    public Filter createFilter(String filter) throws InvalidSyntaxException {
+        return m_bundleContext.createFilter(filter);
+    }
+
+    /**
+     * Gets a bundle by symbolic name
+     * @param s the name
+     * @return the matching bundle or <code>null</code> if not found
+     */
+    public Bundle getBundle(String s) {
+        return m_bundleContext.getBundle(s);
+    }
+
+    /**
+     * Gets the service references matching with the given query.
+     * Uses the service context if specified, used the bundle context
+     * otherwise.
+     * @param clazz the required interface
+     * @param filter the LDAP filter
+     * @return the array of available service references
+     * @throws InvalidSyntaxException if the LDAP filter is malformed
+     * @see org.osgi.framework.BundleContext#getAllServiceReferences(java.lang.String, java.lang.String)
+     */
+    public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+        if (m_serviceContext == null) {
+            return m_bundleContext.getAllServiceReferences(clazz, filter);
+        } else {
+            return m_serviceContext.getAllServiceReferences(clazz, filter);
+        }
+    }
+
+    /**
+     * Gets the current bundle object.
+     * @return the bundle declaring the component type of the instance
+     * using the current IPojoContext.
+     * @see org.osgi.framework.BundleContext#getBundle()
+     */
+    public Bundle getBundle() {
+        return m_bundleContext.getBundle();
+    }
+
+    /**
+     * Gets the bundle object with the given id.
+     * @param bundleId the bundle id
+     * @return the bundle object
+     * @see org.osgi.framework.BundleContext#getBundle(long)
+     */
+    public Bundle getBundle(long bundleId) {
+        return m_bundleContext.getBundle(bundleId);
+    }
+
+    /**
+     * Gets installed bundles.
+     * @return the list of installed bundles
+     * @see org.osgi.framework.BundleContext#getBundles()
+     */
+    public Bundle[] getBundles() {
+        return m_bundleContext.getBundles();
+    }
+
+    /**
+     * Gets a data file.
+     * @param filename the file name.
+     * @return the File object
+     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
+     */
+    public File getDataFile(String filename) {
+        return m_bundleContext.getDataFile(filename);
+    }
+
+    /**
+     * Gets a property value.
+     * @param key the key of the asked property
+     * @return the property value (object) or <code>null</code> if no
+     * property are associated with the given key
+     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
+     */
+    public String getProperty(String key) {
+        return m_bundleContext.getProperty(key);
+    }
+
+    /**
+     * Gets a service object.
+     * The given service reference must come from the same context than
+     * where the service is get.
+     * This method uses the service context if specified, the bundle
+     * context otherwise.
+     * This method may throw {@link IllegalStateException} if the used bundle
+     * context is no more valid (because we're leaving).
+     * @param ref the required service reference
+     * @return the service object or <code>null</code> if the service reference 
+     * is no more valid or if the service object is not accessible.
+     * @see org.osgi.framework.BundleContext#getService(org.osgi.framework.ServiceReference)
+     */
+    public <S> S getService(ServiceReference<S> ref) {
+        if (m_serviceContext == null) {
+            return m_bundleContext.getService(ref);
+        } else {
+            return (S) m_serviceContext.getService(ref);
+        }
+    }
+
+    /**
+     * Gets a service reference for the given interface.
+     * This method uses the service context if specified, the bundle
+     * context otherwise.
+     * @param clazz the required interface name
+     * @return a service reference on a available provider or <code>null</code>
+     * if no providers available
+     * @see org.osgi.framework.BundleContext#getServiceReference(java.lang.String)
+     */
+    public ServiceReference getServiceReference(String clazz) {
+        if (m_serviceContext == null) {
+            return m_bundleContext.getServiceReference(clazz);
+        } else {
+            return m_serviceContext.getServiceReference(clazz);
+        }
+    }
+
+     /**
+     * Gets a service reference for the given interface.
+     * This method uses the service context if specified, the bundle
+     * context otherwise.
+     * @param sClass the required interface class
+     * @param <S> the service class
+     * @return a service reference on a available provider or <code>null</code>
+     * if no providers available
+     * @see org.osgi.framework.BundleContext#getServiceReference(java.lang.String)
+     */
+    public <S> ServiceReference<S> getServiceReference(Class<S> sClass) {
+        if (m_serviceContext == null) {
+            return m_bundleContext.getServiceReference(sClass);
+        } else {
+            return m_serviceContext.getServiceReference(sClass);
+        }
+    }
+
+    /**
+     * Gets service reference list for the given query.
+     * This method uses the service context if specified, the bundle
+     * context otherwise.
+     * @param sClass the name of the required service interface
+     * @param filter the LDAP filter to apply on service provider
+     * @param <S> the service class
+     *  @return the array of consistent service reference or <code>null</code>
+     * if no available providers
+     * @throws InvalidSyntaxException if the LDAP filter is malformed
+     */
+    public <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> sClass, String filter) throws InvalidSyntaxException {
+        if (m_serviceContext == null) {
+            return m_bundleContext.getServiceReferences(sClass, filter);
+        } else {
+            return m_serviceContext.getServiceReferences(sClass, filter);
+        }
+    }
+
+    /**
+     * Gets service reference list for the given query.
+     * This method uses the service context if specified, the bundle
+     * context otherwise.
+     * @param clazz the name of the required service interface
+     * @param filter the LDAP filter to apply on service provider
+     * @return the array of consistent service reference or <code>null</code>
+     * if no available providers
+     * @throws InvalidSyntaxException if the LDAP filter is malformed
+     * @see org.osgi.framework.BundleContext#getServiceReferences(java.lang.String, java.lang.String)
+     */
+    public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+        if (m_serviceContext == null) {
+            return m_bundleContext.getServiceReferences(clazz, filter);
+        } else {
+            return m_serviceContext.getServiceReferences(clazz, filter);
+        }
+    }
+
+    /**
+     * Installs a bundle.
+     * @param location the URL of the bundle to install
+     * @return the installed bundle
+     * @throws BundleException if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
+     */
+    public Bundle installBundle(String location) throws BundleException {
+        return m_bundleContext.installBundle(location);
+    }
+
+    /**
+     * Installs a bundle.
+     * @param location the URL of the bundle to install
+     * @param input the input stream to load the bundle.
+     * @return the installed bundle
+     * @throws BundleException  if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, java.io.InputStream)
+     */
+    public Bundle installBundle(String location, InputStream input) throws BundleException {
+        return m_bundleContext.installBundle(location, input);
+    }
+
+    /**
+     * Registers a service.
+     * This method uses the service context if specified (and so, registers
+     * the service in this service registry), the bundle context otherwise (the
+     * service will be available to every global instances).
+     * @param clazzes the interfaces provided by the service.
+     * @param service the service object.
+     * @param properties the service properties to publish
+     * @return the service registration for this service publication.
+     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
+     */
+    public ServiceRegistration registerService(String[] clazzes, Object service, Dictionary properties) {
+        if (m_serviceContext == null) {
+            return m_bundleContext.registerService(clazzes, service, properties);
+        } else {
+            return m_serviceContext.registerService(clazzes, service, properties);
+        }
+    }
+
+    /**
+     * Registers a service.
+     * This method uses the service context if specified (and so, registers
+     * the service in this service registry), the bundle context otherwise (the
+     * service will be available to every global instances).
+     * @param clazz the interface provided by the service.
+     * @param service the the service object.
+     * @param properties the service properties to publish.
+     * @return the service registration for this service publication.
+     * @see org.osgi.framework.BundleContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
+     */
+    public ServiceRegistration registerService(String clazz, Object service, Dictionary properties) {
+        if (m_serviceContext == null) {
+            return m_bundleContext.registerService(clazz, service, properties);
+        } else {
+            return m_serviceContext.registerService(clazz, service, properties);
+        }
+    }
+
+    /**
+     * Removes a bundle listener.
+     * @param listener the listener to remove
+     * @see org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void removeBundleListener(BundleListener listener) {
+        m_bundleContext.removeBundleListener(listener);
+    }
+
+    /**
+     * Removes a framework listener.
+     * @param listener the listener to remove
+     * @see org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void removeFrameworkListener(FrameworkListener listener) {
+        m_bundleContext.removeFrameworkListener(listener);
+    }
+
+    /**
+     * Registers a service
+     * @param sClass  the service class
+     * @param s the service object (must implement sClass)
+     * @param stringDictionary service properties
+     * @param <S> the Service Class (specification)
+     * @return the service registration
+     */
+    public <S> ServiceRegistration<S> registerService(Class<S> sClass, S s, Dictionary<String, ?> stringDictionary) {
+        if (m_serviceContext == null) {
+            return m_bundleContext.registerService(sClass, s, stringDictionary);
+        } else {
+            return m_serviceContext.registerService(sClass, s, stringDictionary);
+        }
+    }
+
+    /**
+     * Removes a service listener.
+     * Removes the service listener from where it was registered so either in
+     * the global context, or in the service context or in the internal dispatcher.
+     * @param listener the service listener to remove
+     * @see org.apache.felix.ipojo.ServiceContext#removeServiceListener(org.osgi.framework.ServiceListener)
+     * @see org.osgi.framework.BundleContext#removeServiceListener(org.osgi.framework.ServiceListener)
+     */
+    public void removeServiceListener(ServiceListener listener) {
+        if (m_serviceContext == null) {
+            EventDispatcher dispatcher = EventDispatcher.getDispatcher();
+            if (dispatcher == null || ! dispatcher.removeListener(listener)) {
+                m_bundleContext.removeServiceListener(listener);
+            }
+        } else {
+            m_serviceContext.removeServiceListener(listener);
+        }
+    }
+
+    /**
+     * Ungets the service reference.
+     * This method uses the service context if specified, 
+     * the bundle context otherwise.
+     * @param reference the reference to unget
+     * @return <code>true</code> if you are the last user of the reference
+     * @see org.osgi.framework.BundleContext#ungetService(org.osgi.framework.ServiceReference)
+     */
+    public boolean ungetService(ServiceReference reference) {
+        if (m_serviceContext == null) {
+            return m_bundleContext.ungetService(reference);
+        } else {
+            return m_serviceContext.ungetService(reference);
+        }
+    }
+
+    /**
+     * Gets the global context, i.e. the bundle context of the factory.
+     * @return the global bundle context.
+     */
+    public BundleContext getGlobalContext() {
+        return m_bundleContext;
+    }
+
+    /**
+     * Gets the service context, i.e. the composite context.
+     * Returns <code>null</code> if the instance does not live
+     * inside a composite.
+     * @return the service context or <code>null</code>.
+     */
+    public ServiceContext getServiceContext() {
+        return m_serviceContext;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
new file mode 100644
index 0000000..511ea30
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/IPojoFactory.java
@@ -0,0 +1,1009 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.SecurityHelper;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+/**
+ * This class defines common mechanisms of iPOJO component factories
+ * (i.e. component type).
+ * This class implements both the Factory and ManagedServiceFactory
+ * services.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class IPojoFactory implements Factory, ManagedServiceFactory {
+    /*
+     * TODO there is potentially an issue when calling FactoryStateListener callbacks with the lock
+     * It should be called by a separate thread dispatching events to listeners.
+     */
+
+    /**
+     * The list of the managed instance name.
+     * This list is shared by all factories and is
+     * used to assert name unicity.
+     */
+    protected static final List INSTANCE_NAME = new ArrayList();
+
+    /**
+     * The component type description exposed by the {@link Factory} service.
+     */
+    protected ComponentTypeDescription m_componentDesc;
+
+    /**
+     * The list of the managed instance managers.
+     * The key of this map is the name (i.e. instance names) of the created instance
+     */
+    protected final Map m_componentInstances = new HashMap();
+
+    /**
+     * The component type metadata.
+     */
+    protected final Element m_componentMetadata;
+
+    /**
+     * The bundle context reference.
+     */
+    protected final BundleContext m_context;
+
+    /**
+     * The factory name.
+     * Could be the component class name if the factory name is not set.
+     * Immutable once set.
+     */
+    protected String m_factoryName;
+
+    /**
+     * The list of required handlers.
+     */
+    protected List m_requiredHandlers = new ArrayList();
+
+    /**
+     * The list of factory state listeners.
+     * @see FactoryStateListener
+     */
+    protected List m_listeners = new ArrayList(1);
+
+    /**
+     * The logger for the factory.
+     */
+    protected final Logger m_logger;
+
+    /**
+     * Is the factory public (exposed as services).
+     */
+    protected final boolean m_isPublic;
+
+    /**
+     * The version of the component type.
+     */
+    protected final String m_version;
+
+    /**
+     * The service registration of this factory (Factory & ManagedServiceFactory).
+     * @see ManagedServiceFactory
+     * @see Factory
+     */
+    protected ServiceRegistration m_sr;
+
+    /**
+     * The factory state.
+     * Can be:
+     * <li>{@link Factory#INVALID}</li>
+     * <li>{@link Factory#VALID}</li>
+     * The factory is invalid at the beginning.
+     * A factory becomes valid if every required handlers
+     * are available (i.e. can be created).
+     */
+    protected int m_state = Factory.INVALID;
+
+    /**
+     * The index used to generate instance name if not set.
+     */
+    private long m_index = 0;
+
+    /**
+     * The flag indicating if this factory has already a
+     * computed description or not.
+     */
+    private boolean m_described;
+
+    /**
+     * Creates an iPOJO Factory.
+     * At the end of this method, the required set of handler is computed.
+     * But the result is computed by a sub-class.
+     * @param context the bundle context of the bundle containing the factory.
+     * @param metadata the description of the component type.
+     * @throws ConfigurationException if the element describing the factory is malformed.
+     */
+    public IPojoFactory(BundleContext context, Element metadata) throws ConfigurationException {
+        m_context = context;
+        m_componentMetadata = metadata;
+        m_factoryName = getFactoryName();
+        String fac = metadata.getAttribute("public");
+        m_isPublic = fac == null || !fac.equalsIgnoreCase("false");
+        m_logger = new Logger(m_context, m_factoryName);
+
+        // Compute the component type version.
+        String version = metadata.getAttribute("version");
+        if ("bundle".equalsIgnoreCase(version)) { // Handle the "bundle" constant: use the bundle version.
+            m_version = (String) m_context.getBundle().getHeaders().get(Constants.BUNDLE_VERSION);
+        } else {
+            m_version = version;
+        }
+
+        m_requiredHandlers = getRequiredHandlerList(); // Call sub-class to get the list of required handlers.
+
+        m_logger.log(Logger.INFO, "New factory created : " + m_factoryName);
+    }
+
+    /**
+     * Gets the component type description.
+     * @return the component type description
+     */
+    public ComponentTypeDescription getComponentTypeDescription() {
+        return new ComponentTypeDescription(this);
+    }
+
+    /**
+     * Adds a factory listener.
+     * @param listener the factory listener to add.
+     * @see org.apache.felix.ipojo.Factory#addFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void addFactoryStateListener(FactoryStateListener listener) {
+        synchronized (this) {
+            m_listeners.add(listener);
+        }
+    }
+
+    /**
+     * Gets the logger used by instances created by the current factory.
+     * @return the factory logger.
+     */
+    public Logger getLogger() {
+        return m_logger;
+    }
+
+    /**
+     * Computes the factory name.
+     * Each sub-type must override this method.
+     * @return the factory name.
+     */
+    public abstract String getFactoryName();
+
+    /**
+     * Computes the required handler list.
+     * Each sub-type must override this method.
+     * @return the required handler list
+     */
+    public abstract List getRequiredHandlerList();
+
+    /**
+     * Creates an instance.
+     * This method is called with the monitor lock.
+     * @param config the instance configuration
+     * @param context the iPOJO context to use
+     * @param handlers the handler array to use
+     * @return the new component instance.
+     * @throws ConfigurationException if the instance creation failed during the configuration process.
+     */
+    public abstract ComponentInstance createInstance(Dictionary config, IPojoContext context, HandlerManager[] handlers)
+        throws ConfigurationException;
+
+    /**
+     * Creates an instance.
+     * This method creates the instance in the global context.
+     * @param configuration the configuration of the created instance.
+     * @return the created component instance.
+     * @throws UnacceptableConfiguration if the given configuration is not consistent with the component type of this factory.
+     * @throws MissingHandlerException if an handler is unavailable when the instance is created.
+     * @throws org.apache.felix.ipojo.ConfigurationException if the instance or type configuration are not correct.
+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+     */
+    public ComponentInstance createComponentInstance(Dictionary configuration) throws UnacceptableConfiguration, MissingHandlerException,
+            ConfigurationException {
+        return createComponentInstance(configuration, null);
+    }
+
+    /**
+     * Creates an instance in the specified service context.
+     * This method is synchronized to assert the validity of the factory during the creation.
+     * Callbacks to sub-class and  created instances need to be aware that they are holding the monitor lock.
+     * This method call the override {@link IPojoFactory#createInstance(Dictionary, IPojoContext, HandlerManager[])
+     * method.
+     * @param configuration the configuration of the created instance.
+     * @param serviceContext the service context to push for this instance.
+     * @return the created component instance.
+     * @throws UnacceptableConfiguration if the given configuration is not consistent with the component type of this factory.
+     * @throws MissingHandlerException if an handler is unavailable when creating the instance.
+     * @throws org.apache.felix.ipojo.ConfigurationException if the instance configuration failed.
+     * @see org.apache.felix.ipojo.Factory#createComponentInstance(java.util.Dictionary)
+     */
+    public synchronized ComponentInstance createComponentInstance(Dictionary configuration, ServiceContext serviceContext) throws UnacceptableConfiguration, // NOPMD
+            MissingHandlerException, ConfigurationException {
+        if (configuration == null) {
+            configuration = new Properties();
+        }
+
+        IPojoContext context = null;
+        if (serviceContext == null) {
+            context = new IPojoContext(m_context);
+        } else {
+            context = new IPojoContext(m_context, serviceContext);
+        }
+
+        try {
+            checkAcceptability(configuration);
+        } catch (UnacceptableConfiguration e) {
+            m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+            throw new UnacceptableConfiguration("The configuration "
+                    + configuration + " is not acceptable for " + m_factoryName
+                    + ": " + e.getMessage());
+        }
+
+        String name;
+        if (configuration.get("instance.name") == null && configuration.get("name") == null) { // Support both instance.name & name
+            name = generateName();
+            configuration.put("instance.name", name);
+        } else {
+            name = (String) configuration.get("instance.name");
+            if (name == null) {
+                name = (String) configuration.get("name");
+                getLogger().log(Logger.WARNING, "The 'name' (" + name + ") attribute, used as the instance name, is deprecated, please use the 'instance.name' attribute");
+                configuration.put("instance.name", name);
+            }
+            if (INSTANCE_NAME.contains(name)) {
+                m_logger.log(Logger.ERROR, "The configuration is not acceptable : Name already used");
+                throw new UnacceptableConfiguration(getFactoryName() + " : Name already used : " + name);
+            }
+        }
+        // Here we are sure to be valid until the end of the method.
+        HandlerManager[] handlers = new HandlerManager[m_requiredHandlers.size()];
+        for (int i = 0; i < handlers.length; i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            handlers[i] = getHandler(req, serviceContext);
+        }
+
+        try {
+            ComponentInstance instance = createInstance(configuration, context, handlers); // This method is called with the lock.
+            INSTANCE_NAME.add(name);
+            m_componentInstances.put(name, instance);
+            m_logger.log(Logger.INFO, "Instance " + name + " from factory " + m_factoryName + " created");
+            return instance;
+        } catch (ConfigurationException e) {
+            m_logger.log(Logger.ERROR, e.getMessage());
+            throw new ConfigurationException(e.getMessage(), m_factoryName);
+        }
+
+
+    }
+
+    /**
+     * Gets the bundle context of the factory.
+     * @return the bundle context of the factory.
+     * @see org.apache.felix.ipojo.Factory#getBundleContext()
+     */
+    public BundleContext getBundleContext() {
+        return m_context;
+    }
+
+    /**
+     * Gets the factory class name.
+     * @return the factory class name.
+     * @see org.apache.felix.ipojo.Factory#getClassName()
+     */
+    public abstract String getClassName();
+
+    /**
+     * Gets the component type description.
+     * @return the component type description object. <code>Null</code> if not already computed.
+     */
+    public synchronized ComponentTypeDescription getComponentDescription() {
+        return m_componentDesc;
+    }
+
+    /**
+     * Gets the component type description (Element-Attribute form).
+     * @return the component type description.
+     * @see org.apache.felix.ipojo.Factory#getDescription()
+     */
+    public synchronized Element getDescription() {
+        // Can be null, if not already computed.
+        if (m_componentDesc == null) {
+            return new Element("No description available for " + m_factoryName, "");
+        }
+        return m_componentDesc.getDescription();
+    }
+
+    /**
+     * Gets the component metadata.
+     * @return the component metadata
+     * @see org.apache.felix.ipojo.Factory#getComponentMetadata()
+     */
+    public Element getComponentMetadata() {
+        return m_componentMetadata;
+    }
+
+    /**
+     * Computes the list of missing handlers. This method is called with the monitor lock.
+     * @return the list of missing handlers.
+     * @see org.apache.felix.ipojo.Factory#getMissingHandlers()
+     */
+    public List getMissingHandlers() {
+        List list = new ArrayList();
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            if (req.getReference() == null) {
+                list.add(req.getFullName());
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Gets the factory name.
+     * This name is immutable once set.
+     * @return the factory name.
+     * @see org.apache.felix.ipojo.Factory#getName()
+     */
+    public String getName() {
+        return m_factoryName;
+    }
+
+    /**
+     * Gets the list of required handlers.
+     * This method is synchronized to avoid the concurrent modification
+     * of the required handlers.
+     * @return the list of required handlers.
+     * @see org.apache.felix.ipojo.Factory#getRequiredHandlers()
+     */
+    public synchronized List getRequiredHandlers() {
+        List list = new ArrayList();
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            list.add(req.getFullName());
+        }
+        return list;
+    }
+
+    /**
+     * Gets the actual factory state.
+     * Must be synchronized as this state is dependent of handler availability.
+     * @return the actual factory state.
+     * @see org.apache.felix.ipojo.Factory#getState()
+     */
+    public synchronized int getState() {
+        return m_state;
+    }
+
+    /**
+     * Checks if the configuration is acceptable.
+     * @param conf the configuration to test.
+     * @return <code>true</code> if the configuration is acceptable.
+     * @see org.apache.felix.ipojo.Factory#isAcceptable(java.util.Dictionary)
+     */
+    public boolean isAcceptable(Dictionary conf) {
+        try {
+            checkAcceptability(conf);
+        } catch (MissingHandlerException e) {
+            return false;
+        } catch (UnacceptableConfiguration e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Checks if the configuration is acceptable.
+     * This method checks the following assertions:
+     * <li>All handlers can be creates</li>
+     * <li>The configuration does not override immutable properties</li>
+     * <li>The configuration contains a value for every unvalued property</li>
+     * @param conf the configuration to test.
+     * @throws UnacceptableConfiguration if the configuration is unacceptable.
+     * @throws MissingHandlerException if an handler is missing.
+     */
+    public void checkAcceptability(Dictionary conf) throws UnacceptableConfiguration, MissingHandlerException {
+        PropertyDescription[] props;
+        synchronized (this) {
+            if (m_state == Factory.INVALID) {
+                throw new MissingHandlerException(getMissingHandlers());
+            }
+            props = m_componentDesc.getProperties(); // Stack confinement.
+            // The property list is up to date, as the factory is valid.
+        }
+
+        // Check that the configuration does not override immutable properties.
+
+        for (int i = 0; i < props.length; i++) {
+            // Is the property immutable
+            if (props[i].isImmutable() && conf.get(props[i].getName()) != null) {
+                throw new UnacceptableConfiguration("The property " + props[i] + " cannot be overide : immutable property"); // The instance configuration tries to override an immutable property.
+            }
+            // Is the property required ?
+            if (props[i].isMandatory() && props[i].getValue() == null && conf.get(props[i].getName()) == null) {
+                throw new UnacceptableConfiguration("The mandatory property " + props[i].getName() + " is missing"); // The property must be set.
+            }
+        }
+    }
+
+    /**
+     * Reconfigures an existing instance.
+     * The acceptability of the configuration is checked before the reconfiguration. Moreover,
+     * the configuration must contain the 'instance.name' property specifying the instance
+     * to reconfigure.
+     * This method is synchronized to assert the validity of the factory during the reconfiguration.
+     * @param properties the new configuration to push.
+     * @throws UnacceptableConfiguration if the new configuration is not consistent with the component type.
+     * @throws MissingHandlerException if the current factory is not valid.
+     * @see org.apache.felix.ipojo.Factory#reconfigure(java.util.Dictionary)
+     */
+    public synchronized void reconfigure(Dictionary properties) throws UnacceptableConfiguration, MissingHandlerException {
+        if (properties == null || (properties.get("instance.name") == null && properties.get("name") == null)) { // Support both instance.name and name
+            throw new UnacceptableConfiguration("The configuration does not contains the \"instance.name\" property");
+        }
+
+        String name = (String) properties.get("instance.name");
+        if (name == null) {
+            name = (String) properties.get("name");
+        }
+
+        ComponentInstance instance = (ComponentInstance) m_componentInstances.get(name);
+        if (instance == null) { // The instance does not exists.
+            return;
+        }
+
+        checkAcceptability(properties); // Test if the configuration is acceptable
+        instance.reconfigure(properties); // re-configure the instance
+    }
+
+    /**
+     * Removes a factory listener.
+     * @param listener the factory listener to remove.
+     * @see org.apache.felix.ipojo.Factory#removeFactoryStateListener(org.apache.felix.ipojo.FactoryStateListener)
+     */
+    public void removeFactoryStateListener(FactoryStateListener listener) {
+        synchronized (this) {
+            m_listeners.remove(listener);
+        }
+    }
+
+    /**
+     * Stopping method.
+     * This method is call when the factory is stopping.
+     * This method is called when holding the lock on the factory.
+     */
+    public abstract void stopping();
+
+    /**
+     * Stops all the instance managers.
+     * This method calls the {@link IPojoFactory#stopping()} method,
+     * notifies listeners, and disposes created instances. Moreover,
+     * if the factory is public, services are also unregistered.
+     *
+     */
+    public synchronized void stop() {
+        ComponentInstance[] instances;
+        if (m_sr != null) {
+            m_sr.unregister();
+            m_sr = null;
+        }
+        stopping(); // Method called when holding the lock.
+        m_state = INVALID; // Set here to avoid to create instances during the stops.
+
+        Set col = m_componentInstances.keySet();
+        Iterator it = col.iterator();
+        instances = new ComponentInstance[col.size()]; // Stack confinement
+        int index = 0;
+        while (it.hasNext()) {
+            instances[index] = (ComponentInstance) (m_componentInstances.get(it.next()));
+            index++;
+        }
+
+        if (m_state == VALID) {
+            for (int i = 0; i < m_listeners.size(); i++) {
+                ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
+            }
+        }
+
+        // Dispose created instances.
+        for (int i = 0; i < instances.length; i++) {
+            ComponentInstance instance = instances[i];
+            if (instance.getState() != ComponentInstance.DISPOSED) {
+                instance.dispose();
+            }
+        }
+
+        // Release each handler
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            ((RequiredHandler) m_requiredHandlers.get(i)).unRef();
+        }
+        m_described = false;
+        m_componentDesc = null;
+        m_componentInstances.clear();
+
+        m_logger.log(Logger.INFO, "Factory " + m_factoryName + " stopped");
+
+    }
+
+    /**
+     * Destroys the factory.
+     * The factory cannot be restarted. Only the {@link Extender} can call this method.
+     */
+    synchronized void dispose() {
+        stop(); // Does not hold the lock.
+        m_requiredHandlers = null;
+        m_listeners = null;
+    }
+
+    /**
+     * Starting method.
+     * This method is called when the factory is starting.
+     * This method is called when holding the lock on the factory.
+     */
+    public abstract void starting();
+
+    /**
+     * Starts the factory.
+     * Tries to compute the component type description,
+     * calls the {@link IPojoFactory#starting()} method,
+     * and published services if the factory is public.
+     */
+    public synchronized void start() {
+        if (m_described) { // Already started.
+            return;
+        }
+
+        m_componentDesc = getComponentTypeDescription();
+
+        starting();
+
+        computeFactoryState();
+
+        if (m_isPublic) {
+            // Exposition of the factory service
+            BundleContext bc = SecurityHelper.selectContextToRegisterServices(m_componentDesc.getFactoryInterfacesToPublish(),
+                    m_context, getIPOJOBundleContext());
+            m_sr =
+                    bc.registerService(m_componentDesc.getFactoryInterfacesToPublish(), this, m_componentDesc
+                            .getPropertiesToPublish());
+        }
+
+        m_logger.log(Logger.INFO, "Factory " + m_factoryName + " started");
+
+    }
+
+    /**
+     * For testing purpose <b>ONLY</b>.
+     * This method recomputes the required handler list.
+     */
+    public void restart() {
+    	// Call sub-class to get the list of required handlers.
+        m_requiredHandlers = getRequiredHandlerList();
+    }
+
+    /**
+     * Gets the iPOJO Bundle Context.
+     * @return the iPOJO Bundle Context
+     */
+    protected final BundleContext getIPOJOBundleContext() {
+        return Extender.getIPOJOBundleContext();
+    }
+
+    /**
+     * Creates or updates an instance.
+     * @param name the name of the instance
+     * @param properties the new configuration of the instance
+     * @throws org.osgi.service.cm.ConfigurationException if the configuration is not consistent for this component type
+     * @see org.osgi.service.cm.ManagedServiceFactory#updated(java.lang.String, java.util.Dictionary)
+     */
+    public void updated(String name, Dictionary properties) throws org.osgi.service.cm.ConfigurationException {
+        ComponentInstance instance;
+        synchronized (this) {
+            instance = (ComponentInstance) m_componentInstances.get(name);
+        }
+
+        if (instance == null) {
+            try {
+                properties.put("instance.name", name); // Add the name in the configuration
+                // If an instance with this name was created before, this creation will failed.
+                createComponentInstance(properties);
+            } catch (UnacceptableConfiguration e) {
+                m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());
+            } catch (MissingHandlerException e) {
+                m_logger.log(Logger.ERROR, "Handler not available : " + e.getMessage());
+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());
+            } catch (ConfigurationException e) {
+                m_logger.log(Logger.ERROR, "The Component Type metadata are not correct : " + e.getMessage());
+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());
+            }
+        } else {
+            try {
+                properties.put("instance.name", name); // Add the name in the configuration
+                reconfigure(properties); // re-configure the component
+            } catch (UnacceptableConfiguration e) {
+                m_logger.log(Logger.ERROR, "The configuration is not acceptable : " + e.getMessage());
+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());
+            } catch (MissingHandlerException e) {
+                m_logger.log(Logger.ERROR, "The factory is not valid, at least one handler is missing : " + e.getMessage());
+                throw new org.osgi.service.cm.ConfigurationException(properties.toString(), e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Deletes an instance.
+     * @param name the name of the instance to delete
+     * @see org.osgi.service.cm.ManagedServiceFactory#deleted(java.lang.String)
+     */
+    public synchronized void deleted(String name) {
+        INSTANCE_NAME.remove(name);
+        ComponentInstance instance = (ComponentInstance) m_componentInstances.remove(name);
+        if (instance != null) {
+            instance.dispose();
+        }
+    }
+
+    /**
+     * Callback called by instance when disposed.
+     * @param instance the destroyed instance
+     */
+    public void disposed(ComponentInstance instance) {
+        String name = instance.getInstanceName();
+        synchronized (this) {
+            INSTANCE_NAME.remove(name);
+            m_componentInstances.remove(name);
+        }
+    }
+
+    /**
+     * Computes the component type description.
+     * To do this, it creates a 'ghost' instance of the handler
+     * and calls the {@link Handler#initializeComponentFactory(ComponentTypeDescription, Element)}
+     * method. The handler instance is then deleted.
+     * The factory must be valid when calling this method.
+     * This method is called with the lock.
+     */
+    protected void computeDescription() {
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            Handler handler = getHandler(req, null).getHandler();
+            try {
+                handler.setFactory(this);
+                handler.initializeComponentFactory(m_componentDesc, m_componentMetadata);
+                ((Pojo) handler).getComponentInstance().dispose();
+            } catch (org.apache.felix.ipojo.ConfigurationException e) {
+                ((Pojo) handler).getComponentInstance().dispose();
+                m_logger.log(Logger.ERROR, e.getMessage());
+                stop();
+                throw new IllegalStateException(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Computes factory state.
+     * The factory is valid if every required handler are available.
+     * If the factory becomes valid for the first time, the component
+     * type description is computed.
+     * This method is called when holding the lock on the current factory.
+     */
+    protected void computeFactoryState() {
+        boolean isValid = true;
+        for (int i = 0; i < m_requiredHandlers.size(); i++) {
+            RequiredHandler req = (RequiredHandler) m_requiredHandlers.get(i);
+            if (req.getReference() == null) {
+                isValid = false;
+                break;
+            }
+
+        }
+
+        if (isValid) {
+            if (m_state == INVALID) {
+
+                if (!m_described) {
+                    computeDescription();
+                    m_described = true;
+                }
+
+                m_state = VALID;
+                if (m_sr != null) {
+                    m_sr.setProperties(m_componentDesc.getPropertiesToPublish());
+                }
+                for (int i = 0; i < m_listeners.size(); i++) {
+                    ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, VALID);
+                }
+                return;
+            }
+        } else {
+            if (m_state == VALID) {
+                m_state = INVALID;
+
+                // Notify listeners.
+                for (int i = 0; i < m_listeners.size(); i++) {
+                    ((FactoryStateListener) m_listeners.get(i)).stateChanged(this, INVALID);
+                }
+
+                // Dispose created instances.
+                Set col = m_componentInstances.keySet();
+                String[] keys = (String[]) col.toArray(new String[col.size()]);
+                for (int i = 0; i < keys.length; i++) {
+                    ComponentInstance instance = (ComponentInstance) m_componentInstances.get(keys[i]);
+                    if (instance.getState() != ComponentInstance.DISPOSED) {
+                        instance.dispose();
+                    }
+                    INSTANCE_NAME.remove(instance.getInstanceName());
+                }
+
+                m_componentInstances.clear();
+
+                if (m_sr != null) {
+                    m_sr.setProperties(m_componentDesc.getPropertiesToPublish());
+                }
+
+                return;
+            }
+        }
+    }
+
+    /**
+     * Checks if the given handler identifier and the service reference match.
+     * Does not need to be synchronized as the method does not use any fields.
+     * @param req the handler identifier.
+     * @param ref the service reference.
+     * @return <code>true</code> if the service reference can fulfill the handler requirement
+     */
+    protected boolean match(RequiredHandler req, ServiceReference ref) {
+        String name = (String) ref.getProperty(Handler.HANDLER_NAME_PROPERTY);
+        String namespace = (String) ref.getProperty(Handler.HANDLER_NAMESPACE_PROPERTY);
+        if (HandlerFactory.IPOJO_NAMESPACE.equals(namespace)) {
+            return name.equalsIgnoreCase(req.getName()) && req.getNamespace() == null;
+        }
+        return name.equalsIgnoreCase(req.getName()) && namespace.equalsIgnoreCase(req.getNamespace());
+    }
+
+    /**
+     * Returns the handler object for the given required handler.
+     * The handler is instantiated in the given service context.
+     * This method is called with the lock.
+     * @param req the handler to create.
+     * @param context the service context in which the handler is created (same as the instance context).
+     * @return the handler object.
+     */
+    protected HandlerManager getHandler(RequiredHandler req, ServiceContext context) {
+        try {
+            return (HandlerManager) req.getFactory().createComponentInstance(null, context);
+        } catch (MissingHandlerException e) {
+            m_logger.log(Logger.ERROR, "The creation of the handler " + req.getFullName() + " has failed: " + e.getMessage());
+            stop();
+            return null;
+        } catch (UnacceptableConfiguration e) {
+            m_logger.log(Logger.ERROR, "The creation of the handler "
+                    + req.getFullName()
+                    + " has failed (UnacceptableConfiguration): "
+                    + e.getMessage());
+            stop();
+            return null;
+        } catch (org.apache.felix.ipojo.ConfigurationException e) {
+            m_logger.log(Logger.ERROR, "The configuration of the handler "
+                    + req.getFullName()
+                    + " has failed (ConfigurationException): "
+                    + e.getMessage());
+            stop();
+            return null;
+        }
+    }
+
+    /**
+     * Helper method generating a new unique name.
+     * This method is call when holding the lock to assert generated name unicity.
+     * @return a non already used name
+     */
+    protected String generateName() {
+        String name = m_factoryName + "-" + m_index;
+        while (INSTANCE_NAME.contains(name)) {
+            m_index = m_index + 1;
+            name = m_factoryName + "-" + m_index;
+        }
+        return name;
+    }
+
+    /**
+     * Structure storing required handlers.
+     * Access to this class must mostly be with the lock on the factory.
+     * (except to access final fields)
+     */
+    protected class RequiredHandler implements Comparable {
+        /**
+         * The factory to create this handler.
+         */
+        private HandlerFactory m_factory;
+
+        /**
+         * The handler name.
+         */
+        private final String m_name;
+
+        /**
+         * The handler start level.
+         */
+        private int m_level = Integer.MAX_VALUE;
+
+        /**
+         * The handler namespace.
+         */
+        private final String m_namespace;
+
+        /**
+         * The Service Reference of the handler factory.
+         */
+        private ServiceReference m_reference;
+
+        /**
+         * Crates a Required Handler.
+         * @param name the handler name.
+         * @param namespace the handler namespace.
+         */
+        public RequiredHandler(String name, String namespace) {
+            m_name = name;
+            m_namespace = namespace;
+        }
+
+        /**
+         * Equals method.
+         * Two handlers are equals if they have same name and namespace or they share the same service reference.
+         * @param object the object to compare to the current object.
+         * @return <code>true</code> if the two compared object are equals
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        public boolean equals(Object object) {
+            if (object instanceof RequiredHandler) {
+                RequiredHandler req = (RequiredHandler) object;
+                if (m_namespace == null) {
+                    return req.m_name.equalsIgnoreCase(m_name) && req.m_namespace == null;
+                } else {
+                    return req.m_name.equalsIgnoreCase(m_name) && m_namespace.equalsIgnoreCase(req.m_namespace);
+                }
+            } else {
+                return false;
+            }
+
+        }
+
+        /**
+         * Hashcode method.
+         * This method delegates to the {@link Object#hashCode()}.
+         * @return the object hashcode.
+         * @see java.lang.Object#hashCode()
+         */
+        public int hashCode() {
+            return super.hashCode();
+        }
+
+        /**
+         * Gets the factory object used for this handler.
+         * The object is get when used for the first time.
+         * This method is called with the lock avoiding concurrent modification and on a valid factory.
+         * @return the factory object.
+         */
+        public HandlerFactory getFactory() {
+            if (m_reference == null) {
+                return null;
+            }
+            if (m_factory == null) {
+                m_factory = (HandlerFactory) m_context.getService(getReference());
+            }
+            return m_factory;
+        }
+
+        /**
+         * Gets the handler qualified name (<code>namespace:name</code>).
+         * @return the handler full name
+         */
+        public String getFullName() {
+            if (m_namespace == null) {
+                return HandlerFactory.IPOJO_NAMESPACE + ":" + m_name;
+            } else {
+                return m_namespace + ":" + m_name;
+            }
+        }
+
+        public String getName() {
+            return m_name;
+        }
+
+        public String getNamespace() {
+            return m_namespace;
+        }
+
+        public ServiceReference getReference() {
+            return m_reference;
+        }
+
+        public int getLevel() {
+            return m_level;
+        }
+
+        /**
+         * Releases the reference of the used factory.
+         * This method is called with the lock on the current factory.
+         */
+        public void unRef() {
+            if (m_reference != null) {
+                m_factory = null;
+                m_reference = null;
+            }
+        }
+
+        /**
+         * Sets the service reference. If the new service reference is <code>null</code>, it ungets the used factory (if already get).
+         * This method is called with the lock on the current factory.
+         * @param ref the new service reference.
+         */
+        public void setReference(ServiceReference ref) {
+            m_reference = ref;
+            Integer level = (Integer) m_reference.getProperty(Handler.HANDLER_LEVEL_PROPERTY);
+            if (level != null) {
+                m_level = level.intValue();
+            }
+        }
+
+        /**
+         * Start level Comparison.
+         * This method is used to sort the handler array.
+         * This method is called with the lock.
+         * @param object the object on which compare.
+         * @return <code>-1</code>, <code>0</code>, <code>+1</code> according to the comparison of their start levels.
+         * @see java.lang.Comparable#compareTo(java.lang.Object)
+         */
+        public int compareTo(Object object) {
+            if (object instanceof RequiredHandler) {
+                RequiredHandler req = (RequiredHandler) object;
+                if (this.m_level == req.m_level) {
+                    return 0;
+                } else if (this.m_level < req.m_level) {
+                    return -1;
+                } else {
+                    return +1;
+                }
+            }
+            return 0;
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
new file mode 100644
index 0000000..25b0cce
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceCreator.java
@@ -0,0 +1,369 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The instance creator creates instances and tracks their factories.
+ * It allows creating instances from external factories.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class InstanceCreator implements FactoryStateListener {
+
+    /**
+     * The logger to log messages if errors occur.
+     */
+    private Logger m_logger;
+
+    /**
+     * The configurations to create and to maintain.
+     */
+    private List m_idle = new ArrayList();
+
+    /**
+     * The map storing created instances.
+     * This map contains [AbstractFactory, List [ManagedInstance]] couples.
+     */
+    private Map m_attached = new HashMap();
+
+    /**
+     * The abstract factory list.
+     */
+    private List m_factories = new ArrayList();
+
+    /**
+     * Creates the instance creator.
+     * This object is generally a singleton.
+     * @param context the bundle context of the iPOJO bundle.
+     */
+    public InstanceCreator(BundleContext context) {
+        m_logger = new Logger(context, "iPOJO Instance Creator");
+    }
+
+    /**
+     * Adds an instance to manage.
+     * @param instance the instance configuration
+     * @param bundle the bundle id declaring the instance
+     */
+    synchronized void addInstance(Dictionary instance, long bundle) {
+        if (instance.get("factory.version") != null) {
+            m_logger.log(Logger.DEBUG, "New instance to managed, looking for " + instance.get("component") + "-" + instance.get("factory.version"));
+        } else {
+            m_logger.log(Logger.DEBUG, "New instance to managed, looking for " + instance.get("component"));
+        }
+
+        ManagedInstance managed = new ManagedInstance(instance, bundle);
+        for (int i = 0; i < m_factories.size(); i++) {
+            IPojoFactory factory = (IPojoFactory) m_factories.get(i);
+            if (managed.matchNameAndVersion(factory)) {
+                // Subscribe to the factory state change
+                m_logger.log(Logger.DEBUG, "Listen factory " + factory.getName() + " events");
+                factory.addFactoryStateListener(this);
+                if (factory.getState() == Factory.VALID && managed.match(factory)) {
+                    managed.create(factory);
+                    List list = (List) m_attached.get(factory);
+                    if (list == null) {
+                        list = new ArrayList();
+                        list.add(managed);
+                        m_attached.put(factory, list);
+                    } else {
+                        list.add(managed);
+                    }
+                    return;
+                }
+            }
+        }
+        // If there is no matching factory, add the instance to the idle list
+        m_idle.add(managed);
+    }
+
+    /**
+     * Disposes all instances declared by the given (leaving) bundle.
+     * @param bundle the bundle.
+     */
+    void removeInstancesFromBundle(long bundle) {
+        // Disposes instance from attached instances
+        Collection col = m_attached.keySet();
+        Iterator iterator = col.iterator();
+        List instanceToRemove = new ArrayList();
+        List factoryToRemove = new ArrayList();
+        while (iterator.hasNext()) {
+            IPojoFactory factory = (IPojoFactory) iterator.next();
+            List list = (List) m_attached.get(factory);
+            for (int i = 0; i < list.size(); i++) {
+                ManagedInstance managed = (ManagedInstance) list.get(i);
+                if (managed.m_bundleId == bundle) {
+                    managed.dispose();
+                    instanceToRemove.add(managed);
+                }
+            }
+            if (!instanceToRemove.isEmpty()) {
+                list.removeAll(instanceToRemove);
+                if (list.isEmpty()) {
+                    factory.removeFactoryStateListener(this);
+                    factoryToRemove.add(factory);
+                }
+            }
+        }
+
+        for (int i = 0; i < factoryToRemove.size(); i++) {
+            m_attached.remove(factoryToRemove.get(i));
+        }
+
+        // Delete idle instances
+        instanceToRemove.clear();
+        for (int i = 0; i < m_idle.size(); i++) {
+            ManagedInstance managed = (ManagedInstance) m_idle.get(i);
+            if (managed.m_bundleId == bundle) {
+                instanceToRemove.add(managed);
+            }
+        }
+        m_idle.removeAll(instanceToRemove);
+    }
+
+    /**
+     * This method is called when a factory appears.
+     * @param factory the new factory.
+     */
+    public synchronized void addFactory(IPojoFactory factory) {
+        List createdInstances = new ArrayList(1);
+        m_logger.log(Logger.DEBUG, "Add the factory " + factory.getName());
+        m_factories.add(factory);
+        for (int i = 0; i < m_idle.size(); i++) {
+            ManagedInstance managed = (ManagedInstance) m_idle.get(i);
+            if (managed.matchNameAndVersion(factory)) {
+                // We have to subscribe to the factory.
+                factory.addFactoryStateListener(this);
+                if (factory.getState() == Factory.VALID && managed.match(factory)) {
+                    managed.create(factory);
+                    List list = (List) m_attached.get(factory);
+                    if (list == null) {
+                        list = new ArrayList();
+                        list.add(managed);
+                        m_attached.put(factory, list);
+                    } else {
+                        list.add(managed);
+                    }
+                    createdInstances.add(managed);
+                }
+            }
+        }
+        if (!createdInstances.isEmpty()) {
+            m_idle.removeAll(createdInstances);
+        }
+    }
+
+    /**
+     * This method is called when a factory is leaving.
+     * @param factory the leaving factory
+     */
+    void removeFactory(IPojoFactory factory) {
+        factory.removeFactoryStateListener(this);
+        m_factories.remove(factory);
+        onInvalidation(factory);
+        m_attached.remove(factory);
+    }
+
+    /**
+     * This method is called when the given factory becomes valid.
+     * @param factory the factory becoming valid.
+     */
+    private void onValidation(IPojoFactory factory) {
+        List toRemove = new ArrayList();
+        for (int i = 0; i < m_idle.size(); i++) {
+            ManagedInstance managed = (ManagedInstance) m_idle.get(i);
+            if (managed.match(factory)) {
+                managed.create(factory);
+                List list = (List) m_attached.get(factory);
+                if (list == null) {
+                    list = new ArrayList();
+                    list.add(managed);
+                    m_attached.put(factory, list);
+                } else {
+                    list.add(managed);
+                }
+                toRemove.add(managed);
+            }
+        }
+        if (!toRemove.isEmpty()) {
+            m_idle.removeAll(toRemove);
+        }
+    }
+
+    /**
+     * This method is called when the given factory becomes invalid.
+     * @param factory the factory becoming invalid.
+     */
+    private void onInvalidation(IPojoFactory factory) {
+        List instances = (List) m_attached.remove(factory);
+        if (instances != null) {
+            for (int i = 0; i < instances.size(); i++) {
+                ManagedInstance managed = (ManagedInstance) instances.get(i);
+                managed.dispose();
+                m_idle.add(managed);
+            }
+        }
+    }
+
+    /**
+     * This method is called when the state of a factory changes.
+     * @param factory the factory.
+     * @param newState the new state.
+     * @see org.apache.felix.ipojo.FactoryStateListener#stateChanged(org.apache.felix.ipojo.Factory, int)
+     */
+    public void stateChanged(Factory factory, int newState) {
+        if (newState == Factory.VALID) {
+            m_logger.log(Logger.DEBUG, "A factory is becoming valid : " + factory.getName());
+            onValidation((IPojoFactory) factory);
+        } else {
+            m_logger.log(Logger.DEBUG, "A factory is becoming invalid : " + factory.getName());
+            onInvalidation((IPojoFactory) factory);
+        }
+    }
+
+    /**
+     * This structure aims to manage a configuration.
+     * It stores all necessary information to create an instance
+     * and to track the factory.
+     */
+    private class ManagedInstance {
+        /**
+         * The configuration of the instance to create.
+         */
+        private Dictionary m_configuration;
+
+        /**
+         * The bundle which creates the instance.
+         */
+        private long m_bundleId;
+
+        /**
+         * The factory used to create the instance.
+         */
+        private IPojoFactory m_factory;
+
+        /**
+         * The created instance.
+         */
+        private ComponentInstance m_instance;
+
+        /**
+         * Creates a ManagedInstance.
+         * @param conf the configuration to create.
+         * @param bundle the bundle in which the instance is declared.
+         */
+        ManagedInstance(Dictionary conf, long bundle) {
+            m_configuration = conf;
+            m_bundleId = bundle;
+        }
+
+        /**
+         * Checks if the required factory name match with the given factory.
+         * This methods checks only the name, and not the configuration.
+         * @param factory the factory to test
+         * @return <code>true</code> if the factory name and the version (if set) match, <code>false</code>
+         * otherwise.
+         */
+        public boolean matchNameAndVersion(IPojoFactory factory) {
+            String component = (String) m_configuration.get("component");
+            String v = (String) m_configuration.get("factory.version");
+            if (v == null) {
+                return factory.getName().equals(component) || factory.getClassName().equalsIgnoreCase(component);
+            } else {
+                return (factory.getName().equals(component) || factory.getClassName().equalsIgnoreCase(component))
+                    && v.equals(factory.getVersion());
+            }
+        }
+
+        /**
+         * Checks if the given factory match with the factory
+         * required by this instance. A factory matches if its
+         * name or its class name is equals to the 'component'
+         * property of the instance. Then the acceptability of
+         * the configuration is checked.
+         * @param factory the factory to confront against the current instance.
+         * @return <code>true</code> if the factory matches.
+         */
+        public boolean match(IPojoFactory factory) {
+            // Test factory name (and classname)
+            if (matchNameAndVersion(factory)) {
+                // Test factory accessibility
+                if (factory.m_isPublic || factory.getBundleContext().getBundle().getBundleId() == m_bundleId) {
+                    // Test the configuration validity.
+                    try {
+                        factory.checkAcceptability(m_configuration);
+                        return true;
+                    } catch (UnacceptableConfiguration e) {
+                        m_logger.log(Logger.ERROR, "An instance can be bound to a matching factory, however the configuration seems unacceptable : "
+                                + e.getMessage());
+                        return false;
+                    } catch (MissingHandlerException e) {
+                        m_logger.log(Logger.ERROR, "An instance can be bound to a matching factory, but this factory cannot be used : "
+                                + e.getMessage());
+                        return false;
+                    }
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Creates the instance by using the given factory.
+         * @param factory the factory to use to create the instance. The factory must match.
+         */
+        public void create(IPojoFactory factory) {
+            try {
+                m_factory = factory;
+                m_instance = m_factory.createComponentInstance(m_configuration);
+                m_logger.log(Logger.INFO, "Instance created");
+            } catch (UnacceptableConfiguration e) {
+                m_logger.log(Logger.ERROR, "A matching factory was found for " + m_configuration + ", but the instantiation failed : "
+                        + e.getMessage());
+            } catch (MissingHandlerException e) {
+                m_logger.log(Logger.ERROR, "A matching factory was found for " + m_configuration + ", but the instantiation failed : "
+                        + e.getMessage());
+            } catch (ConfigurationException e) {
+                m_logger.log(Logger.ERROR, "A matching factory was found for " + m_configuration + ", but the instantiation failed : "
+                        + e.getMessage());
+            }
+        }
+
+        /**
+         * Disposes the current instance if not <code>null</code>.
+         */
+        public void dispose() {
+            if (m_instance != null) {
+                m_instance.dispose();
+            }
+            m_instance = null;
+            m_factory = null;
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
new file mode 100644
index 0000000..1d9c6b9
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceManager.java
@@ -0,0 +1,1371 @@
+/*
+ * 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;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.FieldMetadata;
+import org.apache.felix.ipojo.parser.MethodMetadata;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.BundleContext;
+
+/**
+ * This class defines the container of primitive instances. It manages content initialization
+ * and handlers cooperation.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class InstanceManager implements ComponentInstance, InstanceStateListener {
+    /**
+     * The name of the component instance.
+     */
+    protected String m_name;
+
+    /**
+     * The name of the component type implementation class.
+     */
+    protected String m_className;
+
+    /**
+     * The handler object list.
+     */
+    protected final HandlerManager[] m_handlers;
+
+    /**
+     * The current instance state ({@link ComponentInstance#STOPPED} at the beginning).
+     * Possible value are
+     * <li>{@link ComponentInstance#INVALID}</li>
+     * <li>{@link ComponentInstance#VALID}</li>
+     * <li>{@link ComponentInstance#DISPOSED}</li>
+     * <li>{@link ComponentInstance#STOPPED}</li>
+     */
+    protected int m_state = STOPPED;
+
+    /**
+     * The instance state listener list.
+     * @see InstanceStateListener
+     */
+    protected List m_listeners = null;
+
+    /**
+     * The content of the current instance.
+     */
+    protected List m_pojoObjects;
+
+    /**
+     * The instance factory.
+     */
+    private final ComponentFactory m_factory;
+
+    /**
+     * The instance logger.
+     */
+    private final Logger m_logger;
+
+    /**
+     * The instance description.
+     */
+    private final PrimitiveInstanceDescription m_description;
+
+    /**
+     * The bundle context of the instance.
+     */
+    private final BundleContext m_context;
+
+    /**
+     * The map [field, {@link FieldInterceptor} list] storing interceptors monitoring fields.
+     * Once configured, this map can't change.
+     */
+    private Map m_fieldRegistration;
+
+    /**
+     * the map [method identifier, {@link MethodInterceptor} list] interested
+     * by the method.
+     * Once configured, this map can't change.
+     */
+    private Map m_methodRegistration;
+
+    /**
+     * the map (sorted by parameter index) or {@link ConstructorInjector} interested by
+     * injecting constructor parameter.
+     * Once configured, this list can't change.
+     */
+    private Map m_constructorRegistration;
+
+    /**
+     * The manipulated class.
+     * Once set, this field doesn't change.
+     */
+    private Class m_clazz;
+
+    /**
+     * The factory method used to create content objects.
+     * If <code>null</code>, the regular constructor is used.
+     * Once set, this field is immutable.
+     */
+    private String m_factoryMethod = null;
+
+    /**
+     * Is the component instance state changing?
+     */
+    private boolean m_inTransition = false;
+
+    /**
+     * The queue of stored state changed.
+     */
+    private List m_stateQueue = new ArrayList();
+
+    /**
+     * The map of [field, value], storing POJO managed
+     * field value.
+     */
+    private Map m_fields = new HashMap();
+
+    /**
+     * The Map storing the Method objects by ids.
+     * [id=>{@link Method}].
+     */
+    private Map m_methods = new HashMap();
+
+
+    /**
+     * Creates a new Component Manager.
+     * The instance is not initialized.
+     * @param factory  the factory managing the instance manager
+     * @param context  the bundle context to give to the instance
+     * @param handlers handler object array
+     */
+    public InstanceManager(ComponentFactory factory, BundleContext context, HandlerManager[] handlers) {
+        m_factory = factory;
+        m_context = context;
+        m_handlers = handlers;
+        m_description = new PrimitiveInstanceDescription(m_factory.getComponentDescription(), this);
+        m_logger = new Logger(m_context, this);
+    }
+
+    /**
+     * The instance logger.
+     * @return the logger
+     */
+    public Logger getLogger() {
+        return m_logger;
+    }
+
+    /**
+     * Configures the instance manager.
+     * Sets the class name, and the instance name as well as the factory method.
+     * Initializes handlers.
+     * @param metadata the component type metadata
+     * @param configuration the configuration of the instance
+     * @throws ConfigurationException if the metadata are not correct
+     */
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+        m_className = metadata.getAttribute("classname");
+
+        // Add the name
+        m_name = (String) configuration.get("instance.name");
+
+        // Check if an object is injected in the instance
+        Object obj = configuration.get("instance.object");
+        if (obj != null) {
+            m_pojoObjects = new ArrayList(1);
+            m_pojoObjects.add(obj);
+        }
+
+        // Get the factory method if presents.
+        m_factoryMethod = (String) metadata.getAttribute("factory-method");
+
+        // Create the standard handlers and add these handlers to the list
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].init(this, metadata, configuration);
+        }
+
+        // Check that the constructor parameter are continuous.
+        if (m_constructorRegistration != null) {
+            for (int i = 0; i < m_constructorRegistration.size(); i++) {
+                if (! m_constructorRegistration.containsKey(new Integer(i))) {
+                    throw new ConfigurationException("The constructor parameter " + i + " is not managed");
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the description of the current instance.
+     * @return the instance description.
+     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceDescription()
+     */
+    public InstanceDescription getInstanceDescription() {
+        return m_description;
+    }
+
+    /**
+     * Gets the list of handlers plugged (i.e. attached) on the instance.
+     * This method does not need a synchronized block as the handler set is constant.
+     * @return the handler array of plugged handlers.
+     */
+    public Handler[] getRegistredHandlers() {
+        Handler[] handler = new Handler[m_handlers.length];
+        for (int i = 0; i < m_handlers.length; i++) {
+            handler[i] = m_handlers[i].getHandler();
+        }
+        return handler;
+    }
+
+    /**
+     * Returns a specified handler.
+     * This method allows cross-handler interactions.
+     * This must does not need a synchronized block as the handler set is constant.
+     * @param name the class name of the handler to find or its qualified name (namespace:name)
+     * @return the handler, or null if not found
+     */
+    public Handler getHandler(String name) {
+        for (int i = 0; i < m_handlers.length; i++) {
+            HandlerFactory fact = (HandlerFactory) m_handlers[i].getHandler().getHandlerManager().getFactory();
+            if (fact.getHandlerName().equals(name)) {
+                return m_handlers[i].getHandler();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gives access to a field value of the first created pojo.
+     * This method processes by analyzing both managed fields and pojo fields (by reflection).
+     * If no pojo were already created try only on managed fields.
+     * @param fieldName the field name.
+     * @return the field value, <code>null</code> is returned if the value is managed and not already set.
+     */
+    public synchronized Object getFieldValue(String fieldName) {
+        if (m_pojoObjects == null) {
+            return getFieldValue(fieldName, null);
+        } else {
+            return getFieldValue(fieldName, m_pojoObjects.get(0)); // Use the first pojo.
+        }
+    }
+
+    /**
+     * Gives access to a field value to the given created pojo.
+     * This method processes by analyzing both managed fields and pojo fields (by reflection).
+     * If the given pojo is <code>null</code>, tries only on managed fields.
+     * @param fieldName the field name.
+     * @param pojo  the pojo on which computing field value.
+     * @return the field value, <code>null</code> is returned if the value is managed and not already set.
+     */
+    public synchronized Object getFieldValue(String fieldName, Object pojo) {
+        Object setByContainer = null;
+
+        if (m_fields != null) {
+            setByContainer = m_fields.get(fieldName);
+        }
+
+        if (setByContainer == null && pojo != null) { // In the case of no given pojo, return null.
+            // If null either the value was not already set or has the null value.
+            try {
+                Field field = pojo.getClass().getDeclaredField(fieldName);
+                if (!field.isAccessible()) {
+                    field.setAccessible(true);
+                }
+                return field.get(pojo);
+            } catch (SecurityException e) {
+                m_logger.log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            } catch (NoSuchFieldException e) {
+                m_logger.log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            } catch (IllegalArgumentException e) {
+                m_logger.log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            } catch (IllegalAccessException e) {
+                m_logger.log(Logger.ERROR, "Cannot reflect on field " + fieldName + " to obtain the value : " + e.getMessage());
+            }
+            return null;
+        } else {
+            return setByContainer;
+        }
+    }
+
+    /**
+     * Starts the instance manager.
+     * This method activates plugged handlers,
+     * and computes the initial instance state.
+     */
+    public void start() {
+        synchronized (this) {
+            if (m_state != STOPPED) { // Instance already started
+                return;
+            } else {
+                m_state = -2; // Temporary state.
+            }
+        }
+
+        // Plug handler descriptions
+        Handler[] handlers = getRegistredHandlers();
+        for (int i = 0; i < handlers.length; i++) {
+            m_description.addHandler(handlers[i].getDescription());
+        }
+
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].addInstanceStateListener(this);
+            try {
+                m_handlers[i].start();
+            } catch (IllegalStateException e) {
+                m_logger.log(Logger.ERROR, e.getMessage());
+                stop();
+                throw e;
+            }
+        }
+
+        // Is an object already contained (i.e. injected)
+        if (m_pojoObjects != null && ! m_pojoObjects.isEmpty()) {
+            managedInjectedObject();
+        }
+
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i].getState() != VALID) {
+                setState(INVALID);
+                return;
+            }
+        }
+        setState(VALID);
+    }
+
+    /**
+     * Stops the instance manager.
+     * This methods sets the instance state to {@link ComponentInstance#STOPPED},
+     * disables attached handlers, and notifies listeners ({@link InstanceStateListener})
+     * of the instance stopping process.
+     */
+    public void stop() {
+        List listeners = null;
+        synchronized (this) {
+            if (m_state == STOPPED) { // Instance already stopped
+                return;
+            }
+            m_stateQueue.clear();
+            m_inTransition = false;
+        }
+
+        setState(INVALID); // Must be called outside a synchronized block.
+
+        // Stop all the handlers
+        for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].removeInstanceStateListener(this);
+            m_handlers[i].stop();
+        }
+
+        synchronized (this) {
+            m_state = STOPPED;
+            if (m_listeners != null) {
+                listeners = new ArrayList(m_listeners); // Stack confinement
+            }
+            m_pojoObjects = null;
+        }
+
+        if (listeners != null) {
+            for (int i = 0; i < listeners.size(); i++) {
+                ((InstanceStateListener) listeners.get(i)).stateChanged(this, STOPPED);
+            }
+        }
+    }
+
+    /**
+     * Disposes the instance.
+     * This method does the following process:
+     * <li>Stop the instance is not {@link ComponentInstance#STOPPED}</li>
+     * <li>Notifies listeners {@link InstanceStateListener} of the destruction</li>
+     * <li>Disposes attached handlers</li>
+     * <li>Clears structures</li>
+     * @see org.apache.felix.ipojo.ComponentInstance#dispose()
+     */
+    public void dispose() {
+        List listeners = null;
+        int state = -2; // Temporary state
+        synchronized (this) {
+            state = m_state; // Stack confinement
+            if (m_listeners != null) {
+                listeners = new ArrayList(m_listeners); // Stack confinement
+            }
+            m_listeners = null;
+        }
+
+        if (state > STOPPED) { // Valid or invalid
+            stop(); // Does not hold the lock.
+        }
+
+        synchronized (this) {
+            m_state = DISPOSED;
+        }
+
+        for (int i = 0; listeners != null && i < listeners.size(); i++) {
+            ((InstanceStateListener) listeners.get(i)).stateChanged(this, DISPOSED);
+        }
+
+        for (int i = m_handlers.length - 1; i > -1; i--) {
+            m_handlers[i].dispose();
+        }
+
+        synchronized (this) {
+            m_factory.disposed(this);
+            m_clazz = null;
+            // Do not clean registration map, so injection still works
+            // after disposal for late callbacks.
+        }
+    }
+
+    /**
+     * Sets the state of the component instance.
+     * If the state changes, calls the {@link PrimitiveHandler#stateChanged(int)} method on the attached handlers.
+     * This method has a reentrant mechanism. If in the flow of the first call the method is called another times,
+     * the second call is stored and executed after the first one finished.
+     * @param state the new state
+     */
+    public void setState(int state) {
+        int originalState = -2;
+        List listeners = null;
+        synchronized (this) {
+            if (m_inTransition) {
+                m_stateQueue.add(new Integer(state));
+                return;
+            }
+
+            if (m_state != state) {
+                m_inTransition = true;
+                originalState = m_state; // Stack confinement.
+                m_state = state;
+                if (m_listeners != null) {
+                    listeners = new ArrayList(m_listeners); // Stack confinement.
+                }
+            }
+        }
+
+        // This section can be executed only by one thread at the same time. The m_inTransition pseudo semaphore block access to this section.
+        if (m_inTransition) { // Check that we are really changing.
+            if (state > originalState) {
+                // The state increases (Stopped = > IV, IV => V) => invoke handlers from the higher priority to the lower
+                try {
+                    for (int i = 0; i < m_handlers.length; i++) {
+                        m_handlers[i].getHandler().stateChanged(state);
+                    }
+                } catch (IllegalStateException e) {
+                    // When an illegal state exception happens, the instance manager must be stopped immediately.
+                    stop();
+                    m_logger.log(Logger.ERROR, e.getMessage(), e);
+                    return;
+                }
+            } else {
+                // The state decreases (V => IV, IV = > Stopped, Stopped => Disposed)
+                try {
+                    for (int i = m_handlers.length - 1; i > -1; i--) {
+                        m_handlers[i].getHandler().stateChanged(state);
+                    }
+                } catch (IllegalStateException e) {
+                    // When an illegal state exception happens, the instance manager must be stopped immediately.
+                    stop();
+                    m_logger.log(Logger.ERROR, e.getMessage());
+                    return;
+                }
+            }
+        }
+
+        if (listeners != null) {
+            for (int i = 0; i < listeners.size(); i++) {
+                ((InstanceStateListener) listeners.get(i)).stateChanged(this, state);
+            }
+        }
+
+        synchronized (this) {
+            m_inTransition = false;
+            if (!m_stateQueue.isEmpty()) {
+                int newState = ((Integer) (m_stateQueue.remove(0))).intValue();
+                setState(newState);
+            }
+        }
+    }
+
+    /**
+     * Gets the actual state of the instance.
+     * Possible values are:
+     * <li>{@link ComponentInstance#INVALID}</li>
+     * <li>{@link ComponentInstance#VALID}</li>
+     * <li>{@link ComponentInstance#DISPOSED}</li>
+     * <li>{@link ComponentInstance#STOPPED}</li>
+     * @return the actual state of the component instance.
+     * @see org.apache.felix.ipojo.ComponentInstance#getState()
+     */
+    public synchronized int getState() {
+        return m_state;
+    }
+
+    /**
+     * Checks if the instance is started.
+     * An instance is started if the state is either
+     * {@link ComponentInstance#VALID} or {@link ComponentInstance#INVALID}.
+     * @return <code>true</code> if the instance is started.
+     * @see org.apache.felix.ipojo.ComponentInstance#isStarted()
+     */
+    public synchronized boolean isStarted() {
+        return m_state > STOPPED;
+    }
+
+    /**
+     * Registers an instance state listener.
+     * @param listener the listener to register.
+     * @see org.apache.felix.ipojo.ComponentInstance#addInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
+     */
+    public synchronized void addInstanceStateListener(InstanceStateListener listener) {
+        if (m_listeners == null) {
+            m_listeners = new ArrayList();
+        }
+        m_listeners.add(listener);
+    }
+
+    /**
+     * Unregisters an instance state listener.
+     * @param listener the listener to unregister.
+     * @see org.apache.felix.ipojo.ComponentInstance#removeInstanceStateListener(org.apache.felix.ipojo.InstanceStateListener)
+     */
+    public synchronized void removeInstanceStateListener(InstanceStateListener listener) {
+        if (m_listeners != null) {
+            m_listeners.remove(listener);
+            if (m_listeners.isEmpty()) {
+                m_listeners = null;
+            }
+        }
+    }
+
+    /**
+     * Gets the factory which has created the current instance.
+     * @return the factory of the component
+     * @see org.apache.felix.ipojo.ComponentInstance#getFactory()
+     */
+    public ComponentFactory getFactory() {
+        return m_factory;
+    }
+
+    /**
+     * Loads the manipulated class.
+     */
+    private void load() {
+        try {
+            m_clazz = m_factory.loadClass(m_className);
+        } catch (ClassNotFoundException e) {
+            m_logger.log(Logger.ERROR, "[" + m_name + "] Class not found during the loading phase : " + e.getMessage(), e);
+            stop();
+            return;
+        }
+    }
+
+    /**
+     * Gets the object array created by the instance.
+     * @return the created content objects of the component instance.
+     */
+    public synchronized Object[] getPojoObjects() {
+        if (m_pojoObjects == null) {
+            return null;
+        }
+        return m_pojoObjects.toArray(new Object[m_pojoObjects.size()]);
+    }
+
+    /**
+     * Creates a POJO objects.
+     * This method is not synchronized and does not require any locks.
+     * If a {@link InstanceManager#m_factoryMethod} is specified,
+     * this method called this static method to creates the object.
+     * Otherwise, the methods uses the regular constructor.
+     * All those methods can receive the {@link BundleContext} in
+     * argument.
+     * @return the created object or <code>null</code> if an error
+     * occurs during the creation.
+     */
+    protected Object createObject() {
+        if (m_clazz == null) {
+            load();
+        }
+
+        // The following code doesn't need to be synchronized as is deal only with immutable fields.
+        Object instance = null;
+        if (m_factoryMethod == null) {
+            // No factory-method, we use the constructor.
+            try {
+                // Try to find the correct constructor.
+                if (m_constructorRegistration != null) {
+                    // Initialize the injected values and types
+                    // We have the IM first.
+                    Object[] values = new Object[m_constructorRegistration.size() + 1];
+                    Class[] types = new Class[m_constructorRegistration.size() + 1];
+                    values[0] = this;
+                    types[0] = InstanceManager.class;
+
+                    // Iterate over the constructor injector
+                    for (int i = 0; i < m_constructorRegistration.size(); i++) {
+                        ConstructorInjector injector = (ConstructorInjector)
+                            m_constructorRegistration.get(new Integer(i));
+                        Object v = injector.getConstructorParameter(i);
+                        if (v != null) {
+                            values[i + 1] = v;
+                            Class t = injector.getConstructorParameterType(i);
+                            if (t == null) {
+                                t = v.getClass();
+                            }
+                            types[i + 1] = t;
+                        }
+                    }
+                    // Find the constructor.
+                    Constructor cst = m_clazz.getDeclaredConstructor(types);
+                    if (! cst.isAccessible()) {
+                        cst.setAccessible(true);
+                    }
+                    String methodId = MethodMetadata.computeMethodId(cst);
+                    onEntry(null, methodId,  values);
+                    instance = cst.newInstance(values);
+                    onExit(instance, methodId, instance);
+                } else {
+                    // Old semantic
+                    // Try to find if there is a constructor with a bundle context as parameter :
+                    try {
+                        Constructor cst = m_clazz.getDeclaredConstructor(new Class[] { InstanceManager.class, BundleContext.class });
+                        if (! cst.isAccessible()) {
+                            cst.setAccessible(true);
+                        }
+                        Object[] args = new Object[] { this, m_context };
+                        onEntry(null, MethodMetadata.BC_CONSTRUCTOR_ID,  new Object[] {m_context});
+                        instance = cst.newInstance(args);
+                        onExit(instance, MethodMetadata.BC_CONSTRUCTOR_ID, instance);
+                    } catch (NoSuchMethodException e) {
+                        // Create an instance if no instance are already created with <init>()BundleContext
+                        if (instance == null) {
+                            Constructor cst = m_clazz.getDeclaredConstructor(new Class[] { InstanceManager.class });
+                            if (! cst.isAccessible()) {
+                                cst.setAccessible(true);
+                            }
+                            Object[] args = new Object[] {this};
+                            onEntry(null, MethodMetadata.EMPTY_CONSTRUCTOR_ID, new Object[0]);
+                            instance = cst.newInstance(args);
+                            onExit(instance, MethodMetadata.EMPTY_CONSTRUCTOR_ID, instance);
+                        }
+                    }
+                }
+
+            } catch (IllegalAccessException e) {
+                m_logger.log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> The POJO constructor is not accessible : " + e.getMessage(), e);
+                stop();
+                throw new RuntimeException("Cannot create a POJO instance, the POJO constructor is not accessible : " + e.getMessage());
+            } catch (SecurityException e) {
+                m_logger.log(
+                                          Logger.ERROR,
+                                          "["
+                                                  + m_name
+                                                  + "] createInstance -> The POJO constructor is not accessible (security reason) : "
+                                                  + e.getMessage(), e);
+                stop();
+                throw new RuntimeException("Cannot create a POJO instance, the POJO constructor is not accessible : " + e.getMessage());
+            } catch (InvocationTargetException e) {
+                m_logger.log(
+                                          Logger.ERROR,
+                                          "["
+                                                  + m_name
+                                                  + "] createInstance -> Cannot invoke the constructor method - the constructor throws an exception : "
+                                                  + e.getTargetException().getMessage(), e.getTargetException());
+                onError(null, m_className, e.getTargetException());
+                stop();
+                throw new RuntimeException("Cannot create a POJO instance, the POJO constructor has thrown an exception: " + e.getTargetException().getMessage());
+            } catch (NoSuchMethodException e) {
+                m_logger.log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> Cannot invoke the constructor (method not found) : " + e.getMessage(), e);
+                stop();
+                throw new RuntimeException("Cannot create a POJO instance, the POJO constructor cannot be found : " + e.getMessage());
+            } catch (Throwable e) {
+                // Catch every other possible error and runtime exception.
+                m_logger.log(Logger.ERROR,
+                        "[" + m_name + "] createInstance -> The POJO constructor invocation failed : " + e.getMessage(), e);
+                stop();
+                throw new RuntimeException("Cannot create a POJO instance, the POJO constructor invocation has thrown an exception : " + e.getMessage());
+            }
+        } else {
+            try {
+                // Build the pojo object with the factory-method.
+                Method factory = null;
+                // Try with the bundle context
+                try {
+                    factory = m_clazz.getDeclaredMethod(m_factoryMethod, new Class[] { BundleContext.class });
+                    if (! factory.isAccessible()) {
+                        factory.setAccessible(true);
+                    }
+                    Object[] args = new Object[] { m_context };
+                    onEntry(null, m_className, args);
+                    instance = factory.invoke(null, new Object[] { m_context });
+                } catch (NoSuchMethodException e1) {
+                    // Try without the bundle context
+                    try {
+                        factory = m_clazz.getDeclaredMethod(m_factoryMethod, new Class[0]);
+                        if (! factory.isAccessible()) {
+                            factory.setAccessible(true);
+                        }
+                        Object[] args = new Object[0];
+                        onEntry(null, m_className, args);
+                        instance = factory.invoke(null, args);
+                    } catch (NoSuchMethodException e2) {
+                        // Error : factory-method not found
+                        m_logger.log(
+                                                  Logger.ERROR,
+                                                  "["
+                                                          + m_name
+                                                          + "] createInstance -> Cannot invoke the factory-method (method not found) : "
+                                                          + e2.getMessage(), e2);
+                        stop();
+                        throw new RuntimeException("Cannot create a POJO instance, the factory-method cannot be found : " + e2.getMessage());
+                    }
+                }
+
+                // Now call the setInstanceManager method.
+                // Find declaring super class.
+                Class declaringClass = instance.getClass();
+                Method method = null;
+                while (declaringClass != null && method == null) {
+                    try {
+                        method = declaringClass.getDeclaredMethod("_setInstanceManager",
+                                new Class[] { InstanceManager.class });
+                    } catch (NoSuchMethodException e) {
+                        //Do nothing
+                    }
+
+                    declaringClass = declaringClass.getSuperclass();
+                }
+
+                if (method == null) {
+                    // Error : _setInstanceManager method is missing
+                    m_logger
+                            .log(
+                                 Logger.ERROR,
+                                 "["
+                                         + m_name
+                                         + "] createInstance -> Cannot invoke the factory-method (the _setInstanceManager method does not exist");
+                    stop();
+                    throw new RuntimeException("Cannot create a POJO instance, the factory-method cannot be found");
+                }
+
+                if (!method.isAccessible()) {
+                    method.setAccessible(true);
+                }
+                method.invoke(instance, new Object[] { this });
+                onExit(null, m_className, instance);
+
+            } catch (InvocationTargetException e) {
+                // Error : invocation failed
+                m_logger.log(Logger.ERROR,
+                                          "[" + m_name + "] createInstance -> The factory-method throws an exception : " + e.getTargetException(), e.getTargetException());
+                onError(null, m_className, e.getTargetException());
+                stop();
+                throw new RuntimeException("Cannot create a POJO instance, the factory-method has thrown an exception: " + e.getTargetException().getMessage());
+            } catch (Throwable e) {
+                // Catch every other possible error and runtime exception.
+                m_logger.log(Logger.ERROR,
+                        "[" + m_name + "] createInstance -> The factory-method invocation failed : " + e.getMessage(), e);
+                stop();
+                throw new RuntimeException("Cannot create a POJO instance, the factory-method invocation has thrown an exception : " + e.getMessage());
+            }
+        }
+        return instance;
+    }
+
+    /**
+     * Creates an instance of the content.
+     * This method needs to be called once only for singleton provided service.
+     * This methods call the {@link InstanceManager#createObject()} method, and adds
+     * the created object to the {@link InstanceManager#m_pojoObjects} list. Then,
+     * it calls the {@link PrimitiveHandler#onCreation(Object)} methods on attached
+     * handlers.
+     * @return a new instance or <code>null</code> if an error occurs during the
+     * creation.
+     */
+    public Object createPojoObject() {
+        Object instance = createObject();
+
+        // Add the new instance in the instance list.
+        synchronized (this) {
+            if (m_pojoObjects == null) {
+                m_pojoObjects = new ArrayList(1);
+            }
+            m_pojoObjects.add(instance);
+        }
+        // Call createInstance on Handlers :
+        for (int i = 0; i < m_handlers.length; i++) {
+            // This methods must be call without the monitor lock.
+            ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(instance);
+        }
+
+        return instance;
+    }
+
+    /**
+     * Deletes a POJO object.
+     * @param pojo the pojo to remove from the list of created pojos.
+     */
+    public synchronized void deletePojoObject(Object pojo) {
+        if (m_pojoObjects != null) {
+            m_pojoObjects.remove(pojo);
+        }
+    }
+
+    /**
+     * Gets the first object created by the instance.
+     * If no object created, creates and returns a POJO object.
+     * This methods call the {@link InstanceManager#createObject()} method, and adds
+     * the created object to the {@link InstanceManager#m_pojoObjects} list. Then,
+     * it calls the {@link PrimitiveHandler#onCreation(Object)} methods on attached
+     * handlers.
+     * <br/>
+     * <p>
+     * <b>TODO</b> this method has a potential race condition if two threads require a pojo
+     * object at the same time. Only one object will be created, but the second thread
+     * can receive the created object before the {@link PrimitiveHandler#onCreation(Object)}
+     * calls.
+     * </p>
+     * @return the pojo object of the component instance to use for singleton component
+     */
+    public Object getPojoObject() {
+        Object pojo = null;
+        boolean newPOJO = false;
+        synchronized (this) {
+            if (m_pojoObjects != null) {
+                pojo = m_pojoObjects.get(0); // Stack confinement
+            } else {
+                pojo = createObject();  // Stack confinement
+                if (m_pojoObjects == null) {
+                    m_pojoObjects = new ArrayList(1);
+                }
+                m_pojoObjects.add(pojo);
+                newPOJO = true;
+            }
+        }
+
+        // Call createInstance on Handlers :
+        for (int i = 0; newPOJO && i < m_handlers.length; i++) {
+            ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(pojo);
+        }
+        //NOTE this method allows returning a POJO object before calling the onCreation on handler:
+        // a second thread get the created object before the first one (which created the object),
+        // call onCreation.
+
+        return pojo;
+    }
+
+    /**
+     * Gets the manipulated class.
+     * The method does not need to be synchronized.
+     * Reassigning the internal class will use the same class object.
+     * @return the manipulated class
+     */
+    public Class getClazz() {
+        if (m_clazz == null) {
+            load();
+        }
+        return m_clazz;
+    }
+
+    /**
+     * Configures an injected object in this container.
+     */
+    private void managedInjectedObject() {
+        Object obj = m_pojoObjects.get(0); // Get first object.
+
+        if (! (obj instanceof Pojo)) {
+            // Error, the injected object is not a POJO.
+            throw new RuntimeException("The injected object in " + m_name + " is not a POJO");
+        }
+
+        load(); // Load the class.
+
+        if (! m_clazz.isInstance(obj)) {
+            throw new RuntimeException("The injected object in " + m_name + " is not an instance of " + m_className);
+        }
+
+        // Call _setInstanceManager
+        try {
+            Method setIM = m_clazz.getDeclaredMethod("_setInstanceManager", new Class[] {this.getClass()});
+            setIM.setAccessible(true); // Necessary as the method is private
+            setIM.invoke(obj, new Object[] {this});
+        } catch (Exception e) {
+            // If anything wrong happened...
+            throw new RuntimeException("Cannot attach the injected object with the container of " + m_name + " : " + e.getMessage());
+        }
+
+        // Call createInstance on Handlers :
+        for (int i = 0; i < m_handlers.length; i++) {
+            // This methods must be call without the monitor lock.
+            ((PrimitiveHandler) m_handlers[i].getHandler()).onCreation(obj);
+        }
+
+
+    }
+
+    /**
+     * Registers an handler.
+     * This methods is called by handler wanting to monitor
+     * fields and/or methods of the implementation class.
+     * @param handler the handler to register
+     * @param fields the field metadata list
+     * @param methods the method metadata list
+     * @deprecated use {@link InstanceManager#register(FieldMetadata, FieldInterceptor)}
+     * and {@link InstanceManager#register(FieldMetadata, MethodInterceptor)} instead.
+     */
+    public void register(PrimitiveHandler handler, FieldMetadata[] fields, MethodMetadata[] methods) {
+        for (int i = 0; fields != null && i < fields.length; i++) {
+            register(fields[i], handler);
+        }
+        for (int i = 0; methods != null && i < methods.length; i++) {
+            register(methods[i], handler);
+        }
+
+    }
+
+    /**
+     * Registers a field interceptor.
+     * A field interceptor will be notified of field access of the
+     * implementation class. Note that handlers are field interceptors.
+     * @param field the field to monitor
+     * @param interceptor the field interceptor object
+     */
+    public void register(FieldMetadata field, FieldInterceptor interceptor) {
+        if (m_fieldRegistration == null) {
+            m_fieldRegistration = new HashMap();
+            m_fieldRegistration.put(field.getFieldName(), new FieldInterceptor[] { interceptor });
+        } else {
+            FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(field.getFieldName());
+            if (list == null) {
+                m_fieldRegistration.put(field.getFieldName(), new FieldInterceptor[] { interceptor });
+            } else {
+                for (int j = 0; j < list.length; j++) {
+                    if (list[j] == interceptor) {
+                        return;
+                    }
+                }
+                FieldInterceptor[] newList = new FieldInterceptor[list.length + 1];
+                System.arraycopy(list, 0, newList, 0, list.length);
+                newList[list.length] = interceptor;
+                m_fieldRegistration.put(field.getFieldName(), newList);
+            }
+        }
+    }
+
+    /**
+     * Registers a method interceptor.
+     * A method interceptor will be notified of method entries, exits
+     * and errors. Note that handlers are method interceptors.
+     * @param method the field to monitor
+     * @param interceptor the field interceptor object
+     */
+    public void register(MethodMetadata method, MethodInterceptor interceptor) {
+        if (m_methodRegistration == null) {
+            m_methodRegistration = new HashMap();
+            m_methodRegistration.put(method.getMethodIdentifier(), new MethodInterceptor[] { interceptor });
+        } else {
+            MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(method.getMethodIdentifier());
+            if (list == null) {
+                m_methodRegistration.put(method.getMethodIdentifier(), new MethodInterceptor[] { interceptor });
+            } else {
+                for (int j = 0; j < list.length; j++) {
+                    if (list[j] == interceptor) {
+                        return;
+                    }
+                }
+                MethodInterceptor[] newList = new MethodInterceptor[list.length + 1];
+                System.arraycopy(list, 0, newList, 0, list.length);
+                newList[list.length] = interceptor;
+                m_methodRegistration.put(method.getMethodIdentifier(), newList);
+            }
+        }
+    }
+
+    /**
+     * Registers a constructor injector.
+     * The constructor injector will be called when a pojo object is going to be
+     * created.
+     * @param index the index of the parameter. Only one injector per index can
+     * be registered.
+     * @param injector the injector object.
+     * @throws ConfigurationException if the given index is already injected by another
+     * injector
+     */
+    public void register(int index, ConstructorInjector injector) throws ConfigurationException {
+        Integer key = new Integer(index);
+        if (m_constructorRegistration == null) {
+            m_constructorRegistration = new HashMap();
+        }
+        if (! m_constructorRegistration.containsKey(key)) {
+            m_constructorRegistration.put(key, injector);
+        } else {
+            throw new ConfigurationException("Another constructor injector " +
+                    "manages the parameter " + index);
+        }
+    }
+
+    /**
+     * This method is called by the manipulated class each time that a GETFIELD instruction is executed.
+     * The method asks to each attached handler monitoring this field which value need
+     * to be injected (i.e. returned) by invoking the {@link PrimitiveHandler#onGet(Object, String, Object)}
+     * method. If the field value changes, this method call the {@link PrimitiveHandler#onSet(Object, String, Object)}
+     * method on each field interceptor monitoring the field in order to advertize the new value.
+     * @param pojo the pojo object on which the field was get
+     * @param fieldName the field name on which the GETFIELD instruction is called
+     * @return the value decided by the last asked handler (throws a warning if two fields decide two different values)
+     */
+    public Object  onGet(Object pojo, String fieldName) {
+        Object initialValue = null;
+        synchronized (this) { // Stack confinement.
+            initialValue = m_fields.get(fieldName);
+        }
+        Object result = initialValue;
+        boolean hasChanged = false;
+        // Get the list of registered handlers
+        FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration.get(fieldName); // Immutable list.
+        for (int i = 0; list != null && i < list.length; i++) {
+            // Call onGet outside of a synchronized block.
+            Object handlerResult = list[i].onGet(null, fieldName, initialValue);
+            if (handlerResult == initialValue) {
+                continue; // Non-binding case (default implementation).
+            } else {
+                if (result != initialValue) {
+                    //TODO analyze impact of removing conflict detection
+                    if ((handlerResult != null && !handlerResult.equals(result)) || (result != null && handlerResult == null)) {
+                        m_logger.log(
+                                                  Logger.WARNING,
+                                                  "A conflict was detected on the injection of "
+                                                          + fieldName);
+                    }
+                }
+                result = handlerResult;
+                hasChanged = true;
+            }
+        }
+        if (hasChanged) {
+            // A change occurs => notify the change
+            //TODO consider just changing the reference, however multiple thread can be an issue
+            synchronized (this) {
+                m_fields.put(fieldName, result);
+            }
+            // Call onset outside of a synchronized block.
+            for (int i = 0; list != null && i < list.length; i++) {
+                list[i].onSet(null, fieldName, result);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Dispatches entry method events on registered method interceptors.
+     * This method calls the {@link PrimitiveHandler#onEntry(Object, Method, Object[])}
+     * methods on method interceptors monitoring the method.
+     * @param pojo the pojo object on which method is invoked.
+     * @param methodId the method id used to compute the {@link Method} object.
+     * @param args the argument array
+     */
+    public void onEntry(Object pojo, String methodId, Object[] args) {
+        if (m_methodRegistration == null) { // Immutable field.
+            return;
+        }
+        MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+        Member method = getMethodById(methodId);
+        // In case of a constructor, the method is null, and the list is null too.
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onEntry(pojo, method, args); // Outside a synchronized block.
+        }
+    }
+
+    /**
+     * Dispatches exit method events on registered method interceptors.
+     * The given returned object is an instance of {@link Exception} if the method thrown an
+     * exception. If the given object is <code>null</code>, either the method returns <code>void</code>,
+     * or the method has returned <code>null</code>
+     * This method calls the {@link PrimitiveHandler#onExit(Object, Method, Object[])} and the
+     * {@link PrimitiveHandler#onFinally(Object, Method)} methods on method interceptors monitoring the method.
+     * @param pojo the pojo object on which method was invoked.
+     * @param methodId the method id used to compute the {@link Method} object.
+     * @param result the returned object.
+     */
+    public void onExit(Object pojo, String methodId, Object result) {
+        if (m_methodRegistration == null) {
+            return;
+        }
+        MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+        Member method = getMethodById(methodId);
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onExit(pojo, method, result);
+        }
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onFinally(pojo, method);
+        }
+    }
+
+    /**
+     * Dispatches error method events on registered method interceptors.
+     * or the method has returned <code>null</code>
+     * This method calls the {@link PrimitiveHandler#onExit(Object, Method, Object[])} and the
+     * {@link PrimitiveHandler#onFinally(Object, Method)} methods on method interceptors monitoring
+     * the method.
+     * @param pojo the pojo object on which the method was invoked
+     * @param methodId the method id used to compute the {@link Method} object.
+     * @param error the Throwable object.
+     */
+    public void onError(Object pojo, String methodId, Throwable error) {
+        if (m_methodRegistration == null) {
+            return;
+        }
+        MethodInterceptor[] list = (MethodInterceptor[]) m_methodRegistration.get(methodId);
+        Member method = getMethodById(methodId);
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onError(pojo, method, error);
+        }
+        for (int i = 0; list != null && i < list.length; i++) {
+            list[i].onFinally(pojo, method);
+        }
+    }
+
+    /**
+     * Computes the {@link Method} object from the given id.
+     * Once computes, a map is used as a cache to avoid to recompute for
+     * the same id.
+     * @param methodId the method id
+     * @return the method object or <code>null</code> if the method cannot be found.
+     */
+    private Member getMethodById(String methodId) {
+        // Not necessary synchronized as recomputing the methodID will give the same Method twice.
+        Member member = (Member) m_methods.get(methodId);
+        if (member == null  && m_clazz != null) {
+
+            // First try on methods.
+            Method[] mets = m_clazz.getDeclaredMethods();
+            for (int i = 0; i < mets.length; i++) {
+                // Check if the method was not already computed. If not, compute the Id and check.
+                if (!m_methods.containsValue(mets[i]) && (MethodMetadata.computeMethodId(mets[i]).equals(methodId))) {
+                    // Store the new methodId
+                    m_methods.put(methodId, mets[i]);
+                    return mets[i];
+                }
+            }
+
+            // If not found, it is a constructor, return the constructor object in this case.
+            if (methodId.startsWith(MethodMetadata.CONSTRUCTOR_PREFIX)) {
+                Constructor[] constructors = m_clazz.getDeclaredConstructors();
+                for (int i = 0; i < constructors.length; i++) {
+                    // Check if the constructor was not already computed. If not, compute the Id and check.
+                    if (!m_methods.containsValue(constructors[i]) && (MethodMetadata.computeMethodId(constructors[i]).equals(methodId))) {
+                        // Store the new methodId
+                        m_methods.put(methodId, constructors[i]);
+                        return constructors[i];
+                    }
+                }
+            }
+
+            // Cannot happen
+            m_logger.log(Logger.INFO, "A methodID cannot be associated with a method from the POJO class: " + methodId);
+            return null;
+        } else {
+            return member;
+        }
+    }
+
+    /**
+     * This method is called by the manipulated class each time that a PUTFIELD instruction is executed.
+     * The method calls the {@link PrimitiveHandler#onSet(Object, String, Object)} method on each field
+     * interceptors monitoring this field.
+     * This method can be invoked with a <code>null</code> pojo argument when the changes comes from another
+     * handler.
+     * @param pojo the pojo object on which the field was set
+     * @param fieldName the field name on which the PUTFIELD instruction is called
+     * @param objectValue the new value of the field
+     */
+    public void onSet(final Object pojo, final String fieldName, final Object objectValue) {
+        synchronized (this) {
+            // First, store the new value.
+            // This must be done in a synchronized block to avoid
+            // concurrent modification
+            m_fields.put(fieldName, objectValue);
+        }
+        // The registrations cannot be modified, so we can directly access
+        // the interceptor list.
+        FieldInterceptor[] list = (FieldInterceptor[]) m_fieldRegistration
+                .get(fieldName);
+        for (int i = 0; list != null && i < list.length; i++) {
+             // The callback must be call outside the synchronization block.
+            list[i].onSet(null, fieldName, objectValue);
+        }
+    }
+
+
+    /**
+     * Gets the bundle context used by this component instance.
+     * @return the context of the component.
+     * @see org.apache.felix.ipojo.ComponentInstance#getContext()
+     */
+    public BundleContext getContext() {
+        return m_context; // Immutable
+    }
+
+    /**
+     * Gets the global bundle context. This is the bundle context
+     * of the bundle declaring the component type.
+     * @return the bundle context of the bundle declaring the component
+     * type.
+     */
+    public BundleContext getGlobalContext() {
+        return ((IPojoContext) m_context).getGlobalContext(); // Immutable
+    }
+
+
+    /**
+     * Gets the local service context. This service context gives
+     * access to the 'local' service registry (the composite one).
+     * If the instance lives in the global (i.e. OSGi) context,
+     * this method returns <code>null</code>
+     * @return the local service context or <code>null</code> if the
+     * instance doesn't live in a composite.
+     */
+    public ServiceContext getLocalServiceContext() {
+        return ((IPojoContext) m_context).getServiceContext(); // Immutable
+    }
+
+    /**
+     * Gets the instance name.
+     * @return the instance name.
+     * @see org.apache.felix.ipojo.ComponentInstance#getInstanceName()
+     */
+    public String getInstanceName() {
+        return m_name; // Immutable
+    }
+
+    /**
+     * Reconfigures the current instance.
+     * Reconfiguring an instance means re-injecting a new
+     * instance configuration. Some properties are immutable
+     * such as the instance name.
+     * This methods calls the {@link PrimitiveHandler#reconfigure(Dictionary)}
+     * methods on each attached handler, and then recompute the instance
+     * state. Note that the reconfiguration process does not deactivate the
+     * instance.
+     * @param configuration the new configuration to push
+     * @see org.apache.felix.ipojo.ComponentInstance#reconfigure(java.util.Dictionary)
+     */
+    public void reconfigure(Dictionary configuration) {
+         m_logger.log(Logger.INFO, "Reconfiguring " + getInstanceName());
+        for (int i = 0; i < m_handlers.length; i++) {
+            m_handlers[i].getHandler().reconfigure(configuration);
+        }
+        // We synchronized the state computation.
+        synchronized (this) {
+            if (m_state == STOPPED) {
+                m_logger.log(Logger.INFO, "Instance stopped during reconfiguration - Try to restart");
+                start();
+            } else if (m_state == INVALID) {
+                m_logger.log(Logger.INFO, "Instance invalid during reconfiguration - Recompute state");
+                // Try to revalidate the instance after reconfiguration
+                for (int i = 0; i < m_handlers.length; i++) {
+                    if (m_handlers[i].getState() != VALID) {
+                        return;
+                    }
+                }
+                setState(VALID);
+            }
+        }
+    }
+
+    /**
+     * Gets the implementation class of the component type.
+     * This method does not need to be synchronized as the
+     * class name is constant once set.
+     * @return the class name of the component implementation.
+     */
+    public String getClassName() {
+        return m_className;
+    }
+
+    /**
+     * State Change listener callback.
+     * This method is called every time that a plugged handler becomes valid or invalid.
+     * This method computes the new instance state and applies it (by calling the
+     * {@link InstanceManager#setState(int)} method.
+     * @param instance the handler becoming valid or invalid
+     * @param newState the new state of the handler
+     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
+     */
+    public void stateChanged(ComponentInstance instance, int newState) {
+        int state;
+        synchronized (this) {
+            if (m_state <= STOPPED) {
+                return;
+            } else {
+                state = m_state; // Stack confinement
+            }
+        }
+
+        // Update the component state if necessary
+        if (newState == INVALID && state == VALID) {
+            // Need to update the state to UNRESOLVED
+            setState(INVALID);
+            return;
+        }
+        if (newState == VALID && state == INVALID) {
+            // An handler becomes valid => check if all handlers are valid
+            for (int i = 0; i < m_handlers.length; i++) {
+                if (m_handlers[i].getState() != VALID) {
+                    return;
+                }
+            }
+            setState(VALID);
+            return;
+        }
+    }
+
+    /**
+     * Gets the list of registered fields (containing field names).
+     * This method is invoked by the POJO itself during
+     * its initialization.
+     * @return the set of registered fields.
+     */
+    public Set getRegistredFields() {
+        if (m_fieldRegistration == null) {
+            return null;
+        }
+        return m_fieldRegistration.keySet();
+    }
+
+    /**
+     * Gets the list of registered methods (containing method ids).
+     * This method is invoked by the POJO itself during its
+     * initialization.
+     * @return the set of registered methods.
+     */
+    public Set getRegistredMethods() {
+        if (m_methodRegistration == null) {
+            return null;
+        } else {
+            return m_methodRegistration.keySet();
+        }
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceStateListener.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceStateListener.java
new file mode 100644
index 0000000..d6ec53a
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/InstanceStateListener.java
@@ -0,0 +1,43 @@
+/* 
+ * 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;
+
+/**
+ * This class defines instance state listeners.
+ * An instance state listener is notified of instance state changes. It needs to be
+ * registered on the instance by invoking the ({@link ComponentInstance#addInstanceStateListener(InstanceStateListener)}
+ * method. Once registered, the listener can track instance state changes. 
+ * Received states are:
+ * <li>{@link ComponentInstance#VALID}</li>
+ * <li>{@link ComponentInstance#INVALID}</li>
+ * <li>{@link ComponentInstance#STOPPED}</li>
+ * <li>{@link ComponentInstance#DISPOSED}</li> 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface InstanceStateListener {
+    
+    /**
+     * State change listener callback method.
+     * Every time that a monitored instance's state changes,
+     * this method is called with the instance and the new state.
+     * @param instance the changing instance
+     * @param newState the new instance state
+     */
+    void stateChanged(ComponentInstance instance, int newState);
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java
new file mode 100644
index 0000000..15560fe
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/MethodInterceptor.java
@@ -0,0 +1,80 @@
+/*
+ * 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;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+/**
+* Method interceptor.
+* A class implementing this interface is able to be notified of method invocations (
+* i.e. entries, exits, and errors).
+* The listener needs to be register on the instance manager with the
+* {@link InstanceManager#register(org.apache.felix.ipojo.parser.MethodMetadata, MethodInterceptor)}
+* method.
+* Events are sent before the method entry (onEntry), after the method returns (onExit),
+* when an error is thrown by the method (onError), and before the after either a returns or an error (onFinally).
+*
+* Instead of a {@link Method} object, the callbacks received a {@link Member} object which can be either a {@link Method}
+* or a {@link Constructor}.
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public interface MethodInterceptor {
+
+    /**
+     * This method is called when a thread enters in a method.
+     * The given argument array is created from the method argument.
+     * @param pojo the pojo on which the method is called.
+     * @param method the invoked method.
+     * @param args the arguments array.
+     */
+    void onEntry(Object pojo, Member method, Object[] args);
+
+    /**
+     * This method is called when the execution exits a method :
+     * before a <code>return</code>.
+     * If the given returned object is <code>null</code>, either the method is
+     * <code>void</code>, or it returns <code>null</code>.
+     * This method must not modify the returned object.
+     * @param pojo the pojo on which the method exits.
+     * @param method the exiting method.
+     * @param returnedObj the the returned object (boxed for primitive type)
+     */
+    void onExit(Object pojo, Member method, Object returnedObj);
+
+    /**
+     * This method is called when the execution throws an exception in the given
+     * method.
+     * @param pojo the pojo on which the method was accessed.
+     * @param method the invoked method.
+     * @param throwable the thrown exception
+     */
+    void onError(Object pojo, Member method, Throwable throwable);
+
+    /**
+     * This method is called when the execution of a method is going to terminate :
+     * just before to throw an exception or before to return.
+     * (onError or onExit was already called).
+     * @param pojo the pojo on which the method was accessed.
+     * @param method the invoked method.
+     */
+    void onFinally(Object pojo, Member method);
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
new file mode 100644
index 0000000..9bc4efb
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/MissingHandlerException.java
@@ -0,0 +1,65 @@
+/* 
+ * 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;
+
+import java.util.List;
+
+/**
+ * Missing Handler Exception.
+ * This exception occurs when an handler factory is missing to create an instance.
+ * In fact, when a required handler factory is not avialable or valid, the {@link Handler}
+ * object cannot be created, and so the instance container cannot be completed.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class MissingHandlerException extends Exception {
+    
+    /**
+     * Serialization Id. 
+     */
+    private static final long serialVersionUID = 5047792897590881478L;
+    
+    /**
+     * The message. 
+     */
+    private String m_message;
+    
+    /**
+     * Creates a MissingHandlerException.
+     * This methods computes the message from
+     * the given list.
+     * @param missing the list of missing handlers.
+     */
+    public MissingHandlerException(List missing) {
+        super();
+        m_message = "Missing handlers : ";
+        for (int i = 0; i < missing.size(); i++) {
+            m_message += (String) missing.get(i) + " ";
+        }
+    }
+    
+    /**
+     * Gets the error message.
+     * @return the error message
+     * @see java.lang.Throwable#getMessage()
+     */
+    public String getMessage() {
+        return m_message;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Nullable.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Nullable.java
new file mode 100644
index 0000000..075f4c7
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Nullable.java
@@ -0,0 +1,33 @@
+/* 
+ * 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;
+
+/**
+ * A Nullable object must implement this interface.
+ * This allows to the code checking if the injected object is
+ * a Nullable object or not such as in:<br/>
+ * <code>if(foo instanceof Nullable){...}</code>
+ * <br/>
+ * This interface does not define any methods. Nullable objects owns
+ * the same methods than the 'real' object.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Nullable {
+    // Nothing
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Pojo.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Pojo.java
new file mode 100644
index 0000000..8bc7779
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/Pojo.java
@@ -0,0 +1,35 @@
+/* 
+ * 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;
+
+/**
+ * Interface implemented by each manipulated class. 
+ * This interface allows getting the component instance from the object.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Pojo {
+
+    /**
+     * Gets the instance container which creates the current object.
+     * @return the component instance which creates this object.
+     */
+    ComponentInstance getComponentInstance();
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
new file mode 100644
index 0000000..0153683
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PolicyServiceContext.java
@@ -0,0 +1,494 @@
+/* 
+ * 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;
+
+import java.io.File;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.BundleListener;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkListener;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * The policy service context is a service context aiming to resolve service dependencies
+ * inside different service context according to a policy.
+ * So, the policy service context behavior follows one of the three following policy:
+ * <li> Local : services are only resolved in the local service context.</li>
+ * <li> Global : services are only resolved in the global context (hte OSGi one)</li>
+ * <li> Local and Global : services are resolved inside the local context and inside
+ * the global context</li>
+ *    
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PolicyServiceContext implements ServiceContext {
+    
+    /**
+     * Resolving policy, resolves services only in the composite
+     * context (local).
+     * This policy is the default one for services inherited from
+     * service-level dependencies.
+     */
+    public static final int LOCAL = 0;
+    
+    /**
+     * Resolving policy, resolves services only in the composite
+     * (local) and in the global context.
+     * This policy is the default one for implementation dependency.
+     */
+    public static final int LOCAL_AND_GLOBAL = 1;
+    
+    /**
+     * Resolving policy, resolves services inside the global context
+     * only.
+     */
+    public static final int GLOBAL = 2;
+    
+    /**
+     * The global service registry.
+     * Targets the OSGi service registry.
+     */
+    public BundleContext m_global;
+    
+    /**
+     * The local (Composite) Service Registry.
+     */
+    public ServiceContext m_local;
+    
+    /**
+     * The resolving policy to use to resolve
+     * dependencies.
+     */
+    private int m_policy = LOCAL_AND_GLOBAL;
+    
+    
+    /**
+     * Creates a PolicyServiceContext.
+     * If the local context is null, sets the policy to
+     * {@link PolicyServiceContext#GLOBAL}, else use the 
+     * given policy.
+     * @param global the global bundle context
+     * @param local the parent (local) service context
+     * @param policy the resolution policy
+     */
+    public PolicyServiceContext(BundleContext global, ServiceContext local, int policy) {
+        m_global = global;
+        m_local = local;
+        if (m_local == null) {
+            m_policy = GLOBAL;
+        } else {
+            m_policy = policy;
+        }
+    }
+
+    /**
+     * Adds a service listener according to the policy.
+     * Be aware, that the listener can be registered both in the local and in the global context
+     * if the {@link PolicyServiceContext#LOCAL_AND_GLOBAL} is used.
+     * @param listener the listener to add
+     * @param filter the LDAP filter
+     * @throws InvalidSyntaxException if the filter is malformed.
+     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener, java.lang.String)
+     */
+    public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException {
+        if (m_policy == LOCAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_local.addServiceListener(listener, filter);
+        }
+        if (m_policy == GLOBAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_global.addServiceListener(listener, filter);
+        }
+
+    }
+
+    /**
+     * Adds a service listener according to the policy.
+     * Be aware, that the listener can be registered both in the local and in the global context
+     * if the {@link PolicyServiceContext#LOCAL_AND_GLOBAL} is used.
+     * @param listener the listener to add
+     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener)
+     */
+    public void addServiceListener(ServiceListener listener) {
+        if (m_policy == LOCAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_local.addServiceListener(listener);
+        }
+        if (m_policy == GLOBAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_global.addServiceListener(listener);
+        }
+    }
+
+    /**
+     * Gets all service references.
+     * These references are found inside the local registry, global registry or both according to the policy.
+     * The returned array can contain service references from both context.
+     * @param clazz the required service specification.
+     * @param filter the LDAP filter
+     * @return the array of service reference, <code>null</code> if no service available
+     * @throws InvalidSyntaxException if the LDAP filter is malformed 
+     * @see org.apache.felix.ipojo.ServiceContext#getAllServiceReferences(java.lang.String, java.lang.String)
+     */
+    public ServiceReference[] getAllServiceReferences(String clazz,
+            String filter) throws InvalidSyntaxException {
+        switch (m_policy) {
+            case LOCAL:
+                return m_local.getAllServiceReferences(clazz, filter);
+            case GLOBAL:
+                return m_global.getAllServiceReferences(clazz, filter);
+            case LOCAL_AND_GLOBAL:
+                ServiceReference[] refLocal = m_local.getAllServiceReferences(clazz, filter);
+                ServiceReference[] refGlobal = m_global.getAllServiceReferences(clazz, filter);
+                return computeServiceReferencesFromBoth(refLocal, refGlobal);
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Gets the service object for the given references.
+     * The service is get inside the context according to the policy.
+     * @param ref the service reference
+     * @return the service object
+     * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)
+     */
+    public Object getService(ServiceReference ref) {
+        switch(m_policy) { // NOPMD No break needed as we return in each branch.
+            case LOCAL:
+                // The reference comes from the local scope
+                return m_local.getService(ref);
+            case GLOBAL:
+                // The reference comes from the global registry
+                return m_global.getService(ref);
+            case LOCAL_AND_GLOBAL:
+                if (ref instanceof org.apache.felix.ipojo.context.ServiceReferenceImpl) {
+                    return m_local.getService(ref);
+                } else {
+                    return m_global.getService(ref);
+                }
+            default : 
+                return null;
+        }
+    }
+
+    /**
+     * Gets a service reference for the required service specification.
+     * The service is looked inside the context according to the policy.
+     * @param clazz the required service specification
+     * @return a service reference or <code>null</code> if no matching service available
+     * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
+     */
+    public ServiceReference getServiceReference(String clazz) {
+        switch (m_policy) { // NOPMD No break needed as we return in each branch.
+            case LOCAL:
+                return m_local.getServiceReference(clazz);
+            case GLOBAL:
+                return m_global.getServiceReference(clazz);
+            case LOCAL_AND_GLOBAL:
+                ServiceReference refLocal = m_local.getServiceReference(clazz);
+                if (refLocal == null) {
+                    return m_global.getServiceReference(clazz);
+                } else {
+                    return refLocal;
+                }
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Gets a service reference.
+     * This method is delegated on PolicyServiceContext#getServiceReference(String)
+     * @param sClass the service interface class
+     * @param <S> the service interface class
+     * @return the service reference of <code>null</code> if not found
+     * @see PolicyServiceContext#getServiceReference(String)
+     */
+    public <S> ServiceReference<S> getServiceReference(Class<S> sClass) {
+        return (ServiceReference<S>) getServiceReference(sClass.getName());
+    }
+
+    /**
+     * Gets a collection of service references
+     * @param clazz the service interface class
+     * @param filter the filter
+     * @param <S> the service interface class
+     * @return the set of service reference
+     * @throws InvalidSyntaxException the filter is invalid
+     * @see PolicyServiceContext#getServiceReferences(String, String)
+     */
+    public <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz, String filter) throws InvalidSyntaxException {
+         ServiceReference<S>[] refs =
+            (ServiceReference<S>[]) getServiceReferences(clazz.getName(), filter);
+        return (refs == null)
+            ? Collections.EMPTY_LIST
+            : (Collection<ServiceReference<S>>) Arrays.asList(refs);
+    }
+
+    /**
+     * Get a service reference for the required service specification.
+     * The services are looked inside the context according to the policy.
+     * @param clazz the required service specification
+     * @param filter the LDAP filter
+     * @return a service reference array or <code>null</code> if not consistent service available
+     * @throws InvalidSyntaxException if the LDAP filter is malformed 
+     * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
+     */
+    public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+        switch (m_policy) {
+            case LOCAL:
+                return m_local.getServiceReferences(clazz, filter);
+            case GLOBAL:
+                return m_global.getServiceReferences(clazz, filter);
+            case LOCAL_AND_GLOBAL:
+                ServiceReference[] refLocal = m_local.getServiceReferences(clazz, filter);
+                ServiceReference[] refGlobal = m_global.getServiceReferences(clazz, filter);
+                return computeServiceReferencesFromBoth(refLocal, refGlobal);
+            default:
+                return null;
+        }
+
+    }
+    
+    /**
+     * Computes the service reference array from the two given set of service references
+     * according to the policy.
+     * @param refLocal the set of local references
+     * @param refGlobal the set of global references
+     * @return the set of service references
+     */
+    private ServiceReference[] computeServiceReferencesFromBoth(ServiceReference[] refLocal, ServiceReference[] refGlobal) {
+        if (refLocal == null) {
+            return refGlobal; // If refGlobal is null, return null, else return refGlobal
+        } else if (refGlobal == null) { // refLocal != null && refGlobal == null
+            return refLocal;
+        } else { // Both refGlobal and refLocal are not null
+            ServiceReference[] refs = new ServiceReference[refLocal.length + refGlobal.length];
+            System.arraycopy(refLocal, 0, refs, 0, refLocal.length);
+            System.arraycopy(refGlobal, 0, refs, refLocal.length, refGlobal.length);
+            return refs;
+        }        
+    }
+
+    /**
+     * This method is not supported.
+     * This context can only be used to resolve service dependencies.
+     * @param clazzes the specifications
+     * @param service the service object
+     * @param properties the service properties
+     * @return the service registration object
+     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
+     */
+    public ServiceRegistration registerService(String[] clazzes, Object service, Dictionary properties) {
+        throw new UnsupportedOperationException("PolicyServiceContext can only be used for service dependency and not to provide services");
+    }
+
+    /**
+     * This method is not supported.
+     * This context can only be used to resolve service dependencies.
+     * @param clazz the specification
+     * @param service the service object
+     * @param properties the service properties to publish
+     * @return the service registration object
+     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
+     */
+    public ServiceRegistration registerService(String clazz, Object service, Dictionary properties) {
+        throw new UnsupportedOperationException("PolicyServiceContext can only be used for service dependency and not to provide services");
+    }
+
+    /**
+     * Removes a service listener.
+     * @param listener the service listener to remove
+     * @see org.apache.felix.ipojo.ServiceContext#removeServiceListener(org.osgi.framework.ServiceListener)
+     */
+    public void removeServiceListener(ServiceListener listener) {
+        if (m_policy == LOCAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_local.removeServiceListener(listener);
+        }
+        if (m_policy == GLOBAL || m_policy == LOCAL_AND_GLOBAL) {
+            m_global.removeServiceListener(listener);
+        }
+    }
+
+    /**
+     * Ungets the service reference.
+     * @param reference the service reference to unget.
+     * @return <code>true</code> if the service release if the reference is no more used.
+     * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)
+     */
+    public boolean ungetService(ServiceReference reference) {
+        if (reference instanceof org.apache.felix.ipojo.context.ServiceReferenceImpl) {
+            return m_local.ungetService(reference);
+        } else {
+            return m_global.ungetService(reference);
+        }
+    }
+
+    /**
+     * Adds a bundle listener.
+     * Delegate on the global bundle context.
+     * @param arg0 : bundle listener to add
+     * @see org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void addBundleListener(BundleListener arg0) {
+        m_global.addBundleListener(arg0);
+    }
+
+    /**
+     * Adds a framework listener.
+     * Delegates on the global bundle context.
+     * @param arg0 : framework listener to add.
+     * @see org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void addFrameworkListener(FrameworkListener arg0) {
+        m_global.addFrameworkListener(arg0);
+    }
+
+    /**
+     * Creates a LDAP filter.
+     * @param arg0 the String-form of the filter
+     * @return the created filter object
+     * @throws InvalidSyntaxException if the given argument is not a valid against the LDAP grammar.
+     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
+     */
+    public Filter createFilter(String arg0) throws InvalidSyntaxException {
+        return m_global.createFilter(arg0);
+    }
+
+    /**
+     * Gets a bundle by name
+     * @param s the name
+     * @return the matching bundle or <code>null</code> if not found
+     */
+    public Bundle getBundle(String s) {
+        return m_global.getBundle(s);
+    }
+
+    /**
+     * Gets the current bundle.
+     * @return the current bundle
+     * @see org.osgi.framework.BundleContext#getBundle()
+     */
+    public Bundle getBundle() {
+        return m_global.getBundle();
+    }
+
+    /**
+     * Gets the bundle object with the given id.
+     * @param bundleId the bundle id
+     * @return the bundle object
+     * @see org.osgi.framework.BundleContext#getBundle(long)
+     */
+    public Bundle getBundle(long bundleId) {
+        return m_global.getBundle(bundleId);
+    }
+
+    /**
+     * Gets installed bundles.
+     * @return the list of installed bundles
+     * @see org.osgi.framework.BundleContext#getBundles()
+     */
+    public Bundle[] getBundles() {
+        return m_global.getBundles();
+    }
+
+
+    /**
+     * Gets a data file.
+     * @param filename the File name.
+     * @return the File object
+     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
+     */
+    public File getDataFile(String filename) {
+        return m_global.getDataFile(filename);
+    }
+
+    /**
+     * Gets a property value.
+     * @param key the key of the asked property
+     * @return the property value (object) or <code>null</code> if no property
+     * are associated with the given key
+     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
+     */
+    public String getProperty(String key) {
+        return m_global.getProperty(key);
+    }
+
+    /**
+     * Installs a bundle.
+     * @param location the URL of the bundle to install
+     * @return the installed bundle
+     * @throws BundleException if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
+     */
+    public Bundle installBundle(String location) throws BundleException {
+        return m_global.installBundle(location);
+    }
+
+    /**
+     * Installs a bundle.
+     * @param location the URL of the bundle to install
+     * @param input the input stream to load the bundle content
+     * @return the installed bundle
+     * @throws BundleException if the bundle cannot be installed correctly
+     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, java.io.InputStream)
+     */
+    public Bundle installBundle(String location, InputStream input) throws BundleException {
+        return m_global.installBundle(location, input);
+    }
+
+    /**
+     * Removes the bundle listener.
+     * @param listener the listener to remove
+     * @see org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
+     */
+    public void removeBundleListener(BundleListener listener) {
+        m_global.removeBundleListener(listener);
+    }
+
+    /**
+     * Removes a framework listener.
+     * @param listener the listener to remove
+     * @see org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
+     */
+    public void removeFrameworkListener(FrameworkListener listener) {
+        m_global.removeFrameworkListener(listener);
+    }
+
+    /**
+     * Registers a service.
+     * Operation not supported.
+     * @param sClass
+     * @param s
+     * @param stringDictionary
+     * @param <S>
+     * @return
+     */
+    public <S> ServiceRegistration<S> registerService(Class<S> sClass, S s, Dictionary<String, ?> stringDictionary) {
+        throw new UnsupportedOperationException("PolicyServiceContext can only be used for service dependency and not to provide services");
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
new file mode 100644
index 0000000..2d70f25
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveHandler.java
@@ -0,0 +1,257 @@
+/*
+ * 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;
+
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Logger;
+
+
+/**
+* This class defines common mechanisms of primitive handlers.
+* Primitive handlers are handler composing the container of primitive
+* component instances (declared by the 'component' element inside the
+* iPOJO descriptor).
+* Note that this class also defines default method implementation.
+* Classes overriding this class can change the behavior of those methods.
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public abstract class PrimitiveHandler extends Handler implements FieldInterceptor, MethodInterceptor,
+    ConstructorInjector {
+
+    /**
+     * The "Primitive" Handler type (value).
+     */
+    public static final String HANDLER_TYPE = "primitive";
+
+    /**
+     * The reference on the instance manager.
+     */
+    private InstanceManager m_manager;
+
+
+    /**
+     * The factory of the instance manager.
+     */
+    private ComponentFactory m_factory;
+
+    /**
+     * Instance Logger used by the handler.
+     */
+    private Logger m_instanceLogger;
+
+    /**
+     * Attaches the current handler to the given instance.
+     * @param manager the instance on which the current handler will be attached.
+     * @see org.apache.felix.ipojo.Handler#attach(org.apache.felix.ipojo.ComponentInstance)
+     */
+    protected final void attach(ComponentInstance manager) {
+        m_manager = (InstanceManager) manager;
+        m_instanceLogger = m_manager.getLogger();
+    }
+
+    /**
+     * Sets the factory of the managed instance.
+     * @param factory the factory
+     * @see org.apache.felix.ipojo.Handler#setFactory(org.apache.felix.ipojo.Factory)
+     */
+    public final void setFactory(Factory factory) {
+        m_factory = (ComponentFactory) factory;
+    }
+
+    /**
+     * Gets the logger of the managed instance.
+     * IF no instance attached yet, use the factory logger.
+     * @return the logger to use to log messages.
+     * @see org.apache.felix.ipojo.Handler#getLogger()
+     */
+    public Logger getLogger() {
+        if (m_instanceLogger == null) {
+            return m_factory.getLogger();
+        }
+        return m_instanceLogger;
+    }
+
+    /**
+     * Gets the instance manager managing the instance.
+     * @return the instance manager
+     */
+    public InstanceManager getInstanceManager() {
+        return m_manager;
+    }
+
+    /**
+     * Gets the factory which creates the managed instance.
+     * @return the factory which creates the managed instance.
+     */
+    public ComponentFactory getFactory() {
+        return m_factory;
+    }
+
+    /**
+     * Gets the PojoMetadata of the content of the managed
+     * instance. This method allows getting manipulation
+     * metadata.
+     * @return the information about the content of the
+     * managed instance.
+     */
+    public PojoMetadata getPojoMetadata() {
+        return m_factory.getPojoMetadata();
+    }
+
+    /**
+     * Gets a plugged handler of the same container.
+     * This method must be called only in the start method (or after).
+     * In the configure method, this method can be inconsistent
+     * as all handlers are not initialized.
+     * @param name the name of the handler to find (class name or qualified
+     * handler name (<code>ns:name</code>)).
+     * @return the handler object or <code>null</code> if the handler is not found.
+     */
+    public final Handler getHandler(String name) {
+        return m_manager.getHandler(name);
+    }
+
+    /**
+     * Callback method called when a managed field
+     * receives a new value. The given pojo can be
+     * null if the new value is set by another handler.
+     * This default implementation does nothing.
+     * @param pojo the pojo object setting the value
+     * @param fieldName the field name
+     * @param value the value received by the field
+     * @see FieldInterceptor#onSet(Object, String, Object)
+     */
+    public void onSet(Object pojo, String fieldName, Object value) {
+        // Nothing to do in the default implementation
+    }
+
+    /**
+     * Callback method called when a managed field
+     * asks for a value.
+     * The default implementation returned the previously
+     * injected value.
+     * @param pojo the pojo object requiring the value
+     * @param fieldName the field name
+     * @param value the value passed to the field (by the previous call)
+     * @return the value to inject, of the previous value if the handler
+     * don't want to inject a value.
+     * @see FieldInterceptor#onGet(Object, String, Object)
+     */
+    public Object onGet(Object pojo, String fieldName, Object value) {
+        return value;
+    }
+
+    /**
+     * Gets the object to inject as a constructor parameter
+     * @param index the index of the parameter
+     * @return the object to inject, or <code>null</code> if no
+     * objects are injected. This implementation returns <code>null</code>
+     * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameter(int)
+     */
+    public Object getConstructorParameter(int index) {
+        return null;
+    }
+
+    /**
+     * Gets the type of the object to inject in the constructor parameter.
+     * This is the type looked into the Pojo class, so it must match.
+     * Returning <code>null</code> will try to get the class from the
+     * injected object, however this can be wrong (implementation instead of interface,
+     * boxed objects...) and error-prone.
+     * @param index the parameter index
+     * @return the Class object (must fit for primitive type), this implementation
+     * just returns <code>null</code>
+     * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameterType(int)
+     */
+    public Class getConstructorParameterType(int index) {
+        return null;
+    }
+
+    /**
+     * Callback method called when a method will be invoked.
+     * This default implementation does nothing.
+     * @param pojo the pojo on which the method is called.
+     * @param method the method invoked.
+     * @param args the arguments array.
+     * @see MethodInterceptor#onEntry(Object, Method, Object[])
+     */
+    public void onEntry(Object pojo, Member method, Object[] args) {
+        // Nothing to do in the default implementation
+    }
+
+    /**
+     * Callback method called when a method ends.
+     * This method is called when a thread exits a method (before a return or a throw).
+     * If the given returned object is <code>null</code>, either the method is
+     * <code>void</code>, or it returns <code>null</code>.
+     * You must not modified the returned object.
+     * The default implementation does nothing.
+     * @param pojo the pojo on which the method exits.
+     * @param method the exiting method.
+     * @param returnedObj the returned object (boxed for primitive type)
+     * @see MethodInterceptor#onExit(Object, Method, Object)
+     */
+    public void onExit(Object pojo, Member method, Object returnedObj) {
+        // Nothing to do in the default implementation
+    }
+
+    /**
+     * Callback method called when an error occurs.
+     * This method is called when the execution throws an exception
+     * in the given method.
+     * The default implementation does nothing.
+     * @param pojo the pojo on which the method was accessed.
+     * @param method the invoked method.
+     * @param throwable the thrown exception
+     * @see org.apache.felix.ipojo.MethodInterceptor#onError(java.lang.Object, java.lang.reflect.Method, java.lang.Throwable)
+     */
+    public void onError(Object pojo, Member method, Throwable throwable) {
+        // Nothing to do in the default implementation
+    }
+
+    /**
+     * Callback method called when the execution of a method will terminate :
+     * just before to throw an exception or before to return.
+     * {@link MethodInterceptor#onExit(Object, Method, Object)} or
+     * {@link MethodInterceptor#onError(Object, Method, Throwable)}
+     * were already called.
+     * This default implementation does nothing.
+     * @param pojo the pojo on which the method was accessed.
+     * @param method the invoked method.
+     */
+    public void onFinally(Object pojo, Member method) {
+        // Nothing to do in the default implementation
+    }
+
+    /**
+     * Callback method called when an instance of the component is created, but
+     * before someone can use it.
+     * The default implementation does nothing.
+     * @param instance the created instance
+     */
+    public void onCreation(Object instance) {
+        // Nothing to do in the default implementation
+    }
+
+
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveInstanceDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveInstanceDescription.java
new file mode 100644
index 0000000..e066251
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/PrimitiveInstanceDescription.java
@@ -0,0 +1,178 @@
+/*
+ * 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;
+
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler;
+import org.apache.felix.ipojo.handlers.configuration.ConfigurationHandlerDescription;
+import org.apache.felix.ipojo.handlers.dependency.DependencyDescription;
+import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
+import org.apache.felix.ipojo.handlers.dependency.DependencyHandlerDescription;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceDescription;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandlerDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Primitive Instance Description.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PrimitiveInstanceDescription extends InstanceDescription {
+
+    /**
+     * Creates a Primitive Instance Description.
+     * @param type the component type description
+     * @param instance the instance description
+     */
+    public PrimitiveInstanceDescription(ComponentTypeDescription type, InstanceManager instance) {
+        super(type, instance);
+    }
+
+    /**
+     * Gets the list of object created by the described instance.
+     * @return the created objects.
+     */
+    public String[] getCreatedObjects() {
+        Object [] objs = ((InstanceManager) m_instance).getPojoObjects();
+        if (objs != null) {
+            String[] result = new String[objs.length];
+            for (int i = 0; i < objs.length; i++) {
+                result[i] = objs[i].toString();
+            }
+            return result;
+        } else {
+            return new String[0];
+        }
+    }
+
+    /**
+     * Gets the instance service dependencies.
+     * @return the set of dependency description or an empty array if
+     * no dependencies.
+     */
+    public DependencyDescription[] getDependencies() {
+        Handler handler =  ((InstanceManager) m_instance).getHandler("org.apache.felix.ipojo:requires");
+        if (handler == null) {
+            return new DependencyDescription[0];
+        } else {
+            return ((DependencyHandlerDescription) ((DependencyHandler) handler)
+                    .getDescription()).getDependencies();
+        }
+    }
+
+    /**
+     * Gets the instance service dependency matching with the given service specification or id.
+     * @param specification the service specification of the looked specification.
+     * @return the dependency description matching with the given service specification or id.
+     * <code>null</code> is not found.
+     * no dependencies.
+     */
+    public DependencyDescription getDependency(String specification) {
+        DependencyDescription[] deps =  getDependencies();
+        if (deps == null) {
+            return null;
+        } else {
+            for (int i = 0; i < deps.length; i++) {
+                if (specification.equals(deps[i].getId())
+                        || specification.equals(deps[i].getSpecification())) {
+                    return deps[i];
+                }
+
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets the instance provided service matching with the given service specification.
+     * @param specification the provided specification of the looked provided service.
+     * @return the provided service description matching with the given service specification.
+     * <code>null</code> is not found.
+     */
+    public ProvidedServiceDescription getProvidedService(String specification) {
+        ProvidedServiceDescription[] pss =  getProvidedServices();
+        if (pss == null) {
+            return null;
+        } else {
+            for (int i = 0; i < pss.length; i++) {
+                String[] str = pss[i].getServiceSpecifications();
+                for  (int j = 0; j < str.length; j++) {
+                    if (specification.equals(str[j])) {
+                        return pss[i];
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets the instance provided service.
+     * @return the set of provided service description or an empty array if
+     * no provided services.
+     */
+    public ProvidedServiceDescription[] getProvidedServices() {
+        Handler handler =  ((InstanceManager) m_instance).getHandler("org.apache.felix.ipojo:provides");
+        if (handler == null) {
+            return new ProvidedServiceDescription[0];
+        } else {
+            return ((ProvidedServiceHandlerDescription) ((ProvidedServiceHandler) handler)
+                    .getDescription()).getProvidedServices();
+        }
+    }
+
+    /**
+     * Gets the instance properties.
+     * @return the set of property descriptions or an empty array if
+     * no properties.
+     */
+    public PropertyDescription[] getProperties() {
+        Handler handler =  ((InstanceManager) m_instance).getHandler("org.apache.felix.ipojo:properties");
+        if (handler == null) {
+            return new PropertyDescription[0];
+        } else {
+            return ((ConfigurationHandlerDescription) ((ConfigurationHandler) handler)
+                    .getDescription()).getProperties();
+        }
+    }
+
+    /**
+     * Gets the instance description.
+     * Overridden to add created objects.
+     * @return the instance description
+     */
+    public Element getDescription() {
+        Element elem = super.getDescription();
+        // Created Object (empty is composite)
+        String[] objs = getCreatedObjects();
+        for (int i = 0; objs != null  && i < objs.length; i++) {
+            Element obj = new Element("Object", "");
+            obj.addAttribute(new Attribute("name", ((Object) objs[i]).toString()));
+            elem.addElement(obj);
+        }
+        return elem;
+    }
+
+
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java
new file mode 100644
index 0000000..7d3765c
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/ServiceContext.java
@@ -0,0 +1,149 @@
+/* 
+ * 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;
+
+import java.util.Dictionary;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * A service context is the facade of a service registry. 
+ * It gives the access to a service broker. All service
+ * interactions should use a service context to garanty
+ * the service isolation.
+ * This class is a subset of {@link BundleContext} methods.
+ * (methods implying interactions with the service registry).
+ * So, refer to this class for further information.
+ * @see BundleContext
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ServiceContext extends BundleContext {
+
+    /**
+     * Adds a service listener.
+     * The listener is added to this service context.
+     * So only services from this context will be tracked.
+     * @param listener the service listener to add.
+     * @param filter the LDAP filter
+     * @throws InvalidSyntaxException if the LDAP filter is malformed
+     * @see org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener, java.lang.String)
+     */
+    void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException;
+
+    /**
+     * Adds a service listener.
+     * The listener is added to this service context.
+     * So only services from this context will be tracked.
+     * @param listener the service listener to add.
+     * @see org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener)
+     */
+    void addServiceListener(ServiceListener listener);
+
+    /**
+     * Gets the service references matching with the given query.
+     * The query is executed inside this service context.
+     * @param clazz the required interface
+     * @param filter a LDAP filter
+     * @return the array of available service references or <code>null</code>
+     * if no providers are available.
+     * @throws InvalidSyntaxException if the LDAP filter is malformed
+     * @see org.osgi.framework.BundleContext#getAllServiceReferences(java.lang.String, java.lang.String)
+     */
+    ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
+
+    /**
+     * Gets a service object.
+     * The given service reference must comes from this
+     * service context.
+     * @param reference the required service reference 
+     * @return the service object or null if the service reference is no more valid or if the service object is not accessible
+     * @see org.osgi.framework.BundleContext#getService(org.osgi.framework.ServiceReference)
+     */
+    <S> S getService(ServiceReference<S> reference);
+
+    /**
+     * Gets a service reference for the given interface.
+     * The query is executed inside this service context.
+     * @param clazz the required interface name
+     * @return a service reference on a available provider or 
+     * <code>null</code> if no providers are available
+     * @see org.osgi.framework.BundleContext#getServiceReference(java.lang.String)
+     */
+    ServiceReference getServiceReference(String clazz);
+
+    /**
+     * Gets service reference list for the given query.
+     * The query is executed inside this service context.
+     * @param clazz : the name of the required service interface
+     * @param filter : LDAP filter to apply on service provider
+     * @return : the array of consistent service reference or <code>null</code>
+     * if no available providers
+     * @throws InvalidSyntaxException if the LDAP filter is malformed
+     * @see org.osgi.framework.BundleContext#getServiceReferences(java.lang.String, java.lang.String)
+     */
+    ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException;
+
+    /**
+     * Registers a service inside this service context.
+     * This service is then isolated inside this context.
+     * @param clazzes the interfaces provided by the service.
+     * @param service the service object.
+     * @param properties service properties to publish
+     * @return the service registration for this service publication.
+     * This service registration is attached to the current service context,
+     * and does not have any meaning in other contexts.
+     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
+     */
+    ServiceRegistration registerService(String[] clazzes, Object service, Dictionary<String, ?> properties);
+
+    /**
+     * Registers a service inside this service context.
+     * This service is then isolated inside this context.
+     * @param clazz the interface provided by the service.
+     * @param service the service object.
+     * @param properties service properties to publish.
+     * @return the service registration for this service publication. 
+     * This service registration is attached to the current service context,
+     * and does not have any meaning in other contexts.
+     * @see org.osgi.framework.BundleContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
+     */
+    ServiceRegistration registerService(String clazz, Object service, Dictionary<String, ?> properties);
+
+    /**
+     * Removes a service listener.
+     * The listener must be registered inside this service context.
+     * @param listener the listener to remove
+     * @see org.osgi.framework.BundleContext#removeServiceListener(org.osgi.framework.ServiceListener)
+     */
+    void removeServiceListener(ServiceListener listener);
+
+    /**
+     * Ungets the service reference.
+     * The service reference must comes from this service context.
+     * @param reference the reference to unget
+     * @return <code>true</code> if you are the last user of the reference.
+     * @see org.osgi.framework.BundleContext#ungetService(org.osgi.framework.ServiceReference)
+     */
+    boolean ungetService(ServiceReference<?> reference);
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/UnacceptableConfiguration.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/UnacceptableConfiguration.java
new file mode 100644
index 0000000..dab2c99
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/UnacceptableConfiguration.java
@@ -0,0 +1,44 @@
+/* 
+ * 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;
+
+/**
+ * UnacceptableConfiguration occurs when a factory refuses to create an
+ * instance. This exception is thrown when the instance configuration does not
+ * specify a value for a required property or when the configuration tries to override
+ * the value of an immutable property
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class UnacceptableConfiguration extends Exception {
+
+    /**
+     * Exception UID.
+     */
+    private static final long serialVersionUID = 2998931848886223965L;
+
+    /**
+     * Creates an UnacceptableConfiguration.
+     * @param message : message about the error.
+     */
+    public UnacceptableConfiguration(String message) {
+        super(message);
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java
new file mode 100644
index 0000000..db23941
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/Architecture.java
@@ -0,0 +1,35 @@
+/* 
+ * 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.architecture;
+
+/**
+ * Architecture service.
+ * This service allows collecting information on the component instance,
+ * such as its state, plugged handlers ...
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface Architecture {
+
+    /**
+     * Returns the description of the instance.
+     * @return the component instance description
+     */
+    InstanceDescription getInstanceDescription();
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
new file mode 100644
index 0000000..f7a3ce5
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/ComponentTypeDescription.java
@@ -0,0 +1,266 @@
+/*
+ * 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.architecture;
+
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.IPojoFactory;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+/**
+ * Component Type description.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ComponentTypeDescription {
+
+    /**
+     * Provided service by the component type.
+     */
+    private String[] m_providedServiceSpecification = new String[0];
+
+    /**
+     * Configuration Properties accepted by the component type.
+     */
+    private PropertyDescription[] m_properties = new PropertyDescription[0];
+
+    /**
+     * Represented factory.
+     */
+    private final IPojoFactory m_factory;
+
+    /**
+     * Constructor.
+     * @param factory : represented factory.
+     */
+    public ComponentTypeDescription(IPojoFactory factory) {
+        m_factory = factory;
+    }
+
+    /**
+     * Gets the attached factory.
+     * @return the factory
+     */
+    public IPojoFactory getFactory() {
+        return m_factory;
+    }
+
+    /**
+     * Gets a printable form of the current component type description.
+     * @return printable form of the component type description
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return getDescription().toString();
+    }
+
+    /**
+     * Gets the implementation class of this component type.
+     * @return the component type implementation class name.
+     * @deprecated
+     */
+    public String getClassName() {
+        return m_factory.getClassName();
+    }
+
+    /**
+     * Gets the component type version.
+     * @return the component type version or
+     * <code>null</code> if not set.
+     */
+    public String getVersion() {
+        return m_factory.getVersion();
+    }
+
+    /**
+     * Gets component-type properties.
+     * @return the list of configuration properties accepted by the component type type.
+     */
+    public PropertyDescription[] getProperties() {
+        return m_properties;
+    }
+
+    /**
+     * Adds a String property in the component type.
+     * @param name : property name.
+     * @param value : property value.
+     */
+    public void addProperty(String name, String value) {
+        addProperty(name, value, false);
+    }
+
+    /**
+     * Adds a String property in the component type.
+     * @param name : property name.
+     * @param value : property value.
+     * @param immutable : the property is immutable.
+     */
+    public void addProperty(String name, String value, boolean immutable) {
+        PropertyDescription prop = new PropertyDescription(name, String.class.getName(), value);
+        addProperty(prop);
+    }
+
+    /**
+     * Adds a configuration properties to the component type.
+     * @param pd : the property to add
+     */
+    public void addProperty(PropertyDescription pd) { //NOPMD remove the instance name of the 'name' property.
+        String name = pd.getName();
+
+        // Check if the property is not already in the array
+        for (int i = 0; i < m_properties.length; i++) {
+            PropertyDescription desc = m_properties[i];
+            if (desc.getName().equals(name)) { return; }
+        }
+
+        PropertyDescription[] newProps = new PropertyDescription[m_properties.length + 1];
+        System.arraycopy(m_properties, 0, newProps, 0, m_properties.length);
+        newProps[m_properties.length] = pd;
+        m_properties = newProps;
+    }
+
+    /**
+     * Gets the list of provided service offered by instances of this type.
+     * @return the list of the provided service.
+     */
+    public String[] getprovidedServiceSpecification() {
+        return m_providedServiceSpecification;
+    }
+
+    /**
+     * Adds a provided service to the component type.
+     * @param serviceSpecification : the provided service to add (interface name)
+     */
+    public void addProvidedServiceSpecification(String serviceSpecification) {
+        String[] newSs = new String[m_providedServiceSpecification.length + 1];
+        System.arraycopy(m_providedServiceSpecification, 0, newSs, 0, m_providedServiceSpecification.length);
+        newSs[m_providedServiceSpecification.length] = serviceSpecification;
+        m_providedServiceSpecification = newSs;
+    }
+
+    /**
+     * Returns the component-type name.
+     * @return the name of this component type
+     */
+    public String getName() {
+        return m_factory.getName();
+    }
+
+    /**
+     * Computes the default service properties to publish :
+     * factory.name, service.pid, component.providedServiceSpecification, component.properties, component.description, factory.State.
+     * @return : the dictionary of properties to publish.
+     */
+    public Dictionary getPropertiesToPublish() {
+        Properties props = new Properties();
+
+        props.put("factory.name", m_factory.getName());
+        props.put(Constants.SERVICE_PID, m_factory.getName()); // Service PID is required for the integration in the configuration admin.
+
+        // Add the version if set
+        String v = getVersion();
+        if (v != null) {
+            props.put("factory.version", v);
+        }
+
+        props.put("component.providedServiceSpecifications", m_providedServiceSpecification);
+        props.put("component.properties", m_properties);
+        props.put("component.description", this);
+
+        // add every immutable property
+        for (int i = 0; i < m_properties.length; i++) {
+            if (m_properties[i].isImmutable() && m_properties[i].getValue() != null) {
+                props.put(m_properties[i].getName(), m_properties[i].getObjectValue(m_factory.getBundleContext()));
+            }
+        }
+
+        // Add factory state
+        props.put("factory.state", new Integer(m_factory.getState()));
+
+        return props;
+
+    }
+
+    /**
+     * Gets the interfaces published by the factory.
+     * By default publish both {@link Factory} and {@link ManagedServiceFactory}.
+     * @return : the list of interface published by the factory.
+     */
+    public String[] getFactoryInterfacesToPublish() {
+        return new String[] {Factory.class.getName(), ManagedServiceFactory.class.getName()};
+    }
+
+    /**
+     * Gets the component type description.
+     * @return : the description
+     */
+    public Element getDescription() {
+        Element desc = new Element("Factory", "");
+
+        desc.addAttribute(new Attribute("name", m_factory.getName()));
+        desc.addAttribute(
+                          new Attribute("bundle",
+                                          Long.toString(((ComponentFactory) m_factory).getBundleContext().getBundle().getBundleId())));
+
+        String state = "valid";
+        if (m_factory.getState() == Factory.INVALID) {
+            state = "invalid";
+        }
+        desc.addAttribute(new Attribute("state", state));
+
+        // Display required & missing handlers
+        Element req = new Element("RequiredHandlers", "");
+        req.addAttribute(new Attribute("list", m_factory.getRequiredHandlers().toString()));
+        Element missing = new Element("MissingHandlers", "");
+        missing.addAttribute(new Attribute("list", m_factory.getMissingHandlers().toString()));
+        desc.addElement(req);
+        desc.addElement(missing);
+
+        for (int i = 0; i < m_providedServiceSpecification.length; i++) {
+            Element prov = new Element("provides", "");
+            prov.addAttribute(new Attribute("specification", m_providedServiceSpecification[i]));
+            desc.addElement(prov);
+        }
+
+        for (int i = 0; i < m_properties.length; i++) {
+            Element prop = new Element("property", "");
+            prop.addAttribute(new Attribute("name", m_properties[i].getName()));
+            prop.addAttribute(new Attribute("type", m_properties[i].getType()));
+            if (m_properties[i].isMandatory()  && m_properties[i].getValue() == null) {
+                prop.addAttribute(new Attribute("value", "REQUIRED"));
+            } else {
+                prop.addAttribute(new Attribute("value", m_properties[i].getValue()));
+            }
+            desc.addElement(prop);
+        }
+
+        return desc;
+    }
+
+    public BundleContext getBundleContext() {
+        return m_factory.getBundleContext();
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
new file mode 100644
index 0000000..ffc64c8
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/HandlerDescription.java
@@ -0,0 +1,86 @@
+/* 
+ * 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.architecture;
+
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Handler Description.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class HandlerDescription {
+
+    /**
+     * The Handler Qualified Name.
+     */
+    private String m_handlerName;
+
+
+    /**
+     * The described handler instance.
+     */
+    private Handler m_handler;
+
+    /**
+     * Creates a handler description.
+     * @param handler the handler.
+     */
+    public HandlerDescription(Handler handler) {
+        HandlerFactory factory = (HandlerFactory) handler.getHandlerManager().getFactory();
+        m_handlerName = factory.getHandlerName();
+        m_handler = handler;
+    }
+
+    /**
+     * Checks if the handler is valid.
+     * @return true if the handler is valid.
+     */
+    public boolean isValid() {
+        return m_handler.isValid();
+    }
+
+    /**
+     * Gets the handler name.
+     * @return the handler qualified name (i.e. namespace:name).
+     */
+    public String getHandlerName() {
+        return m_handlerName;
+    }
+
+    /**
+     * Gets handler information.
+     * This represent the actual state of the handler.
+     * @return the handler information.
+     */
+    public Element getHandlerInfo() {
+        Element elem = new Element("Handler", "");
+        elem.addAttribute(new Attribute("name", m_handlerName));
+        if (isValid()) {
+            elem.addAttribute(new Attribute("state", "valid"));
+        } else {
+            elem.addAttribute(new Attribute("state", "invalid"));
+        }
+        return elem;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
new file mode 100644
index 0000000..632722c
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/InstanceDescription.java
@@ -0,0 +1,195 @@
+/* 
+ * 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.architecture;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.InstanceStateListener;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Instance Description.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class InstanceDescription implements InstanceStateListener {
+   
+    /**
+     * The list of handlers plugged on the component instance.
+     */
+    protected HandlerDescription[] m_handlers = new HandlerDescription[0];
+    
+    /**
+     * The Underlying component instance.
+     */
+    protected ComponentInstance m_instance;
+
+    /**
+     * Component Type of the instance.
+     */
+    protected ComponentTypeDescription m_type;
+
+    /**
+     * Creates the instance description.
+     * @param ci  the state of the instance.
+     * @param desc  the component type description of this instance.
+     */
+    public InstanceDescription(ComponentTypeDescription desc, ComponentInstance ci) {
+        m_handlers = new HandlerDescription[0];
+        m_type = desc;
+        m_instance = ci;
+        m_instance.addInstanceStateListener(this);
+    }
+
+    /**
+     * Gets the instance name.
+     * @return the name of the instance.
+     */
+    public String getName() {
+        return m_instance.getInstanceName();
+    }
+
+    /**
+     * Gets the component type description of the described instance.
+     * @return : the component type description of this instance.
+     */
+    public ComponentTypeDescription getComponentDescription() {
+        return m_type;
+    }
+
+    /**
+     * Gets the plugged handler list.
+     * @return the live handler list
+     */
+    public HandlerDescription[] getHandlers() {
+        return m_handlers;
+    }
+
+    /**
+     * Adds an handler description to the list.
+     * @param desc : the handler description to add
+     */
+    public void addHandler(HandlerDescription desc) {
+        // Verify that the dependency description is not already in the array.
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i] == desc) {
+                return; // NOTHING TO DO, the description is already in the
+                        // array
+            }
+        }
+        // The component Description is not in the array, add it
+        HandlerDescription[] newHd = new HandlerDescription[m_handlers.length + 1];
+        System.arraycopy(m_handlers, 0, newHd, 0, m_handlers.length);
+        newHd[m_handlers.length] = desc;
+        m_handlers = newHd;
+    }
+    
+    /**
+     * Gets a handler description by specifying the handler qualified name.
+     * This method ignores case of the given handler name.
+     * @param handler the handler name
+     * @return the handler description or <code>null</code> if not found
+     */
+    public HandlerDescription getHandlerDescription(String handler) {
+        for (int i = 0; i < m_handlers.length; i++) {
+            if (m_handlers[i].getHandlerName().equalsIgnoreCase(handler)) {
+                return m_handlers[i];
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets the state of the described instance.
+     * @return the state of the instance.
+     */
+    public int getState() {
+        waitForStability();
+        return m_instance.getState();
+    }
+
+    /**
+     * Gets the bundle id of the bundle containing the component type of the instance.
+     * @return the bundle id owning the component implementation class.
+     */
+    public long getBundleId() {
+        return m_instance.getFactory().getBundleContext().getBundle().getBundleId();
+    }
+
+    /**
+     * Gets the instance description.
+     * @return the instance description
+     */
+    public Element getDescription() {
+        Element instance = new Element("Instance", "");
+        instance.addAttribute(new Attribute("name", getName())); // Name
+        
+        int state = getState();
+        if (state == ComponentInstance.STOPPED) {
+            instance.addAttribute(new Attribute("state", "stopped"));
+        }
+        if (state == ComponentInstance.VALID) {
+            instance.addAttribute(new Attribute("state", "valid"));
+        }
+        if (state == ComponentInstance.INVALID) {
+            instance.addAttribute(new Attribute("state", "invalid"));
+        }
+        if (state == ComponentInstance.DISPOSED) {
+            instance.addAttribute(new Attribute("state", "disposed"));
+        }
+        // Bundle
+        instance.addAttribute(new Attribute("bundle", Long.toString(getBundleId())));
+
+        // Component Type
+        instance.addAttribute(new Attribute("component.type", m_type.getName()));
+
+        // Handlers
+        for (int i = 0; i < m_handlers.length; i++) {
+            instance.addElement(m_handlers[i].getHandlerInfo());
+        }
+
+        return instance;
+
+    }
+
+    /**
+     * Waits for state stability before returning results.
+     */
+    private synchronized void waitForStability() {
+        while (m_instance.getState() == -2) { // Transition
+            try {
+                wait();
+            } catch (InterruptedException e) {
+               // We're interrupted, will re-check the condition.
+            }
+        }
+        
+    }
+
+    /**
+     * The underlying instance state changes.
+     * @param instance the instance
+     * @param newState the new state
+     * @see org.apache.felix.ipojo.InstanceStateListener#stateChanged(org.apache.felix.ipojo.ComponentInstance, int)
+     */
+    public synchronized void stateChanged(ComponentInstance instance, int newState) {
+        notifyAll(); // if we was in a transition, the transition is now done.
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
new file mode 100644
index 0000000..4b037b4
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/architecture/PropertyDescription.java
@@ -0,0 +1,200 @@
+/* 
+ * 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.architecture;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler;
+import org.apache.felix.ipojo.util.Property;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Property Information.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PropertyDescription {
+
+    /**
+     * Name of the property.
+     */
+    private String m_name;
+
+    /**
+     * Type of the property.
+     */
+    private String m_type;
+
+    /**
+     * Value of the property.
+     */
+    private String m_value = null;
+    
+    /**
+     * Attached property object.
+     */
+    private Property m_property;
+    
+    
+    /**
+     * Immutable property flag
+     * If set to <code>true</code>, the property cannot be override by the instance configuration.
+     * Moreover, immutable properties are exposed on the factory service too.
+     */
+    private boolean m_immutable = false;
+    
+    /**
+     * A property is mandatory. So, either the component type description provides a value or
+     * the instance configuration must provide a value. Immutable properties are mandatories. 
+     */
+    private boolean m_isMandatory = false;
+
+    /**
+     * Constructor.
+     * 
+     * @param name the name of the property
+     * @param type the type of the property
+     * @param value the default value of the property, can be <code>null</code>
+     */
+    public PropertyDescription(String name, String type, String value) {
+        m_name = name;
+        m_type = type;
+        m_value = value;
+    }
+    
+    /**
+     * Constructor.
+     * 
+     * @param prop the attache Property object.
+     */
+    public PropertyDescription(Property prop) {
+        m_property = prop;
+        m_name = prop.getName();
+        m_type = prop.getType();
+        m_value = null; // Living property, value will be asked at runtime.
+    }
+    
+    /**
+     * Constructor.
+     * 
+     * @param name the name of the property
+     * @param type the type of the property
+     * @param value the default value (String form) of the property, can be <code>null</code>
+     * @param immutable the property is immutable.
+     */
+    public PropertyDescription(String name, String type, String value, boolean immutable) {
+        m_name = name;
+        m_type = type;
+        m_value = value;
+        m_immutable = immutable;
+    }
+
+    /**
+     * Gets the current property name.
+     * @return the property name.
+     */
+    public String getName() {
+        return m_name;
+    }
+
+    /**
+     * Gets the current property type.
+     * @return the property type.
+     */
+    public String getType() {
+        return m_type;
+    }
+
+    /**
+     * Gets the current property value.
+     * @return the default value for the property,
+     * <code>null</code> if the property hasn't a value..
+     */
+    public String getValue() {
+        if (m_property == null) {
+            return m_value;
+        } else {
+            Object value =  m_property.getValue();
+            if (value == null) {
+                return "null";
+            } else {
+                return value.toString();
+            }
+        }
+    }
+    
+    /**
+     * Sets the property value.
+     * This method can only be called on 'living' property
+     * (properties with a {@link Property} object).
+     * @param value the new value.
+     */
+    public void setValue(Object value) {
+        if (m_property == null) {
+            throw new UnsupportedOperationException("Cannot set the value of a non 'living' property");
+        } else {
+            ConfigurationHandler handler = (ConfigurationHandler) m_property.getHandler();
+            handler.reconfigureProperty(m_property, value);
+        }
+    }
+    
+    /**
+     * Is the property immutable.
+     * @return <code>true</code> if the property is immutable.
+     */
+    public boolean isImmutable() {
+        return m_immutable;
+    }
+    
+    /**
+     * Sets the property as mandatory.
+     */
+    public void setMandatory() {
+        m_isMandatory = true;
+    }
+    
+    /**
+     * Is the property mandatory.
+     * @return <code>true</code> if the property is mandatory,
+     * <code>false</code> otherwise.
+     */
+    public boolean isMandatory() {
+        return m_isMandatory;
+    }
+    
+    /**
+     * Gets the object value of the current immutable property.
+     * @param context  the bundle context to use to load classes.
+     * @return the object value of the current property or <code>
+     * null</code> if the current value is <code>null</code>.
+     */
+    public Object getObjectValue(BundleContext context) {
+        if (m_value == null) {
+            return null;
+        }
+        
+        Class type = null;
+        try {
+            type = Property.computeType(m_type, context);
+            return Property.create(type, m_value);
+        } catch (ConfigurationException e) {
+            return m_value; // Cannot create the object.
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/ServiceReferenceImpl.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/ServiceReferenceImpl.java
new file mode 100644
index 0000000..9889882
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/ServiceReferenceImpl.java
@@ -0,0 +1,156 @@
+/* 
+ * 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.context;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Internal service reference implementation. This class is used for in the
+ * composition.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceReferenceImpl implements ServiceReference {
+
+    /**
+     * Service Registration attached to the service reference.
+     */
+    private ServiceRegistrationImpl m_registration = null;
+    
+    /**
+     * Component Instance.
+     */
+    private ComponentInstance m_cm;
+
+    /**
+     * Constructor.
+     * 
+     * @param instance : component instance publishing the service.
+     * @param ref : registration attached to this service reference.
+     */
+    public ServiceReferenceImpl(ComponentInstance instance, ServiceRegistrationImpl ref) {
+        m_registration = ref;
+        m_cm = instance;
+    }
+
+    /**
+     * Not supported in composite.
+     * @return null
+     * @see org.osgi.framework.ServiceReference#getBundle()
+     */
+    public Bundle getBundle() {
+        return m_cm.getContext().getBundle();
+    }
+
+    /**
+     * Get the service registration for this reference.
+     * @return the service registration for this service reference.
+     */
+    public ServiceRegistrationImpl getServiceRegistration() {
+        return m_registration;
+    }
+
+
+    /**
+     * Get a property value.
+     * @param name : the key of the required property.
+     * @return the property value or null if no property for the given key.
+     * @see org.osgi.framework.ServiceReference#getProperty(java.lang.String)
+     */
+    public Object getProperty(String name) {
+        return m_registration.getProperty(name);
+    }
+
+    /**
+     * Get the String arrays of service property keys.
+     * @return : the list of property keys.
+     * @see org.osgi.framework.ServiceReference#getPropertyKeys()
+     */
+    public String[] getPropertyKeys() {
+        return m_registration.getPropertyKeys();
+    }
+    
+    public Dictionary getProperties() {
+        return m_registration.getProperties();
+    }
+
+
+    /**
+     * Unsupported Operation inside composite.
+     * @return bundles using this reference.
+     * @see org.osgi.framework.ServiceReference#getUsingBundles()
+     */
+    public Bundle[] getUsingBundles() {
+        throw new UnsupportedOperationException("getUsingBundles is not supported in service context");
+    }
+
+    /**
+     * Check if the current service reference is assignable to the given bundle.
+     * @param arg0 : the bundle to check
+     * @param arg1 : the class name to check.
+     * @return true in the case of composite
+     * @see org.osgi.framework.ServiceReference#isAssignableTo(org.osgi.framework.Bundle, java.lang.String)
+     */
+    public boolean isAssignableTo(Bundle arg0, String arg1) {
+        return true;
+    }
+
+    /**
+     * Service Reference compare method.
+     * @param reference the service reference
+     * @return this methods is not yet supported, and throws an
+     *         {@link UnsupportedOperationException}.
+     * @see org.osgi.framework.ServiceReference#compareTo(java.lang.Object)
+     */
+    public int compareTo(Object reference) {
+
+        ServiceReference other = (ServiceReference) reference;
+
+        Long id = (Long) getProperty(Constants.SERVICE_ID);
+        Long otherId = (Long) other.getProperty(Constants.SERVICE_ID);
+
+        if (id.equals(otherId)) {
+            return 0; // same service
+        }
+
+        Integer rank = (Integer) getProperty(Constants.SERVICE_RANKING);
+        Integer otherRank = (Integer) other
+                .getProperty(Constants.SERVICE_RANKING);
+
+        // If no rank, then spec says it defaults to zero.
+        rank = (rank == null) ? new Integer(0) : rank;
+        otherRank = (otherRank == null) ? new Integer(0) : otherRank;
+
+        // Sort by rank in ascending order.
+        if (rank.compareTo(otherRank) < 0) {
+            return -1; // lower rank
+        } else if (rank.compareTo(otherRank) > 0) {
+            return 1; // higher rank
+        }
+
+        // If ranks are equal, then sort by service id in descending order.
+        return (id.compareTo(otherId) < 0) ? 1 : -1;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistrationImpl.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistrationImpl.java
new file mode 100644
index 0000000..0dc8dfb
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistrationImpl.java
@@ -0,0 +1,272 @@
+/* 
+ * 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.context;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.InstanceManager;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Internal service registration implementation. This class is used for in the
+ * composition.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceRegistrationImpl implements ServiceRegistration {
+
+    /**
+     * Service Registry.
+     */
+    private ServiceRegistry m_registry = null;
+
+    /**
+     * Interfaces associated with the service object.
+     */
+    private String[] m_classes = null;
+
+    /**
+     * Service Id associated with the service object.
+     */
+    private Long m_serviceId = null;
+
+    /**
+     * Service object.
+     */
+    private Object m_svcObj = null;
+
+    /**
+     * Service factory interface.
+     */
+    private ServiceFactory m_factory = null;
+
+    /**
+     * Associated property dictionary.
+     */
+    private Map m_propMap = null;
+
+    /**
+     * Re-usable service reference.
+     */
+    private ServiceReferenceImpl m_ref = null;
+
+    /**
+     * Property Keys List.
+     */
+    private List m_list = new ArrayList();
+
+    /**
+     * Constructor.
+     * 
+     * @param registry : the service registry
+     * @param instance : component instance
+     * @param classes : published interfaces array
+     * @param serviceId : the unique service id
+     * @param svcObj : the service object or the service factory object
+     * @param dict : service properties
+     */
+    public ServiceRegistrationImpl(ServiceRegistry registry, ComponentInstance instance, String[] classes, Long serviceId, Object svcObj, Dictionary dict) {
+        m_registry = registry;
+        m_classes = classes;
+        m_serviceId = serviceId;
+        m_svcObj = svcObj;
+        if (m_svcObj instanceof ServiceFactory) { m_factory = (ServiceFactory) m_svcObj; }
+        initializeProperties(dict);
+
+        // This reference is the "standard" reference for this service and will
+        // always be returned by getReference().
+        // Since all reference to this service are supposed to be equal, we use
+        // the hash code of this reference for
+        // a references to this service in ServiceReference.
+        m_ref = new ServiceReferenceImpl(instance, this);
+    }
+
+    /**
+     * Check if the service registration still valid.
+     * @return true if the service registration is valid.
+     */
+    protected boolean isValid() {
+        return m_svcObj != null;
+    }
+
+    /**
+     * Get the service reference attached with this service registration.
+     * @return the service reference
+     * @see org.osgi.framework.ServiceRegistration#getReference()
+     */
+    public ServiceReference getReference() {
+        return m_ref;
+    }
+
+    /**
+     * Add properties to a service registration.
+     * @param dict : the properties to add
+     * @see org.osgi.framework.ServiceRegistration#setProperties(java.util.Dictionary)
+     */
+    public void setProperties(Dictionary dict) {
+        // Make sure registration is valid.
+        if (!isValid()) {
+            throw new IllegalStateException("The service registration is no longer valid.");
+        }
+        // Set the properties.
+        initializeProperties(dict);
+        // Tell registry about it.
+        m_registry.servicePropertiesModified(this);
+    }
+
+    /**
+     * Unregister the service.
+     * @see org.osgi.framework.ServiceRegistration#unregister()
+     */
+    public void unregister() {
+        if (m_svcObj == null) {
+            throw new IllegalStateException("Service already unregistered.");
+        } else {
+            m_registry.unregisterService(this);
+            m_svcObj = null;
+            m_factory = null;
+        }
+    }
+
+    /**
+     * Look for a property in the service properties.
+     * @param key : property key
+     * @return the object associated with the key or null if the key is not
+     * present.
+     */
+    protected Object getProperty(String key) {
+        return m_propMap.get(key);
+    }
+
+    /**
+     * Get the property keys.
+     * @return the property keys list.
+     */
+    protected String[] getPropertyKeys() {
+        synchronized (m_propMap) {
+            m_list.clear();
+            Iterator iterator = m_propMap.entrySet().iterator();
+            while (iterator.hasNext()) {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                m_list.add(entry.getKey());
+            }
+            return (String[]) m_list.toArray(new String[m_list.size()]);
+        }
+    }
+    
+    /**
+     * Gets the published properties.
+     * @return the dictionary containing each published properties.
+     */
+    protected Dictionary getProperties() {
+        synchronized (m_propMap) {
+            Dictionary dict = new Properties();
+            Iterator keys = m_propMap.keySet().iterator();
+            while (keys.hasNext()) {
+                String key = (String) keys.next();
+                dict.put(key, m_propMap.get(key));
+            }
+            return dict;
+        }
+    }
+
+    /**
+     * Get the service object.
+     * @return the service object. Call the service factory if needed.
+     */
+    protected Object getService() {
+        // If the service object is a service factory, then
+        // let it create the service object.
+        if (m_factory == null) {
+            return m_svcObj;
+        } else {
+            return getFactoryUnchecked();
+        }
+    }
+
+    /**
+     * Initialize properties.
+     * @param dict : service properties to publish.
+     */
+    private void initializeProperties(Dictionary dict) {
+        // Create a case insensitive map.
+        if (m_propMap == null) {
+            m_propMap = new StringMap(false);
+        } else {
+            m_propMap.clear();
+        }
+
+        if (dict != null) {
+            Enumeration keys = dict.keys();
+            while (keys.hasMoreElements()) {
+                Object key = keys.nextElement();
+                m_propMap.put(key, dict.get(key));
+            }
+        }
+        // Add the framework assigned properties.
+        m_propMap.put(Constants.OBJECTCLASS, m_classes);
+        m_propMap.put(Constants.SERVICE_ID, m_serviceId);
+    }
+
+    /**
+     * Get a service object via a service factory.
+     * @return the service object via the service factory invocation.
+     */
+    private Object getFactoryUnchecked() {
+        return m_factory.getService(null, this);
+    }
+
+    /**
+     * Unget a service. (Internal Method)
+     * 
+     * @param instance : component instance using the service.
+     * @param svcObj : the unget service object.
+     */
+    private void ungetFactoryUnchecked(ComponentInstance instance, Object svcObj) {
+        if (instance instanceof InstanceManager) {
+            m_factory.ungetService(((InstanceManager) instance).getContext().getBundle(), this, svcObj);
+        }
+
+    }
+
+    /**
+     * Unget a service.
+     * 
+     * @param instance : component instance using the service.
+     * @param srvObj : the unget service object.
+     */
+    public void ungetService(ComponentInstance instance, Object srvObj) {
+        // If the service object is a service factory, then let is release the
+        // service object.
+        if (m_factory != null) {
+            ungetFactoryUnchecked(instance, srvObj);
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java
new file mode 100644
index 0000000..81c1a7c
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/ServiceRegistry.java
@@ -0,0 +1,346 @@
+/* 
+ * 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.context;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.util.Logger;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * Internal Service Registry. This class is used for in the composition.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceRegistry {
+
+    /**
+     * Service Id index.
+     */
+    private long m_serviceId = 1L;
+
+    /**
+     * List of service listeners.
+     */
+    private List m_listeners = new ArrayList(); // ListenerInfo List
+
+    /**
+     * List of service registration.
+     */
+    private List m_regs = new ArrayList();
+
+    /**
+     * A "real" bundle context to create LDAP filter.
+     */
+    private BundleContext m_context; // BundleContext to create Filter
+    
+    /**
+     * Registry logger.
+     */
+    private Logger m_logger;
+
+    /**
+     * Listener info structure.
+     */
+    private static class ListenerInfo {
+        /**
+         * Listener object.
+         */
+        private ServiceListener m_listener;
+        /**
+         * Filter associated with the filter.
+         */
+        private Filter m_filter;
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param context : bundle context.
+     */
+    public ServiceRegistry(BundleContext context) {
+        m_context = context;
+        m_logger = new Logger(m_context, "Registry logger " + m_context.getBundle().getBundleId());
+    }
+
+    /**
+     * Add a given service listener with no filter.
+     * 
+     * @param arg0 : the service listener to add
+     */
+    public void addServiceListener(ServiceListener arg0) {
+        ListenerInfo info = new ListenerInfo();
+        info.m_listener = arg0;
+        info.m_filter = null;
+        m_listeners.add(info);
+    }
+
+    /**
+     * Unget a service.
+     * 
+     * @param instance : instance releasing the service.
+     * @param ref : released reference.
+     * @return true if the unget success
+     */
+    public boolean ungetService(ComponentInstance instance, ServiceReference ref) {
+
+        ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
+        if (reg.isValid()) {
+            reg.ungetService(instance, reg.getService());
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Unregister a service listener.
+     * 
+     * @param arg0 : the service listener to remove
+     */
+    public void removeServiceListener(ServiceListener arg0) {
+        m_listeners.remove(arg0);
+    }
+
+    /**
+     * Register a service.
+     * 
+     * @param instance : provider instance.
+     * @param clazz : provided interface.
+     * @param svcObj : service object of service factory object.
+     * @param dict : service properties.
+     * @return the created service registration.
+     */
+    public ServiceRegistration registerService(ComponentInstance instance, String clazz, Object svcObj, Dictionary dict) {
+        synchronized (m_regs) {
+            ServiceRegistrationImpl reg = new ServiceRegistrationImpl(this, instance, new String[] { clazz }, new Long(m_serviceId++), svcObj, dict);
+            m_regs.add(reg);
+            fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));
+            return reg;
+        }
+    }
+
+    /**
+     * Register a service.
+     * 
+     * @param instance : provider instance.
+     * @param clazzes : provided interfaces.
+     * @param svcObj : service object of service factory object.
+     * @param dict : service properties.
+     * @return the created service registration.
+     */
+    public ServiceRegistration registerService(ComponentInstance instance, String[] clazzes, Object svcObj, Dictionary dict) {
+        synchronized (m_regs) {
+            ServiceRegistrationImpl reg = new ServiceRegistrationImpl(this, instance, clazzes, new Long(m_serviceId++), svcObj, dict);
+            m_regs.add(reg);
+            fireServiceChanged(new ServiceEvent(ServiceEvent.REGISTERED, reg.getReference()));
+            return reg;
+        }
+    }
+
+    /**
+     * Dispatch a service event.
+     * @param event : the service to dispatch
+     */
+    private void fireServiceChanged(ServiceEvent event) {
+        synchronized (m_listeners) {
+            // Iterate on the service listener list to notify service listener
+            for (int i = 0; i < m_listeners.size(); i++) {
+                ListenerInfo info = (ListenerInfo) m_listeners.get(i);
+                ServiceReference ref = event.getServiceReference();
+                if (info.m_filter == null) {
+                    info.m_listener.serviceChanged(event);
+                }
+                Dictionary props = ((ServiceReferenceImpl) ref).getProperties();
+                if (info.m_filter != null && info.m_filter.match(props)) {
+                    info.m_listener.serviceChanged(event);
+                }
+            }
+        }
+    }
+
+    /**
+     * Get available (and accessible) service references.
+     * 
+     * @param className : required interface
+     * @param expr : LDAP filter
+     * @return : the list of available service references.
+     * @throws InvalidSyntaxException
+     *             occurs when the LDAP filter is malformed.
+     */
+    public ServiceReference[] getServiceReferences(String className, String expr) throws InvalidSyntaxException {
+        synchronized (m_regs) {
+            // Define filter if expression is not null.
+            Filter filter = null;
+            if (expr != null) {
+                filter = m_context.createFilter(expr);
+            }
+
+            List refs = new ArrayList();
+
+            for (int i = 0; i < m_regs.size(); i++) {
+                ServiceRegistrationImpl reg = (ServiceRegistrationImpl) m_regs.get(i);
+                // Determine if the registered services matches the search
+                // criteria.
+                boolean matched = false;
+
+                // If className is null, then look at filter only.
+                if ((className == null) && ((filter == null) || filter.match(reg.getProperties()))) {
+                    matched = true;
+                } else if (className != null) {
+                    // If className is not null, then first match the
+                    // objectClass property before looking at the
+                    // filter.
+                    Dictionary props = ((ServiceRegistrationImpl) reg).getProperties();
+                    String[] objectClass = (String[]) props.get(Constants.OBJECTCLASS);
+                    for (int classIdx = 0; classIdx < objectClass.length; classIdx++) {
+                        if (objectClass[classIdx].equals(className) && ((filter == null) || filter.match(props))) {
+                            matched = true;
+                            break;
+                        }
+                    }
+                }
+
+                // Add reference if it was a match.
+                if (matched) {
+                    refs.add(reg.getReference());
+                }
+            }
+
+            if (! refs.isEmpty()) {
+                return (ServiceReference[]) refs.toArray(new ServiceReference[refs.size()]);
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Look for a service reference.
+     * 
+     * @param clazz : required interface.
+     * @return the first available provider or null if none available.
+     */
+    public ServiceReference getServiceReference(String clazz) {
+        synchronized (m_regs) {
+            try {
+                ServiceReference[] refs = getServiceReferences(clazz, null);
+                if (refs != null) {
+                    return refs[0];
+                } // If the refs != null we are sure that it exists one reference or more.
+            } catch (InvalidSyntaxException ex) {
+                // Cannot happen : null filter.
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Get a service object.
+     * @param instance : component instance requiring the service.
+     * @param ref : the required reference.
+     * @return the service object.
+     */
+    public Object getService(ComponentInstance instance, ServiceReference ref) {
+        synchronized (m_regs) {
+            // Look for the service registration for this ref
+            ServiceRegistrationImpl reg = ((ServiceReferenceImpl) ref).getServiceRegistration();
+            if (reg.isValid()) {
+                // Delegate the service providing to the service registration
+                return reg.getService();
+            } else {
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Get all service references consistent with the given interface and
+     * filter.
+     * @param clazz : the required interface.
+     * @param filter : the LDAP filter.
+     * @return the list of all service reference or null if none available.
+     * @throws InvalidSyntaxException occurs when the LDAP filter is malformed.
+     */
+    public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
+        synchronized (m_regs) {
+            // Can delegate on getServiceReference, indeed their is no test on
+            // the "modularity" conflict.
+            return getServiceReferences(clazz, filter);
+        }
+    }
+
+    /**
+     * Add a service listener with a filter.
+     * @param listener : the service listener to add
+     * @param filter : LDAP filter
+     */
+    public void addServiceListener(ServiceListener listener, String filter) {
+        // If the filter is null, subscribe with no filter.
+        if (filter == null) {
+            addServiceListener(listener);
+            return;
+        }
+        
+        try {
+            ListenerInfo info = new ListenerInfo();
+            info.m_listener = listener;
+            info.m_filter = m_context.createFilter(filter);
+            m_listeners.add(info);
+        } catch (InvalidSyntaxException ex) {
+            m_logger.log(Logger.ERROR, ex.getMessage(), ex);
+        }
+        
+    }
+
+    /**
+     * Dispatch a service properties modified event.
+     * @param reg : the implicated service registration.
+     */
+    public void servicePropertiesModified(ServiceRegistrationImpl reg) {
+        fireServiceChanged(new ServiceEvent(ServiceEvent.MODIFIED, reg.getReference()));
+    }
+
+    /**
+     * Unregister a service.
+     * @param reg : the service registration to unregister
+     */
+    public void unregisterService(ServiceRegistrationImpl reg) {
+        m_regs.remove(reg);
+        fireServiceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, reg.getReference()));
+    }
+
+    /**
+     * Reset the service registry.
+     */
+    public void reset() {
+        m_serviceId = 1L;
+        m_listeners = new ArrayList();
+        m_regs = new ArrayList();
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/StringMap.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/StringMap.java
new file mode 100644
index 0000000..737c95b
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/context/StringMap.java
@@ -0,0 +1,148 @@
+/* 
+ * 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.context;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.TreeMap;
+
+/**
+ * Simple utility class that creates a map for string-based keys by extending
+ * <tt>TreeMap</tt>. This map can be set to use case-sensitive or
+ * case-insensitive comparison when searching for the key. Any keys put into
+ * this map will be converted to a <tt>String</tt> using the
+ * <tt>toString()</tt> method, since it is only intended to compare strings.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class StringMap extends TreeMap {
+
+    /**
+     * serialVersionUID.
+     */
+    private static final long serialVersionUID = 6948801857034259744L;
+
+    /**
+     * Constructor.
+     */
+    public StringMap() {
+        this(true);
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param caseSensitive : fix if the map if case sensitive or not.
+     */
+    public StringMap(boolean caseSensitive) {
+        super(new StringComparator(caseSensitive));
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param map : initial properties.
+     * @param caseSensitive : fix if the map if case sensitive or not.
+     */
+    public StringMap(Map map, boolean caseSensitive) {
+        this(caseSensitive);
+        putAll(map);
+    }
+
+    /**
+     * Put a record in the map.
+     * @param key : key
+     * @param value : value
+     * @return an object.
+     * @see java.util.TreeMap#put(K, V)
+     */
+    public Object put(Object key, Object value) {
+        return super.put(key.toString(), value);
+    }
+
+    /**
+     * Check if the map is case-sensitive.
+     * @return true if the map is case sensitive.
+     */
+    public boolean isCaseSensitive() {
+        return ((StringComparator) comparator()).isCaseSensitive();
+    }
+
+    /**
+     * Set the case sensitivity.
+     * 
+     * @param flag : the new case sensitivity.
+     */
+    public void setCaseSensitive(boolean flag) {
+        ((StringComparator) comparator()).setCaseSensitive(flag);
+    }
+
+    private static class StringComparator implements Comparator, Serializable {
+        /**
+         * Id.
+         */
+        private static final long serialVersionUID = 1L;
+        
+        /**
+         * Is the map case sensitive?
+         */
+        private boolean m_isCaseSensitive = true;
+
+        /**
+         * Constructor.
+         * 
+         * @param flag : true to enable the case sensitivity.
+         */
+        public StringComparator(boolean flag) {
+            m_isCaseSensitive = flag;
+        }
+
+        /**
+         * Compare to object.
+         * @param object1 : first object to compare
+         * @param object2 : second object to compare
+         * @return the comparison result
+         * @see java.util.Comparator#compare(T, T)
+         */
+        public int compare(Object object1, Object object2) {
+            if (m_isCaseSensitive) {
+                return object1.toString().compareTo(object2.toString());
+            } else {
+                return object1.toString().compareToIgnoreCase(object2.toString());
+            }
+        }
+
+        /**
+         * Check if the comparator is case sensitive.
+         * @return true if the map is case sensitive.
+         */
+        public boolean isCaseSensitive() {
+            return m_isCaseSensitive;
+        }
+
+        /**
+         * Set the case sensitivity.
+         * 
+         * @param flag : true to enable the case sensitivity
+         */
+        public void setCaseSensitive(boolean flag) {
+            m_isCaseSensitive = flag;
+        }
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
new file mode 100644
index 0000000..a5f6c7e
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/architecture/ArchitectureHandler.java
@@ -0,0 +1,73 @@
+/* 
+ * 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.handlers.architecture;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.PrimitiveHandler;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.architecture.InstanceDescription;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Architecture Handler : do reflection on your component.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ArchitectureHandler extends PrimitiveHandler implements Architecture {
+
+    /**
+     * Name of the component.
+     */
+    private String m_name;
+
+    /**
+     * Configure the handler.
+     * @param metadata : the metadata of the component
+     * @param configuration : the instance configuration
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary configuration) {
+        m_name = (String) configuration.get("instance.name");
+    }
+
+    /**
+     * Stop method.
+     * @see org.apache.felix.ipojo.Handler#stop()
+     */
+    public void stop() {
+        // Nothing do do when stopping.
+    }
+
+    /**
+     * Start method.
+     * @see org.apache.felix.ipojo.Handler#start()
+     */
+    public void start() {
+        debug("Start architecture handler with " + m_name + " name");
+    }
+
+    /**
+     * Get the instance description.
+     * @return the instance description
+     * @see org.apache.felix.ipojo.architecture.Architecture#getDescription()
+     */
+    public InstanceDescription getInstanceDescription() {
+        return getInstanceManager().getInstanceDescription();
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
new file mode 100644
index 0000000..b5659f2
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandler.java
@@ -0,0 +1,629 @@
+/*
+ * 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.handlers.configuration;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.PrimitiveHandler;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.FieldMetadata;
+import org.apache.felix.ipojo.parser.MethodMetadata;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Callback;
+import org.apache.felix.ipojo.util.Property;
+import org.apache.felix.ipojo.util.SecurityHelper;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ManagedService;
+
+/**
+ * Handler managing the Configuration Admin.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ConfigurationHandler extends PrimitiveHandler implements ManagedService {
+
+    /**
+     * List of the configurable fields.
+     */
+    private List/*<Property>*/ m_configurableProperties = new ArrayList(1);
+
+    /**
+     * ProvidedServiceHandler of the component. It is useful to propagate
+     * properties to service registrations.
+     */
+    private ProvidedServiceHandler m_providedServiceHandler;
+
+    /**
+     * Properties propagated during the last instance "update".
+     */
+    private Dictionary m_propagatedFromInstance = new Properties();
+
+    /**
+     * Properties to propagate.
+     */
+    private Dictionary m_toPropagate = new Properties();
+
+    /**
+     * Properties propagated from the configuration admin.
+     */
+    private Dictionary m_propagatedFromCA;
+
+    /**
+     * Check if the instance was already reconfigured by the configuration admin.
+     */
+    private boolean m_configurationAlreadyPushed;
+
+    /**
+     * should the component propagate configuration ?
+     */
+    private boolean m_mustPropagate;
+
+    /**
+     * Service Registration to publish the service registration.
+     */
+    private ServiceRegistration m_sr;
+
+    /**
+     * Managed Service PID.
+     * This PID must be different from the instance name if the instance was created
+     * with the Configuration Admin.
+     */
+    private String m_managedServicePID;
+
+    /**
+     * the handler description.
+     */
+    private ConfigurationHandlerDescription m_description;
+
+    /**
+     * Updated method.
+     * This method is called when a reconfiguration is completed.
+     */
+    private Callback m_updated;
+
+
+    /**
+     * Initialize the component type.
+     * @param desc : component type description to populate.
+     * @param metadata : component type metadata.
+     * @throws ConfigurationException : metadata are incorrect.
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
+     */
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
+        Element[] confs = metadata.getElements("Properties", "");
+        if (confs == null) { return; }
+        Element[] configurables = confs[0].getElements("Property");
+        for (int i = 0; configurables != null && i < configurables.length; i++) {
+            String fieldName = configurables[i].getAttribute("field");
+            String methodName = configurables[i].getAttribute("method");
+            String paramIndex = configurables[i].getAttribute("constructor-parameter");
+
+            if (fieldName == null && methodName == null  && paramIndex == null) {
+                throw new ConfigurationException("Malformed property : The property needs to contain" +
+                        " at least a field, a method or a constructor-parameter");
+            }
+
+            String name = configurables[i].getAttribute("name");
+            if (name == null) {
+                if (fieldName == null  && methodName != null) {
+                    name = methodName;
+                } else if (fieldName == null  && paramIndex != null) {
+                    name = paramIndex;
+                } else {
+                    name = fieldName;
+                }
+                configurables[i].addAttribute(new Attribute("name", name)); // Add the type to avoid configure checking
+            }
+
+            String value = configurables[i].getAttribute("value");
+
+            // Detect the type of the property
+            PojoMetadata manipulation = getFactory().getPojoMetadata();
+            String type = null;
+            if (methodName != null) {
+                MethodMetadata[] method = manipulation.getMethods(methodName);
+                if (method.length == 0) {
+                    type = configurables[i].getAttribute("type");
+                    if (type == null) {
+                        throw new ConfigurationException("Malformed property : The type of the property cannot be discovered, add a 'type' attribute");
+                    }
+                } else {
+                    if (method[0].getMethodArguments().length != 1) {
+                        throw new ConfigurationException("Malformed property :  The method " + methodName + " does not have one argument");
+                    }
+                    type = method[0].getMethodArguments()[0];
+                    configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
+                }
+            } else if (fieldName != null) {
+                FieldMetadata field = manipulation.getField(fieldName);
+                if (field == null) { throw new ConfigurationException("Malformed property : The field " + fieldName + " does not exist in the implementation class"); }
+                type = field.getFieldType();
+                configurables[i].addAttribute(new Attribute("type", type)); // Add the type to avoid configure checking
+            } else if (paramIndex != null) {
+                int index = Integer.parseInt(paramIndex);
+                type = configurables[i].getAttribute("type");
+                MethodMetadata[] cts = manipulation.getConstructors();
+                // If we don't have a type, try to get the first constructor and get the type of the parameter
+                // we the index 'index'.
+                if (type == null && cts.length > 0  && cts[0].getMethodArguments().length > index) {
+                    type = cts[0].getMethodArguments()[index];
+                } else if (type == null) { // Applied only if type was not determined.
+                    throw new ConfigurationException("Cannot determine the type of the property " + index +
+                            ", please use the type attribute");
+                }
+                configurables[i].addAttribute(new Attribute("type", type));
+            }
+
+            // Is the property set to immutable
+            boolean immutable = false;
+            String imm = configurables[i].getAttribute("immutable");
+            immutable = imm != null && imm.equalsIgnoreCase("true");
+
+            boolean mandatory = false;
+            String man = configurables[i].getAttribute("mandatory");
+            mandatory =  man != null && man.equalsIgnoreCase("true");
+
+            PropertyDescription pd = null;
+            if (value == null) {
+                pd = new PropertyDescription(name, type, null, false); // Cannot be immutable if we have no value.
+            } else {
+                pd = new PropertyDescription(name, type, value, immutable);
+            }
+
+            if (mandatory) {
+                pd.setMandatory();
+            }
+
+            desc.addProperty(pd);
+        }
+
+    }
+
+    /**
+     * Configures the handler.
+     * Access to field does not require synchronization as this method is executed
+     * before any thread access to this object.
+     * @param metadata the metadata of the component
+     * @param configuration the instance configuration
+     * @throws ConfigurationException one property metadata is not correct
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+        // Build the map
+        Element[] confs = metadata.getElements("Properties", "");
+        Element[] configurables = confs[0].getElements("Property");
+
+        // Check if the component is dynamically configurable
+        // Propagation enabled by default.
+        m_mustPropagate = true;
+        m_toPropagate = configuration; // Instance configuration to propagate.
+        String propa = confs[0].getAttribute("propagation");
+        if (propa != null && propa.equalsIgnoreCase("false")) {
+            m_mustPropagate = false;
+            m_toPropagate = null;
+        }
+
+        // Check if the component support ConfigurationADmin reconfiguration
+        m_managedServicePID = confs[0].getAttribute("pid"); // Look inside the component type description
+        String instanceMSPID = (String) configuration.get("managed.service.pid"); // Look inside the instance configuration.
+        if (instanceMSPID != null) {
+            m_managedServicePID = instanceMSPID;
+        }
+
+        // updated method
+        String upd = confs[0].getAttribute("updated");
+        if (upd != null) {
+            MethodMetadata method = getPojoMetadata().getMethod(upd);
+            if (method == null) {
+                throw new ConfigurationException("The updated method is not found in the class "
+                        + getInstanceManager().getClassName());
+            } else if (method.getMethodArguments().length == 0) {
+                m_updated = new Callback(upd, new Class[0], false, getInstanceManager());
+            } else if (method.getMethodArguments().length == 1
+                    && method.getMethodArguments()[0].equals(Dictionary.class.getName())) {
+                m_updated = new Callback(upd, new Class[] {Dictionary.class}, false, getInstanceManager());
+            } else {
+                throw new ConfigurationException("The updated method is found in the class "
+                        + getInstanceManager().getClassName() + " must have either no argument or a Dictionary");
+            }
+        }
+
+        for (int i = 0; configurables != null && i < configurables.length; i++) {
+            String fieldName = configurables[i].getAttribute("field");
+            String methodName = configurables[i].getAttribute("method");
+            String paramIndex = configurables[i].getAttribute("constructor-parameter");
+            int index = -1;
+
+            String name = configurables[i].getAttribute("name"); // The initialize method has fixed the property name.
+            String value = configurables[i].getAttribute("value");
+
+            String type = configurables[i].getAttribute("type"); // The initialize method has fixed the property name.
+
+            Property prop = null;
+            if (paramIndex == null) {
+                prop = new Property(name, fieldName, methodName, value, type, getInstanceManager(), this);
+            } else {
+                index = Integer.parseInt(paramIndex);
+                prop = new Property(name, fieldName, methodName, index,
+                        value, type, getInstanceManager(), this);
+            }
+            addProperty(prop);
+
+            // Check if the instance configuration contains value for the current property :
+            if (configuration.get(name) == null) {
+                if (fieldName != null && configuration.get(fieldName) != null) {
+                    prop.setValue(configuration.get(fieldName));
+                }
+            } else {
+                prop.setValue(configuration.get(name));
+            }
+
+            if (fieldName != null) {
+                FieldMetadata field = new FieldMetadata(fieldName, type);
+                getInstanceManager().register(field, prop);
+            }
+
+            if (index != -1) {
+                getInstanceManager().register(index, prop);
+            }
+        }
+
+        m_description = new ConfigurationHandlerDescription(this, m_configurableProperties, m_managedServicePID);
+
+    }
+
+    /**
+      * Stop method.
+      * This method is synchronized to avoid the configuration admin pushing a configuration during the un-registration.
+      * Do nothing.
+      * @see org.apache.felix.ipojo.Handler#stop()
+      */
+    public synchronized void stop() {
+        if (m_sr != null) {
+            m_sr.unregister();
+            m_sr = null;
+        }
+    }
+
+    /**
+     * Start method.
+     * This method is synchronized to avoid the config admin pushing a configuration before ending the method.
+     * Propagate properties if the propagation is activated.
+     * @see org.apache.felix.ipojo.Handler#start()
+     */
+    public synchronized void start() {
+        // Get the provided service handler :
+        m_providedServiceHandler = (ProvidedServiceHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":provides");
+
+
+        // Propagation
+        if (m_mustPropagate) {
+            for (int i = 0; i < m_configurableProperties.size(); i++) {
+                Property prop = (Property) m_configurableProperties.get(i);
+                if (prop.getValue() != Property.NO_VALUE && prop.getValue() != null) { // No injected value, or null
+                    m_toPropagate.put(prop.getName(), prop.getValue());
+                }
+            }
+            reconfigure(m_toPropagate);
+        }
+
+
+        // Give initial values and reset the 'invoked' flag.
+        for (int i = 0; i < m_configurableProperties.size(); i++) {
+            Property prop = (Property) m_configurableProperties.get(i);
+            prop.reset(); // Clear the invoked flag.
+            if (prop.hasField() && prop.getValue() != Property.NO_VALUE && prop.getValue() != null) {
+                getInstanceManager().onSet(null, prop.getField(), prop.getValue());
+            }
+        }
+
+        if (m_managedServicePID != null && m_sr == null) {
+            Properties props = new Properties();
+            props.put(Constants.SERVICE_PID, m_managedServicePID);
+            props.put("instance.name", getInstanceManager().getInstanceName());
+            props.put("factory.name", getInstanceManager().getFactory().getFactoryName());
+
+            // Security Check
+            if (SecurityHelper.hasPermissionToRegisterService(ManagedService.class.getName(),
+                    getInstanceManager().getContext())) {
+                m_sr = getInstanceManager().getContext().registerService(ManagedService.class.getName(), this, (Dictionary) props);
+            } else {
+                error("Cannot register the ManagedService - The bundle "
+                        + getInstanceManager().getContext().getBundle().getBundleId()
+                        + " does not have the permission to register the service");
+            }
+        }
+    }
+
+    /**
+     * Adds the given property metadata to the property metadata list.
+     *
+     * @param prop : property metadata to add
+     */
+    protected void addProperty(Property prop) {
+        m_configurableProperties.add(prop);
+    }
+
+    /**
+     * Checks if the list contains the property.
+     *
+     * @param name : name of the property
+     * @return true if the property exist in the list
+     */
+    protected boolean containsProperty(String name) {
+        for (int i = 0; i < m_configurableProperties.size(); i++) {
+            if (((Property) m_configurableProperties.get(i)).getName().equals(name)) { return true; }
+        }
+        return false;
+    }
+
+    /**
+     * Reconfigure the component instance.
+     * Check if the new configuration modifies the current configuration.
+     * Invokes the updated method is needed.
+     * @param configuration : the new configuration
+     * @see org.apache.felix.ipojo.Handler#reconfigure(java.util.Dictionary)
+     */
+    public synchronized void reconfigure(Dictionary configuration) {
+        info(getInstanceManager().getInstanceName() + " is reconfiguring the properties : " + configuration);
+        Properties props = reconfigureProperties(configuration);
+        propagate(props, m_propagatedFromInstance);
+        m_propagatedFromInstance = props;
+
+        if (getInstanceManager().getPojoObjects() != null) {
+            try {
+                notifyUpdated(null);
+            } catch (Throwable e) {
+                error("Cannot call the updated method : " + e.getMessage(), e);
+            }
+        }
+    }
+
+    /**
+     * Reconfigured configuration properties and returns non matching properties.
+     * When called, it must hold the monitor lock.
+     * @param configuration : new configuration
+     * @return the properties that does not match with configuration properties
+     */
+    private Properties reconfigureProperties(Dictionary configuration) {
+        Properties toPropagate = new Properties();
+        Enumeration keysEnumeration = configuration.keys();
+        while (keysEnumeration.hasMoreElements()) {
+            String name = (String) keysEnumeration.nextElement();
+            Object value = configuration.get(name);
+            boolean found = false;
+            // Check if the name is a configurable property
+            for (int i = 0; i < m_configurableProperties.size(); i++) {
+                Property prop = (Property) m_configurableProperties.get(i);
+                if (prop.getName().equals(name)) {
+                    reconfigureProperty(prop, value);
+                    found = true;
+                    break; // Exit the search loop
+                }
+            }
+            if (!found) {
+                // The property is not a configurable property, add it to the toPropagate list.
+                toPropagate.put(name, value);
+            }
+        }
+
+        // Every removed configurable property gets reset to its default value
+        for (int i = 0; i < m_configurableProperties.size(); i++) {
+            Property prop = (Property) m_configurableProperties.get(i);
+            if (configuration.get(prop.getName()) == null) {
+                reconfigureProperty(prop, prop.getDefaultValue());
+            }
+        }
+        return toPropagate;
+
+    }
+
+    /**
+     * Reconfigures the given property with the given value.
+     * This methods handles {@link org.apache.felix.ipojo.InstanceManager#onSet(Object, String, Object)}
+     * call and the callback invocation.
+     * The reconfiguration occurs only if the value changes.
+     * @param prop the property object to reconfigure
+     * @param value the new value.
+     */
+    public void reconfigureProperty(Property prop, Object value) {
+        if (prop.getValue() == null || ! prop.getValue().equals(value)) {
+            prop.setValue(value);
+            if (prop.hasField()) {
+                getInstanceManager().onSet(null, prop.getField(), prop.getValue()); // Notify other handler of the field value change.
+            }
+            if (prop.hasMethod()) {
+                if (getInstanceManager().getPojoObjects() != null) {
+                    prop.invoke(null); // Call on all created pojo objects.
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes the old properties from the provided services and propagate new properties.
+     * @param newProps : new properties to propagate
+     * @param oldProps : old properties to remove
+     */
+    private void propagate(Dictionary newProps, Dictionary oldProps) {
+        if (m_mustPropagate && m_providedServiceHandler != null) {
+            if (oldProps != null) {
+                m_providedServiceHandler.removeProperties(oldProps);
+            }
+
+            if (newProps != null) {
+                // Remove the name, the pid and the managed service pid props
+                newProps.remove("name");
+                newProps.remove("managed.service.pid");
+                newProps.remove(Constants.SERVICE_PID);
+                // Propagation of the properties to service registrations :
+                m_providedServiceHandler.addProperties(newProps);
+            }
+        }
+    }
+
+    /**
+     * Handler createInstance method.
+     * This method is override to allow delayed callback invocation.
+     * Invokes the updated method is needed.
+     * @param instance : the created object
+     * @see org.apache.felix.ipojo.PrimitiveHandler#onCreation(Object)
+     */
+    public void onCreation(Object instance) {
+        for (int i = 0; i < m_configurableProperties.size(); i++) {
+            Property prop = (Property) m_configurableProperties.get(i);
+            if (prop.hasMethod()) {
+                prop.invoke(instance);
+            }
+        }
+
+        try {
+            notifyUpdated(instance);
+        } catch (Throwable e) {
+            error("Cannot call the updated method : " + e.getMessage(), e);
+        }
+    }
+
+    /**
+     * Invokes the updated method.
+     * This method build the dictionary containing all valued properties,
+     * as well as properties propagated to the provided service handler (
+     * only if the propagation is enabled).
+     * @param instance the instance on which the callback must be called.
+     * If <code>null</code> the callback is called on all the existing
+     * object.
+     */
+    private void notifyUpdated(Object instance) {
+        if (m_updated == null) {
+            return;
+        }
+
+        if (m_updated.getArguments().length == 0) {
+            // We don't have to compute the properties,
+            // we just call the callback.
+            try {
+                if (instance == null) {
+                    m_updated.call(new Object[0]);
+                } else {
+                    m_updated.call(instance, new Object[0]);
+                }
+            } catch (Exception e) {
+                error("Cannot call the updated method " + m_updated.getMethod() + " : " + e.getMessage());
+            }
+            return;
+        }
+
+        // Else we must compute the properties.
+        Properties props = new Properties();
+        for (int i = 0; i < m_configurableProperties.size(); i++) {
+            String n = ((Property) m_configurableProperties.get(i)).getName();
+            Object v = ((Property) m_configurableProperties.get(i)).getValue();
+            if (v != Property.NO_VALUE) {
+                props.put(n, v);
+            }
+        }
+        // add propagated properties to the list if propagation enable
+        if (m_mustPropagate) {
+            // Start by properties from the configuration admin,
+            if (m_propagatedFromCA != null) {
+
+                Enumeration e = m_propagatedFromCA.keys();
+                while (e.hasMoreElements()) {
+                    String k = (String) e.nextElement();
+                    if (! k.equals("instance.name")) {
+                        props.put(k, m_propagatedFromCA.get(k));
+                    }
+                }
+            }
+            // Do also the one from the instance configuration
+            if (m_propagatedFromInstance != null) {
+                Enumeration e = m_propagatedFromInstance.keys();
+                while (e.hasMoreElements()) {
+                    String k = (String) e.nextElement();
+                    if (! k.equals("instance.name")) { // Skip instance.name
+                        props.put(k, m_propagatedFromInstance.get(k));
+                    }
+                }
+            }
+        }
+
+        try {
+            if (instance == null) {
+                m_updated.call(new Object[] {props});
+            } else {
+                m_updated.call(instance, new Object[] {props});
+            }
+        } catch (Exception e) {
+            error("Cannot call the updated method " + m_updated.getMethod() + " : " + e.getMessage());
+        }
+    }
+
+    /**
+     * Managed Service method.
+     * This method is called when the instance is reconfigured by the ConfigurationAdmin.
+     * When called, it must hold the monitor lock.
+     * @param conf : pushed configuration.
+     * @throws org.osgi.service.cm.ConfigurationException the reconfiguration failed.
+     * @see org.osgi.service.cm.ManagedService#updated(java.util.Dictionary)
+     */
+    public synchronized void updated(Dictionary conf) throws org.osgi.service.cm.ConfigurationException {
+        if (conf == null && ! m_configurationAlreadyPushed) {
+            return; // First call
+        } else if (conf != null) { // Configuration push
+            Properties props = reconfigureProperties(conf);
+            propagate(props, m_propagatedFromCA);
+            m_propagatedFromCA = props;
+            m_configurationAlreadyPushed = true;
+        } else if (m_configurationAlreadyPushed) { // Configuration deletion
+            propagate(null, m_propagatedFromCA);
+            m_propagatedFromCA = null;
+            m_configurationAlreadyPushed = false;
+        }
+
+        if (getInstanceManager().getPojoObjects() != null) {
+            try {
+                notifyUpdated(null);
+            } catch (Throwable e) {
+                error("Cannot call the updated method : " + e.getMessage(), e);
+            }
+        }
+    }
+
+    /**
+     * Gets the configuration handler description.
+     * @return the configuration handler description.
+     * @see org.apache.felix.ipojo.Handler#getDescription()
+     */
+    public HandlerDescription getDescription() {
+        return m_description;
+    }
+
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandlerDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandlerDescription.java
new file mode 100644
index 0000000..d8bdb4b
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/configuration/ConfigurationHandlerDescription.java
@@ -0,0 +1,111 @@
+/* 
+ * 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.handlers.configuration;
+
+import java.util.List;
+
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.Property;
+
+/**
+ * Configuration handler description.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ConfigurationHandlerDescription extends HandlerDescription {
+    
+    /**
+     * The property descriptions.
+     */
+    private PropertyDescription[] m_properties;
+    
+    /**
+     * The Managed Service PID.
+     * <code>null</code> if not set.
+     */
+    private String m_pid;
+
+    /**
+     * Creates the description object for the configuration handler description.
+     * @param handler the configuration handler.
+     * @param props the list of properties.
+     * @param pid the managed service pid or <code>null</code> if not set.
+     */
+    public ConfigurationHandlerDescription(Handler handler, List/*<Property>*/ props, String pid) {
+        super(handler);
+        m_properties = new PropertyDescription[props.size()];
+        for (int i = 0; i < props.size(); i++) {
+            m_properties[i] = new PropertyDescription((Property) props.get(i));
+        }        
+        m_pid = pid;
+    }
+    
+    /**
+     * The handler information.
+     * @return the handler description.
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element elem = super.getHandlerInfo();
+        
+        if (m_pid != null) {
+            elem.addAttribute(new Attribute("managed.service.pid", m_pid));
+        }
+        
+        for (int i = 0; i < m_properties.length; i++) {
+            String name = m_properties[i].getName();
+            Object value = m_properties[i].getValue();
+            Element property = new Element("property", "");
+            elem.addElement(property);
+            if (name != null) {
+                property.addAttribute(new Attribute("name", name));
+            }
+            if (value != null) {
+                if (value == Property.NO_VALUE) {
+                    property.addAttribute(new Attribute("value", "NO_VALUE"));
+                } else {
+                    property.addAttribute(new Attribute("value", value.toString()));
+                }
+            }
+        }
+        return elem;
+    }
+    
+    /**
+     * Gets the properties.
+     * @return the property set.
+     */
+    public PropertyDescription[] getProperties() {
+        return m_properties;
+    }
+    
+    /**
+     * Gets the managed service pid.
+     * @return the managed service pid of <code>null</code>
+     * if not set.
+     */
+    public String getManagedServicePid() {
+        return m_pid;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
new file mode 100644
index 0000000..eb45ae7
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/Dependency.java
@@ -0,0 +1,1068 @@
+/*
+ * 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.handlers.dependency;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.ConstructorInjector;
+import org.apache.felix.ipojo.FieldInterceptor;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.MethodInterceptor;
+import org.apache.felix.ipojo.Nullable;
+import org.apache.felix.ipojo.PolicyServiceContext;
+import org.apache.felix.ipojo.handlers.dependency.ServiceUsage.Usage;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Represent a service dependency of the component instance.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Dependency extends DependencyModel implements FieldInterceptor, MethodInterceptor,
+    ConstructorInjector {
+
+    /**
+     * Reference on the Dependency Handler.
+     */
+    private final DependencyHandler m_handler;
+
+    /**
+     * Field of the dependency.
+     */
+    private final String m_field;
+
+    /**
+     * List of dependency callback.
+     * Immutable once set.
+     */
+    private DependencyCallback[] m_callbacks;
+
+    /**
+     * Is the dependency a service level dependency.
+     * Immutable once set.
+     */
+    private boolean m_isServiceLevelRequirement;
+
+    /**
+     * Is the provider set frozen ?
+     */
+    private boolean m_isFrozen;
+
+    /**
+     * Is the dependency started ?
+     */
+    private boolean m_isStarted;
+
+    /**
+     * Thread Local.
+     */
+    private ServiceUsage m_usage;
+
+    /**
+     * Type of the object to inject.
+     * Cannot change once set.
+     */
+    private int m_type;
+
+    /**
+     * Nullable object.
+     * Immutable once set.
+     */
+    private Object m_nullable;
+
+    /**
+     * Default-Implementation.
+     */
+    private final String m_di;
+
+    /**
+     * Is the Nullable pattern enable?
+     */
+    private final boolean m_supportNullable;
+
+    /**
+     * Id of the dependency.
+     * Immutable once set.
+     */
+    private String m_id;
+
+    /**
+     * Do we have to inject proxy?
+     */
+    private boolean m_isProxy;
+
+    /**
+     * Proxy Object.
+     */
+    private Object m_proxyObject;
+
+    /**
+     * Constructor paramter index.
+     * -1 if not used.
+     */
+    private int m_index = -1;
+
+    /**
+     * Dependency constructor. After the creation the dependency is not started.
+     *
+     * @param handler : the dependency handler managing this dependency
+     * @param field : field of the dependency
+     * @param spec : required specification
+     * @param filter : LDAP filter of the dependency
+     * @param isOptional : is the dependency an optional dependency ?
+     * @param isAggregate : is the dependency an aggregate dependency
+     * @param nullable : describe if the nullable ability is enable or disable
+     * @param isProxy : is the proxied dependency
+     * @param identity : id of the dependency, may be null
+     * @param context : bundle context (or service context) to use.
+     * @param policy : resolution policy
+     * @param cmp : comparator to sort references
+     * @param defaultImplem : default-implementation class
+     */
+    public Dependency(DependencyHandler handler, String field, Class spec, Filter filter, boolean isOptional, boolean isAggregate, boolean nullable, boolean isProxy, String identity, BundleContext context, int policy, Comparator cmp, String defaultImplem) {
+        super(spec, isAggregate, isOptional, filter, cmp, policy, context, handler, handler.getInstanceManager());
+        m_handler = handler;
+        m_field = field;
+        m_isProxy = isProxy;
+
+        if (field != null) {
+            m_usage = new ServiceUsage();
+        } else {
+            m_usage = null;
+        }
+
+        m_supportNullable = nullable;
+        m_di = defaultImplem;
+
+        if (identity == null) {
+            if (spec != null) {
+                m_id = spec.getName();
+            }
+        } else {
+            m_id = identity;
+        }
+
+        // Else wait the setSpecification call.
+    }
+
+    /**
+     * Set the specification of the current dependency.
+     * In order to store the id of the dependency, this
+     * method is override. This method is called during the
+     * configuration.
+     * @param spec : request service Class
+     * @see org.apache.felix.ipojo.util.DependencyModel#setSpecification(java.lang.Class)
+     */
+    public void setSpecification(Class spec) {
+        super.setSpecification(spec);
+        if (m_id == null) {
+            m_id = spec.getName();
+        }
+    }
+
+    public String getField() {
+        return m_field;
+    }
+
+    /**
+     * Add a callback to the dependency.
+     * This method is called during the configuration.
+     * @param callback : callback to add
+     */
+    protected void addDependencyCallback(DependencyCallback callback) {
+        if (m_callbacks == null) {
+            m_callbacks = new DependencyCallback[] { callback };
+        } else {
+            DependencyCallback[] newCallbacks = new DependencyCallback[m_callbacks.length + 1];
+            System.arraycopy(m_callbacks, 0, newCallbacks, 0, m_callbacks.length);
+            newCallbacks[m_callbacks.length] = callback;
+            m_callbacks = newCallbacks;
+        }
+    }
+
+
+    protected void addConstructorInjection(int index) throws ConfigurationException {
+        m_index = index;
+        m_usage = new ServiceUsage();
+        m_handler.getInstanceManager().register(index, this);
+    }
+
+    /**
+     * Stop the current dependency.
+     * @see org.apache.felix.ipojo.util.DependencyModel#stop()
+     */
+    public synchronized void stop() {
+        m_isStarted = false;
+        super.stop();
+    }
+
+    public DependencyHandler getHandler() {
+        return m_handler;
+    }
+
+    public synchronized boolean isFrozen() {
+        return m_isFrozen;
+    }
+
+    /**
+     * Unfreeze the dependency.
+     * @see org.apache.felix.ipojo.util.DependencyModel#unfreeze()
+     */
+    public synchronized void unfreeze() {
+        m_isFrozen = false;
+    }
+
+    /**
+     * Call the bind method.
+     * @param pojo : pojo instance on which calling the bind method.
+     */
+    protected void onObjectCreation(Object pojo) {
+
+        ServiceReference[] refs;
+        synchronized (this) {
+            if (!m_isStarted) { return; }
+
+            // We are notified of an instance creation, we have to freeze when the static policy is used
+            if (getBindingPolicy() == STATIC_BINDING_POLICY) {
+                m_isFrozen = true;
+            }
+
+            // Check optional case : nullable object case : do not call bind on nullable object
+            if (isOptional() && getSize() == 0) { return; }
+
+            refs = getServiceReferences(); // Stack confinement.
+        }
+
+        // This is a pretty strange case, but we don't have any service.
+        // This may happen during refresh.
+        // So we just return.
+        if (refs == null) {
+            return;
+        }
+
+        // Call bind callback.
+        for (int j = 0; m_callbacks != null && j < m_callbacks.length; j++) { // The array is constant.
+            if (m_callbacks[j].getMethodType() == DependencyCallback.BIND) {
+                if (isAggregate()) {
+                    for (int i = 0; i < refs.length; i++) {
+                        invokeCallback(m_callbacks[j], refs[i], pojo);
+                    }
+                } else {
+                    // Take the first reference.
+                    invokeCallback(m_callbacks[j], refs[0], pojo);
+                }
+            }
+        }
+    }
+
+    /**
+     * Call unbind callback method.
+     * @param ref : reference to send (if accepted) to the method
+     */
+    private void callUnbindMethod(ServiceReference ref) {
+        if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects() != null) {
+            for (int i = 0; m_callbacks != null && i < m_callbacks.length; i++) {
+                if (m_callbacks[i].getMethodType() == DependencyCallback.UNBIND) {
+                    invokeCallback(m_callbacks[i], ref, null); // Call on each created pojo objects.
+                }
+            }
+        }
+    }
+
+    /**
+     * Helper method calling the given callback.
+     * @param callback : callback to call.
+     * @param ref : service reference.
+     * @param pojo : pojo on which calling the callback, if null call on each created pojo objects.
+     */
+    private void invokeCallback(DependencyCallback callback, ServiceReference ref, Object pojo) {
+        try {
+            if (pojo == null) {
+                callback.call(ref, getService(ref));
+            } else {
+                callback.callOnInstance(pojo, ref, getService(ref));
+            }
+        } catch (NoSuchMethodException e) {
+            m_handler.error("The method " + callback.getMethodName() + " does not exist in the implementation class " + m_handler.getInstanceManager().getClassName(), e);
+            m_handler.getInstanceManager().stop();
+        } catch (IllegalAccessException e) {
+            m_handler.error("The method " + callback.getMethodName() + " is not accessible in the implementation class " + m_handler.getInstanceManager().getClassName(), e);
+            m_handler.getInstanceManager().stop();
+        } catch (InvocationTargetException e) {
+            m_handler.error("The method " + callback.getMethodName() + " in the implementation class " + m_handler.getInstanceManager().getClassName() + " throws an exception : " + e.getTargetException().getMessage(), e.getTargetException());
+            m_handler.getInstanceManager().stop();
+        }
+
+    }
+
+   /**
+    * Call 'modify' method with the service reference in parameter (if accepted).
+    * @param ref : the service reference of the modified service
+    */
+    private void callModifyMethod(ServiceReference ref) {
+        if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects() != null) {
+            for (int i = 0; m_callbacks != null && i < m_callbacks.length; i++) {
+                if (m_callbacks[i].getMethodType() == DependencyCallback.MODIFIED) {
+                    invokeCallback(m_callbacks[i], ref, null); // Call on each created pojo objects.
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Call  method with the service reference in parameter (if accepted).
+     * @param ref : the service reference of the new service
+     */
+    private void callBindMethod(ServiceReference ref) {
+        // call bind method :
+        // if (m_handler.getInstanceManager().getState() == InstanceManager.VALID) {
+        if (m_handler.getInstanceManager().getState() > InstanceManager.STOPPED && m_handler.getInstanceManager().getPojoObjects() != null) {
+            for (int i = 0; m_callbacks != null && i < m_callbacks.length; i++) {
+                if (m_callbacks[i].getMethodType() == DependencyCallback.BIND) {
+                    invokeCallback(m_callbacks[i], ref, null);
+                }
+            }
+        }
+    }
+
+    private Object createNullableObject() {
+         // To load the proxy we use the POJO class loader. Indeed, this classloader imports iPOJO (so can access to Nullable) and has
+        // access to the service specification.
+        try {
+            ClassLoader cl = new NullableClassLoader(
+                    getHandler().getInstanceManager().getClazz().getClassLoader(),
+                    getSpecification().getClassLoader());
+
+            m_nullable =
+                Proxy.newProxyInstance(cl, new Class[] {
+                        getSpecification(), Nullable.class }, new NullableObject()); // NOPMD
+
+        } catch (NoClassDefFoundError e) {
+            // A NoClassDefFoundError is thrown if the specification uses a class not accessible by the actual instance.
+            // It generally comes from a missing import.
+            throw new IllegalStateException("Cannot create the Nullable object, a referenced class cannot be loaded: " + e.getMessage());
+        } catch (Throwable e) { // Catch any other exception that can occurs
+            throw new IllegalStateException(
+                    "Cannot create the Nullable object, an unexpected error occurs: "
+                            + e.getMessage());
+        }
+
+        return m_nullable;
+    }
+
+    /**
+     * Start the dependency.
+     */
+    public void start() {
+
+        if (isOptional() && !isAggregate()) {
+            if (m_di == null) {
+                // If nullable are supported, create the nullable object.
+                if (m_supportNullable) {
+                    createNullableObject();
+                }
+            } else {
+                // Create the default-implementation object.
+                try {
+                    Class clazz = getHandler().getInstanceManager().getContext().getBundle().loadClass(m_di);
+                    m_nullable = clazz.newInstance();
+                } catch (IllegalAccessException e) {
+                    throw new IllegalStateException("Cannot load the default-implementation " + m_di + " : " + e.getMessage());
+                } catch (InstantiationException e) {
+                    throw new IllegalStateException("Cannot load the default-implementation " + m_di + " : " + e.getMessage());
+                } catch (ClassNotFoundException e) {
+                    throw new IllegalStateException("Cannot load the default-implementation " + m_di + " : " + e.getMessage());
+                } catch (Throwable e) { // Catch any other exception
+                    throw new IllegalStateException("Cannot load the default-implementation (unexpected exception) " + m_di + " : " + e.getMessage());
+                }
+            }
+        }
+
+        if (m_isProxy) {
+            if (isAggregate()) {
+                m_proxyObject = new ServiceCollection(this);
+            } else {
+                // Can we really proxy ? We can proxy only interfaces.
+                if (getSpecification().isInterface()) {
+                    String type = getHandler().getInstanceManager().getContext().getProperty(DependencyHandler.PROXY_TYPE_PROPERTY);
+                    if (type == null || type.equals(DependencyHandler.SMART_PROXY)) {
+                        SmartProxyFactory proxyFactory = new SmartProxyFactory(this.getClass().getClassLoader());
+                        m_proxyObject = proxyFactory.getProxy(getSpecification(), this);
+                    } else {
+                        DynamicProxyFactory proxyFactory = new DynamicProxyFactory();
+                        m_proxyObject = proxyFactory.getProxy(getSpecification());
+                    }
+                } else {
+                    m_handler.warn("Cannot create a proxy for a service dependency which is not an interface " +
+                            "- disabling proxy for " + getId());
+                }
+            }
+        }
+
+        super.start();
+        // Once the dependency is started, access to fields must be synchronized.
+        synchronized (this) {
+            if (getBindingPolicy() == STATIC_BINDING_POLICY && m_handler.getInstanceManager().getPojoObjects() != null) {
+                m_isFrozen = true;
+            }
+
+            m_isStarted = true;
+        }
+
+
+    }
+
+    protected DependencyCallback[] getCallbacks() {
+        return m_callbacks;
+    }
+
+    /**
+     * Set that this dependency is a service level dependency.
+     * This forces the scoping policy to be STRICT.
+     */
+    public void setServiceLevelDependency() {
+        m_isServiceLevelRequirement = true;
+        setBundleContext(new PolicyServiceContext(m_handler.getInstanceManager().getGlobalContext(), m_handler.getInstanceManager().getLocalServiceContext(), PolicyServiceContext.LOCAL));
+    }
+
+    public String getId() {
+        return m_id;
+    }
+
+    public boolean isServiceLevelRequirement() {
+        return m_isServiceLevelRequirement;
+    }
+
+
+    /**
+     * A new service has to be injected.
+     * @param reference : the new matching service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceArrival(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceArrival(ServiceReference reference) {
+        callBindMethod(reference);
+        //The method is only called when a new service arrives, or when the used one is replaced.
+    }
+
+    /**
+     * An already injected service is modified.
+     * @param reference : the modified service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceModification(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceModification(ServiceReference reference) {
+        callModifyMethod(reference);
+    }
+
+    /**
+     * A used (already injected) service disappears.
+     * @param ref : leaving service reference.
+     * @see org.apache.felix.ipojo.util.DependencyModel#onServiceDeparture(org.osgi.framework.ServiceReference)
+     */
+    public void onServiceDeparture(ServiceReference ref) {
+        callUnbindMethod(ref);
+    }
+
+    /**
+     * The dependency has been reconfigured.
+     * Call unbind method and then bind methods. If the dependency cache is not reset,
+     * the thread continues to get older services.
+     * @param departs : no more matching services.
+     * @param arrivals : new services
+     * @see org.apache.felix.ipojo.util.DependencyModel#onDependencyReconfiguration(org.osgi.framework.ServiceReference[], org.osgi.framework.ServiceReference[])
+     */
+    public void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals) {
+        for (int i = 0; departs != null && i < departs.length; i++) {
+            callUnbindMethod(departs[i]);
+        }
+
+        for (int i = 0; arrivals != null && i < arrivals.length; i++) {
+            callBindMethod(arrivals[i]);
+        }
+    }
+
+    /**
+     * Reset the thread local cache if used.
+     */
+    public void resetLocalCache() {
+        if (m_usage != null) {
+            Usage usage = (Usage) m_usage.get();
+            if (usage.m_stack > 0) {
+                createServiceObject(usage);
+            }
+        }
+    }
+
+    /**
+     * Get the used service references list.
+     * @return the used service reference or null if no service reference are available.
+     */
+    public List getServiceReferencesAsList() {
+        ServiceReference[] refs = super.getServiceReferences();
+        if (refs == null) {
+            return null;
+        } else {
+            return Arrays.asList(refs);
+        }
+    }
+
+    /**
+     * Called by the proxy to get  service objects to delegate a method.
+     * On aggregate dependencies, it returns a list.
+     * @return a service object or a nullable/default-implementation object.
+     * For aggregate dependencies it returns a list or an empty list.
+     */
+    public Object getService() {
+        // Check that we're in proxy mode.
+        if (! m_isProxy) {
+            throw new IllegalStateException("The dependency is not a proxied dependency");
+        }
+
+        Usage usage = (Usage) m_usage.get();
+        if (usage.m_stack == 0) { // uninitialized usage.
+            if (usage.m_componentStack > 0) {
+                // We comes from the component who didn't touch the service.
+                // So we initialize the usage.
+                createServiceObject(usage);
+                usage.inc(); // Start the caching, so set the stack level to 1
+                m_usage.set(usage);
+                if (isAggregate()) {
+                    Object obj =  usage.m_object;
+                    if (obj instanceof Set) {
+                        List list = new ArrayList();
+                        list.addAll((Set) obj);
+                        return list;
+                    } else {
+                        // We already have a list
+                        return obj;
+                    }
+                } else {
+                    return usage.m_object;
+                }
+            } else {
+                // External access => Immediate get.
+                if (isAggregate()) {
+                    ServiceReference[] refs = getServiceReferences();
+                    if (refs == null) {
+                        return new ArrayList(0); // Create an empty list.
+                    } else {
+                        List objs = new ArrayList(refs.length);
+                        for (int i = 0; refs != null && i < refs.length; i++) {
+                            ServiceReference ref = refs[i];
+                            objs.add(getService(ref));
+                        }
+                        return objs;
+                    }
+                } else { // Scalar dependency.
+                    ServiceReference ref = getServiceReference();
+                    if (ref != null) {
+                        return getService(ref);
+                    } else {
+                        // No service available.
+                        // TODO Decide what we have to do.
+                        throw new RuntimeException("Service " + getSpecification() + " unavailable");
+                    }
+                }
+            }
+        } else {
+            // Use the copy.
+            // if the copy is a set, transform to a list
+            if (isAggregate()) {
+                Object obj =  usage.m_object;
+                if (obj instanceof Set) {
+                    List list = new ArrayList();
+                    list.addAll((Set) obj);
+                    return list;
+                } else {
+                    // We already have a list
+                    return obj;
+                }
+            } else {
+                return usage.m_object;
+            }
+
+        }
+    }
+
+    /**
+     * This method is called by the replaced code in the component
+     * implementation class. Construct the service object list is necessary.
+     * @param pojo : POJO object.
+     * @param fieldName : field
+     * @param value : last value.
+     * @return the service object or a nullable / default implementation if defined.
+     * @see org.apache.felix.ipojo.FieldInterceptor#onGet(java.lang.Object, java.lang.String, java.lang.Object)
+     */
+    public Object onGet(Object pojo, String fieldName, Object value) {
+
+        // Initialize the thread local object is not already touched.
+        Usage usage = (Usage) m_usage.get();
+        if (usage.m_stack == 0) { // uninitialized usage.
+            createServiceObject(usage);
+            usage.inc(); // Start the caching, so set the stack level to 1
+            m_usage.set(usage);
+        }
+        if (! m_isProxy) {
+            return usage.m_object;
+        } else {
+            return m_proxyObject;
+        }
+
+    }
+
+
+    /**
+     * Creates the object to store in the given Thread Local.
+     * This object will be injected inside the POJO field.
+     * @param usage : Thread Local to populate.
+     */
+    private void createServiceObject(Usage usage) {
+        ServiceReference[] refs = getServiceReferences();
+        if (! isAggregate()) {
+            if (refs == null) {
+                if (m_nullable == null && m_supportNullable) {
+                    m_handler.warn("[" + m_handler.getInstanceManager().getInstanceName() + "] The dependency is not optional, however no service object can be injected in " + m_field + " -> " + getSpecification().getName());
+                    createNullableObject();
+                }
+                usage.m_object = m_nullable; // Add null if the Nullable pattern is disable.
+            } else {
+                ServiceReference ref = getServiceReference();
+                usage.m_object = getService(ref);
+            }
+        } else {
+            if (m_type == 0) { // Array
+                try {
+                    if (refs == null) {
+                        usage.m_object = (Object[]) Array.newInstance(getSpecification(), 0); // Create an empty array.
+                    } else {
+                        //  Use a reflective construction to avoid class cast exception. This method allows setting the component type.
+                        Object[] objs = (Object[]) Array.newInstance(getSpecification(), refs.length);
+                        for (int i = 0; refs != null && i < refs.length; i++) {
+                            ServiceReference ref = refs[i];
+                            objs[i] = getService(ref);
+                        }
+                        usage.m_object = objs;
+                    }
+                } catch (ArrayStoreException e) {
+                    m_handler.error("Cannot create the array - Check that the bundle can access the service interface", e);
+                    throw new RuntimeException("Cannot create the array - Check that the bundle can access the service interface : " + e.getMessage());
+                }
+            } else if (m_type == DependencyHandler.LIST) {
+                if (refs == null) {
+                    usage.m_object = new ArrayList(0); // Create an empty list.
+                } else {
+                   // Use a list to store service objects
+                    List objs = new ArrayList(refs.length);
+                    for (int i = 0; refs != null && i < refs.length; i++) {
+                        ServiceReference ref = refs[i];
+                        objs.add(getService(ref));
+                    }
+                    usage.m_object = objs;
+                }
+            } else if (m_type == DependencyHandler.VECTOR) {
+                if (refs == null) {
+                    usage.m_object = new Vector(0); // Create an empty vector.
+                } else {
+                   // Use a vector to store service objects
+                    Vector objs = new Vector(refs.length);
+                    for (int i = 0; refs != null && i < refs.length; i++) {
+                        ServiceReference ref = refs[i];
+                        objs.add(getService(ref));
+                    }
+                    usage.m_object = objs;
+                }
+            } else if (m_type == DependencyHandler.SET) {
+                if (refs == null) {
+                    usage.m_object = new HashSet(0); // Create an empty vector.
+                } else {
+                   // Use a vector to store service objects
+                    Set objs = new HashSet(refs.length);
+                    for (int i = 0; refs != null && i < refs.length; i++) {
+                        ServiceReference ref = refs[i];
+                        objs.add(getService(ref));
+                    }
+                    usage.m_object = objs;
+                }
+            }
+        }
+    }
+
+    /**
+     * The field was set.
+     * This method should not be call if the POJO is written correctly.
+     * @param pojo : POJO object
+     * @param fieldName : field name
+     * @param value : set value.
+     * @see org.apache.felix.ipojo.FieldInterceptor#onSet(java.lang.Object, java.lang.String, java.lang.Object)
+     */
+    public void onSet(Object pojo, String fieldName, Object value) {
+        // Nothing to do.
+    }
+
+    /**
+     * A POJO method will be invoked.
+     * @param pojo : Pojo object
+     * @param method : called method
+     * @param args : arguments
+     * @see org.apache.felix.ipojo.MethodInterceptor#onEntry(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+     */
+    public void onEntry(Object pojo, Member method, Object[] args) {
+        if (m_usage != null) {
+            Usage usage = (Usage) m_usage.get();
+            usage.incComponentStack(); // Increment the number of component access.
+            if (usage.m_stack > 0) {
+                usage.inc();
+                m_usage.set(usage); // Set the Thread local as value has been modified
+            }
+        }
+    }
+
+    /**
+     * A POJO method has thrown an error.
+     * This method does nothing and wait for the finally.
+     * @param pojo : POJO object.
+     * @param method : Method object.
+     * @param throwable : thrown error
+     * @see org.apache.felix.ipojo.MethodInterceptor#onError(java.lang.Object, java.lang.reflect.Method, java.lang.Throwable)
+     */
+    public void onError(Object pojo, Member method, Throwable throwable) {
+        // Nothing to do  : wait onFinally
+    }
+
+    /**
+     * A POJO method has returned.
+     * @param pojo : POJO object.
+     * @param method : Method object.
+     * @param returnedObj : returned object (null for void method)
+     * @see org.apache.felix.ipojo.MethodInterceptor#onExit(java.lang.Object, java.lang.reflect.Method, java.lang.Object)
+     */
+    public void onExit(Object pojo, Member method, Object returnedObj) {
+        // Nothing to do  : wait onFinally
+    }
+
+    /**
+     * A POJO method is finished.
+     * @param pojo : POJO object.
+     * @param method : Method object.
+     * @see org.apache.felix.ipojo.MethodInterceptor#onFinally(java.lang.Object, java.lang.reflect.Method)
+     */
+    public void onFinally(Object pojo, Member method) {
+        if (m_usage != null) {
+            Usage usage = (Usage) m_usage.get();
+            usage.decComponentStack();
+            if (usage.m_stack > 0) {
+                if (usage.dec()) {
+                    // Exit the method flow => Release all objects
+                    usage.clear();
+                    m_usage.set(usage); // Set the Thread local as value has been modified
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets true if the dependency use Nullable objects.
+     * @return true if the dependency is optional and supports nullable objects.
+     */
+    public boolean supportsNullable() {
+        return m_supportNullable;
+    }
+
+    public String getDefaultImplementation() {
+        return m_di;
+    }
+
+    public boolean isProxy() {
+        return m_isProxy;
+    }
+
+    public void setProxy(boolean proxy) {
+        m_isProxy = proxy;
+    }
+
+    /**
+     * Set the type to inject.
+     * This method set the dependency as aggregate.
+     * @param type either list of vector
+     */
+    protected void setType(int type) {
+        setAggregate(true);
+        m_type = type;
+    }
+
+    /**
+     * Classloader for nullable objects.
+     */
+    private class NullableClassLoader extends ClassLoader {
+       /**
+        * Component classloader.
+        */
+        private ClassLoader m_component;
+
+       /**
+        * Specification classloader.
+        */
+        private ClassLoader m_specification;
+
+        /**
+         * Creates a NullableClassLoader.
+         * @param cmp the component class loader.
+         * @param spec the specification class loader.
+         */
+        public NullableClassLoader(ClassLoader cmp, ClassLoader spec) {
+            m_component = cmp;
+            m_specification = spec;
+        }
+
+        /**
+         * Loads the given class.
+         * This method uses the classloader of the component class
+         * and (if not found) the specification classloader.
+         * @param name the class name
+         * @return the class object
+         * @throws ClassNotFoundException if the class is not found by the two classloaders.
+         * @see java.lang.ClassLoader#loadClass(java.lang.String)
+         */
+        public Class loadClass(String name) throws ClassNotFoundException {
+            try {
+                return m_component.loadClass(name);
+            } catch (ClassNotFoundException e) {
+                return m_specification.loadClass(name);
+            }
+        }
+
+
+    }
+
+    /**
+     * Creates smart proxy object for proxied scalar dependencies.
+     */
+    private class SmartProxyFactory extends ClassLoader {
+
+        /**
+         * Handler classloader, used to load the temporal dependency class.
+         */
+        private ClassLoader m_handlerCL;
+
+        /**
+         * Creates the proxy classloader.
+         * @param parent the handler classloader.
+         */
+        public SmartProxyFactory(ClassLoader parent) {
+            super(getHandler().getInstanceManager().getFactory().getBundleClassLoader());
+            m_handlerCL = parent;
+        }
+
+        /**
+         * Loads a proxy class generated for the given (interface) class.
+         * @param clazz the service specification to proxy
+         * @return the Class object of the proxy.
+         */
+        protected Class getProxyClass(Class clazz) {
+            byte[] clz = ProxyGenerator.dumpProxy(clazz); // Generate the proxy.
+            // Turn around the VM changes (FELIX-2716) about java.* classes.
+            String cn = clazz.getName();
+            if (cn.startsWith("java.")) {
+                cn = "$" + cn;
+            }
+            return defineClass(cn + "$$Proxy", clz, 0, clz.length);
+        }
+
+        /**
+         * Create a proxy object for the given specification. The proxy
+         * uses the given dependency to get the service object.
+         * @param spec the service specification (interface)
+         * @param dep the dependency used to get the service
+         * @return the proxy object.
+         */
+        public Object getProxy(Class spec, Dependency dep) {
+            try {
+                Class clazz = getProxyClass(getSpecification());
+                Constructor constructor = clazz.getConstructor(
+                        new Class[]{clazz.getClassLoader().loadClass(Dependency.class.getName())});
+                return constructor.newInstance(new Object[] {dep});
+            } catch (Throwable e) {
+                m_handler.error("Cannot create the proxy object", e);
+                m_handler.getInstanceManager().stop();
+                return null;
+            }
+        }
+
+        /**
+         * Loads the given class.
+         * This method uses the classloader of the specification class
+         * or the handler class loader.
+         * @param name the class name
+         * @return the class object
+         * @throws ClassNotFoundException if the class is not found by the two classloaders.
+         * @see java.lang.ClassLoader#loadClass(java.lang.String)
+         */
+        public Class loadClass(String name) throws ClassNotFoundException {
+            try {
+                return getHandler().getInstanceManager().getContext().getBundle().loadClass(name);
+            } catch (ClassNotFoundException e) {
+                return m_handlerCL.loadClass(name);
+            }
+        }
+    }
+
+    /**
+     * Creates java dynamic proxy object for proxied scalar dependencies.
+     */
+    private class DynamicProxyFactory implements InvocationHandler {
+
+        /**
+         * HashCode method.
+         */
+        private Method m_hashCodeMethod;
+
+        /**
+         * Equals method.
+         */
+        private Method m_equalsMethod;
+
+        /**
+         * toStirng method.
+         */
+        private Method m_toStringMethod;
+
+        /**
+         * Creates a DynamicProxyFactory.
+         */
+        public DynamicProxyFactory() {
+            try {
+                m_hashCodeMethod = Object.class.getMethod("hashCode", null);
+                m_equalsMethod = Object.class
+                    .getMethod("equals", new Class[] { Object.class });
+                m_toStringMethod = Object.class.getMethod("toString", null);
+            } catch (NoSuchMethodException e) {
+                throw new NoSuchMethodError(e.getMessage());
+            }
+        }
+
+        /**
+         * Creates a proxy object for the given specification. The proxy
+         * uses the given dependency to get the service object.
+         * @param spec the service specification (interface)
+         * @return the proxy object.
+         */
+        public Object getProxy(Class spec) {
+            return java.lang.reflect.Proxy.newProxyInstance(
+                    getHandler().getInstanceManager().getClazz().getClassLoader(),
+                    new Class[] {spec},
+                    this);
+        }
+
+        /**
+         * Invocation Handler delegating invocation on the
+         * service object.
+         * @param proxy the proxy object
+         * @param method the method
+         * @param args the arguments
+         * @return a proxy object.
+         * @throws Exception if the invocation throws an exception
+         * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+         */
+        public Object invoke(Object proxy, Method method, Object[] args) throws Exception {
+            Object svc = getService();
+            Class declaringClass = method.getDeclaringClass();
+            if (declaringClass == Object.class) {
+                if (method.equals(m_hashCodeMethod)) {
+                    return new Integer(this.hashCode());
+                } else if (method.equals(m_equalsMethod)) {
+                    return proxy == args[0] ? Boolean.TRUE : Boolean.FALSE;
+                } else if (method.equals(m_toStringMethod)) {
+                    return this.toString();
+                } else {
+                    throw new InternalError(
+                            "Unexpected Object method dispatched: " + method);
+                }
+            }
+
+            return method.invoke(svc, args);
+        }
+
+    }
+
+    /**
+     * Gets the constructor parameter.
+     * @return the index of the constructor parameter,
+     * or <code>-1</code> if not set.
+     */
+    public int getConstructorParameterIndex() {
+        return m_index;
+    }
+
+    /**
+     * Gets the object to inject in the constructor parameter.
+     * @param index the index of the parameter
+     * @return the created proxy object
+     * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameter(int)
+     */
+    public Object getConstructorParameter(int index) {
+        if (m_index == index  && m_proxyObject != null) {
+            return m_proxyObject;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the type of the constructor parameter.
+     * @param index the parameter index
+     * @return the class of the object. For scalar dependency, it's the
+     * specification, for aggregate it depends of the container object:
+     * {@link List} or {@link Set}.
+     * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameterType(int)
+     */
+    public Class getConstructorParameterType(int index) {
+        if (m_index == index  && m_proxyObject != null) {
+            if (isAggregate()) {
+                switch (m_type) {
+                case DependencyHandler.LIST: return List.class;
+                case DependencyHandler.SET : return Set.class;
+                //TODO We should also manage the Collection type.
+                default: return null; // Should never happen, it was checked before.
+                }
+            } else {
+                return getSpecification();
+            }
+        } else {
+            return null;
+        }
+    }
+
+
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
new file mode 100644
index 0000000..571a92c
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyCallback.java
@@ -0,0 +1,325 @@
+/* 
+ * 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.handlers.dependency;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.util.Callback;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * This class allwos the creation of callback when service dependency arrives or
+ * disappear.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DependencyCallback extends Callback {
+
+    /**
+     * Bind method (called when a service arrives).
+     */
+    public static final int BIND = 0;
+
+    /**
+     * Unbind method (called when a service disappears).
+     */
+    public static final int UNBIND = 1;
+    
+    /**
+     * Updated method (called when a service is modified).
+     */
+    public static final int MODIFIED = 2;
+
+    /**
+     * Is the method a bind method or an unbind method ?
+     */
+    private int m_methodType;
+    
+    /**
+     * Arguments of the callback.
+     */
+    private String[] m_argument;
+
+    /**
+     * Callback method name.
+     */
+    private String m_method;
+    
+    /**
+     * Service Dependency. 
+     */
+    private Dependency m_dependency;
+
+    /**
+     * Constructor.
+     * 
+     * @param dep : the dependency attached to this dependency callback
+     * @param method : the method to call
+     * @param methodType : is the method to call a bind method or an unbind
+     * method
+     */
+    public DependencyCallback(Dependency dep, String method, int methodType) {
+        super(method, (String[]) null, false, dep.getHandler().getInstanceManager());
+        m_methodType = methodType;
+        m_dependency = dep;
+        m_method = method;
+    }
+
+
+    public int getMethodType() {
+        return m_methodType;
+    }
+    
+    public String getMethodName() {
+        return m_method;
+    }
+    
+    /**
+     * Set the argument type (Empty or the class name).
+     * @param arg : the array of argument types.
+     */
+    public void setArgument(String[] arg) {
+        m_argument = arg;
+    }
+    
+    /**
+     * Search the method object in the POJO by analyzing present method.
+     * If not found in the pojo it tests the parent classes.
+     * The name of the method and the argument type are checked.
+     */
+    protected void searchMethod() {
+        if (m_argument != null) {
+            Method[] methods = m_dependency.getHandler().getInstanceManager().getClazz().getDeclaredMethods();
+            for (int i = 0; i < methods.length; i++) {
+                // First check the method name
+                if (methods[i].getName().equals(m_method)) {
+                    // Check arguments
+                    Class[] clazzes = methods[i].getParameterTypes();
+                    if (clazzes.length == m_argument.length) { // Test size to avoid useless loop // NOPMD
+                        int argIndex = 0;
+                        for (; argIndex < m_argument.length; argIndex++) {
+                            if (!m_argument[argIndex].equals(clazzes[argIndex].getName())) {
+                                break;
+                            }
+                        }
+                        if (argIndex == m_argument.length) { // If the array was completely read.
+                            m_methodObj = methods[i]; // It is the looked method.
+                            if (! m_methodObj.isAccessible()) { 
+                                // If not accessible, try to set the accessibility.
+                                m_methodObj.setAccessible(true);
+                            }
+                            return;
+                        }
+                    }
+
+                }
+            }
+        }
+        
+        // Not found => Try parent method.
+        searchParentMethod();
+        
+        if (m_methodObj == null) {
+            // If not found, stop the instance (fatal error)
+            m_dependency.getHandler().error("The method " + m_method + " cannot be called : method not found");
+            m_dependency.getHandler().getInstanceManager().stop();
+        } else {
+            if (! m_methodObj.isAccessible()) { 
+                // If not accessible, try to set the accessibility.
+                m_methodObj.setAccessible(true);
+            }
+        }
+    }
+    
+    /**
+     * Introspect parent class to find the method.
+     */
+    private void searchParentMethod() {
+        // look at parent classes
+        Method[] methods = m_dependency.getHandler().getInstanceManager().getClazz().getMethods();
+        for (int i = 0; i < methods.length; i++) {
+            // First check the method name
+            if (methods[i].getName().equals(m_method)) {
+                // Check arguments
+                Class[] clazzes = methods[i].getParameterTypes();
+                switch (clazzes.length) {
+                    case 0:
+                        // Callback with no arguments.
+                        m_methodObj = methods[i];
+                        m_argument = new String[0];
+                        return;
+                    case 1:
+                        // The callback receives a ServiceReference
+                        if (clazzes[0].getName().equals(ServiceReference.class.getName())) {
+                            // Callback with a service reference.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { ServiceReference.class.getName() };
+                            return;
+                        }
+                        // The callback receives a Service object
+                        if (clazzes[0].getName().equals(m_dependency.getSpecification().getName())) {
+                            // Callback with the service object.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { m_dependency.getSpecification().getName() };
+                            return;
+                        }
+                        break;
+                    case 2:
+                        // The callback receives the service object and the service reference
+                        if (clazzes[0].getName().equals(m_dependency.getSpecification().getName()) && clazzes[1].getName().equals(ServiceReference.class.getName())) {
+                            // Callback with two arguments.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { m_dependency.getSpecification().getName(), ServiceReference.class.getName() };
+                            return;
+                        }
+                        // The callback receives the service object and the service properties (in a Map)
+                        if (clazzes[0].getName().equals(m_dependency.getSpecification().getName()) && clazzes[1].getName().equals(Map.class.getName())) {
+                            // Callback with two arguments.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { m_dependency.getSpecification().getName(), Map.class.getName() };
+                            return;
+                        }
+                        // The callback receives the service object and the service properties (in a Dictionary)
+                        if (clazzes[0].getName().equals(m_dependency.getSpecification().getName()) && clazzes[1].getName().equals(Dictionary.class.getName())) {
+                            // Callback with two arguments.
+                            m_methodObj = methods[i];
+                            m_argument = new String[] { m_dependency.getSpecification().getName(), Dictionary.class.getName() };
+                            return;
+                        }
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Call the callback method with a service reference.
+     * 
+     * @param ref : the service reference to send to the method
+     * @param obj : the service object
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    protected void call(ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        if (m_methodObj == null) {
+            searchMethod();
+        }
+        switch (m_argument.length) {
+            case 0 :
+                call(new Object[0]);
+                break;
+            case 1 : 
+                if (m_argument[0].equals(ServiceReference.class.getName())) {
+                    call(new Object[] {ref});
+                } else {
+                    call(new Object[] {obj});
+                }
+                break;
+            case 2 :
+                if (m_argument[1].equals(ServiceReference.class.getName())) {
+                    call(new Object[] {obj, ref});
+                } else if (m_argument[1].equals(Dictionary.class.getName())) {
+                    call(new Object[] {obj, getPropertiesInDictionary(ref)});
+                } else {
+                    call(new Object[] {obj, getPropertiesInMap(ref)});
+                }
+                break;
+            default : 
+                break;
+        }
+    }
+
+    /**
+     * Creates a {@link Dictionary} containing service properties of the
+     * given service reference.
+     * @param ref the service reference
+     * @return a {@link Dictionary} containing the service properties.
+     */
+    private Dictionary getPropertiesInDictionary(ServiceReference ref) {
+        String[] keys = ref.getPropertyKeys(); // Can't be null
+        Dictionary dict = new Properties();
+        for (int i = 0; i < keys.length; i++) {
+            dict.put(keys[i], ref.getProperty(keys[i]));
+        }
+        return dict;
+    }
+    
+    /**
+     * Creates a {@link Map} containing service properties of the
+     * given service reference.
+     * @param ref the service reference
+     * @return a {@link Map} containing the service properties.
+     */
+    private Map getPropertiesInMap(ServiceReference ref) {
+        String[] keys = ref.getPropertyKeys(); // Can't be null
+        Map map = new HashMap();
+        for (int i = 0; i < keys.length; i++) {
+            map.put(keys[i], ref.getProperty(keys[i]));
+        }
+        return map;
+    }
+
+
+    /**
+     * Call the callback on the given instance with the given argument.
+     * 
+     * @param instance : the instance on which call the callback
+     * @param ref : the service reference to send to the callback
+     * @param obj : the service object
+     * @throws NoSuchMethodException : the method is not found
+     * @throws IllegalAccessException : the method could not be called
+     * @throws InvocationTargetException : an error happens in the called method
+     */
+    protected void callOnInstance(Object instance, ServiceReference ref, Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        if (m_methodObj == null) {
+            searchMethod();
+        }
+        switch (m_argument.length) {
+            case 0 :
+                call(instance, new Object[0]);
+                break;
+            case 1 : 
+                if (m_argument[0].equals(ServiceReference.class.getName())) {
+                    call(instance, new Object[] {ref});
+                } else {
+                    call(instance, new Object[] {obj});
+                }
+                break;
+            case 2 :
+                if (m_argument[1].equals(ServiceReference.class.getName())) {
+                    call(instance, new Object[] {obj, ref});
+                } else if (m_argument[1].equals(Dictionary.class.getName())) {
+                    call(instance, new Object[] {obj, getPropertiesInDictionary(ref)});
+                } else {
+                    call(instance, new Object[] {obj, getPropertiesInMap(ref)});
+                }
+                break;
+            default : 
+                break;
+        }
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
new file mode 100644
index 0000000..c4c4531
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyDescription.java
@@ -0,0 +1,146 @@
+/* 
+ * 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.handlers.dependency;
+
+import java.util.Comparator;
+import java.util.List;
+
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Service Dependency Description.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DependencyDescription {
+    /**
+     * The described dependency.
+     */
+    private Dependency m_dependency;
+
+    /**
+     * Creates a dependency description.
+     * @param dep the described dependency
+     */
+    public DependencyDescription(Dependency dep) {
+        m_dependency = dep;
+    }
+
+    public boolean isMultiple() { return m_dependency.isAggregate(); }
+
+    public boolean isOptional() { return m_dependency.isOptional(); }
+
+    public String getFilter() { return m_dependency.getFilter(); }
+
+    public String getInterface() { return m_dependency.getSpecification().getName(); }
+
+    public int getState() { return m_dependency.getState(); }
+    
+    public String getId() { return m_dependency.getId(); }
+    
+    public boolean isProxy() { return m_dependency.isProxy(); }
+
+    
+    /**
+     * Gets <code>true</code> if the dependency uses Nullable objects.
+     * @return true if the dependency is optional and supports nullable object.
+     */
+    public boolean supportsNullable() { return m_dependency.supportsNullable(); }
+    
+    public String getDefaultImplementation() { return m_dependency.getDefaultImplementation(); }
+    
+    public int getPolicy() { return m_dependency.getBindingPolicy(); }
+    
+    public String getComparator() { return m_dependency.getComparator(); }
+    
+    public boolean isFrozen() { return m_dependency.isFrozen(); }
+
+    /**
+     * Gets the service reference list.
+     * @return the list of matching service reference,
+     * <code>null</code> if no service reference.
+     */
+    public List getServiceReferences() { return m_dependency.getServiceReferencesAsList(); }
+
+    /**
+     * Gets the service reference if only one service reference is used.
+     * @return the ServiceReference (only if the cardinality could be 1),
+     * or <code>null</code> if no service reference.
+     */
+    public ServiceReference getServiceReference() { 
+        List list = getServiceReferences();
+        if (list == null) {
+            return null;
+        } else {
+            return (ServiceReference) list.get(0);
+        }
+    }
+
+    /**
+     * Gets the used service set.
+     * @return the list [service reference] containing the used services,
+     * <code>null</code> if no providers are used
+     */
+    public List getUsedServices() { return m_dependency.getUsedServiceReferences(); }
+    
+    /**
+     * Sets the dependency comparator.
+     * The reference set will be sort at the next usage.
+     * @param cmp the comparator
+     */
+    public void setComparator(Comparator cmp) {
+        m_dependency.setComparator(cmp);
+    }
+    
+    /**
+     * Sets the dependency filter.
+     * @param filter the new LDAP filter
+     */
+    public void setFilter(Filter filter) {
+        m_dependency.setFilter(filter);
+    }
+    
+    /**
+     * Sets the dependency cardinality.
+     * @param isAgg if <code>true</code> sets the dependency to aggregate,
+     * if <code>false</code> sets the dependency to scalar.
+     */
+    public void setAggregate(boolean isAgg) {
+        m_dependency.setAggregate(isAgg);
+    }
+    
+    /**
+     * Sets the dependency optionality.
+     * @param isOpt if <code>true</code> sets the dependency to optional,
+     * if <code>false</code> sets the dependency to mandatory.
+     */
+    public void setOptional(boolean isOpt) {
+        m_dependency.setOptionality(isOpt);
+    }
+
+    /**
+     * Gets the required service specification name.
+     * @return the required service specification class name.
+     */
+    public String getSpecification() {
+        return m_dependency.getSpecification().getName();
+    }
+    
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
new file mode 100644
index 0000000..a9e3eec
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandler.java
@@ -0,0 +1,656 @@
+/*
+ * 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.handlers.dependency;
+
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.IPojoContext;
+import org.apache.felix.ipojo.PolicyServiceContext;
+import org.apache.felix.ipojo.PrimitiveHandler;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.FieldMetadata;
+import org.apache.felix.ipojo.parser.MethodMetadata;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.apache.felix.ipojo.util.DependencyStateListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * The dependency handler manages a list of service dependencies.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DependencyHandler extends PrimitiveHandler implements DependencyStateListener {
+
+    /**
+     * Proxy settings property.
+     */
+    public static final String PROXY_SETTINGS_PROPERTY = "ipojo.proxy";
+
+    /**
+     * Proxy type property.
+     */
+    public static final String PROXY_TYPE_PROPERTY = "ipojo.proxy.type";
+
+    /**
+     * Proxy type value: smart.
+     */
+    public static final String SMART_PROXY = "smart";
+
+    /**
+     * Proxy type value: dynamic-proxy.
+     */
+    public static final String DYNAMIC_PROXY = "dynamic-proxy";
+
+    /**
+     * Proxy settings value: enabled.
+     */
+    public static final String PROXY_ENABLED = "enabled";
+
+    /**
+     * Proxy settings value: disabled.
+     */
+    public static final String PROXY_DISABLED = "disabled";
+
+    /**
+     * Dependency field type : Vector
+     * The dependency will be injected as a vector.
+     */
+    protected static final int VECTOR = 2;
+
+    /**
+     * Dependency Field Type : List.
+     * The dependency will be injected as a list.
+     */
+    protected static final int LIST = 1;
+
+    /**
+     * Dependency Field Type : Set.
+     * The dependency will be injected as a set.
+     */
+    protected static final int SET = 3;
+
+    /**
+     * List of dependencies of the component.
+     */
+    private Dependency[] m_dependencies = new Dependency[0];
+
+    /**
+     * Is the handler started.
+     */
+    private boolean m_started;
+
+    /**
+     * The handler description.
+     */
+    private DependencyHandlerDescription m_description;
+
+    /**
+     * Add a dependency.
+     * @param dep : the dependency to add
+     */
+    private void addDependency(Dependency dep) {
+        for (int i = 0; m_dependencies != null && i < m_dependencies.length; i++) {
+            if (m_dependencies[i] == dep) {
+                return;
+            }
+        }
+        if (m_dependencies == null) {
+            m_dependencies = new Dependency[] { dep };
+        } else {
+            Dependency[] newDep = new Dependency[m_dependencies.length + 1];
+            System.arraycopy(m_dependencies, 0, newDep, 0, m_dependencies.length);
+            newDep[m_dependencies.length] = dep;
+            m_dependencies = newDep;
+        }
+    }
+
+    /**
+     * Get the list of managed dependency.
+     * @return the dependency list
+     */
+    public Dependency[] getDependencies() {
+        return m_dependencies;
+    }
+
+    /**
+     * Validate method. This method is invoked by an AbstractServiceDependency when this dependency becomes RESOLVED.
+     * @param dep : the dependency becoming RESOLVED.
+     * @see org.apache.felix.ipojo.util.DependencyStateListener#validate(org.apache.felix.ipojo.util.DependencyModel)
+     */
+    public void validate(DependencyModel dep) {
+        checkContext();
+    }
+
+    /**
+     * Invalidate method. This method is invoked by an AbstractServiceDependency when this dependency becomes UNRESOLVED or BROKEN.
+     * @param dep : the dependency becoming UNRESOLVED or BROKEN.
+     * @see org.apache.felix.ipojo.util.DependencyStateListener#invalidate(org.apache.felix.ipojo.util.DependencyModel)
+     */
+    public void invalidate(DependencyModel dep) {
+        setValidity(false);
+    }
+
+    /**
+     * Check the validity of the dependencies.
+     */
+    protected void checkContext() {
+        if (!m_started) {
+            return;
+        }
+        synchronized (m_dependencies) {
+            // Store the initial state
+            boolean initialState = getValidity();
+
+            boolean valid = true;
+            for (int i = 0; i < m_dependencies.length; i++) {
+                Dependency dep = m_dependencies[i];
+                if (dep.getState() != Dependency.RESOLVED) {
+                    valid = false;
+                    break;
+                }
+            }
+
+            // Check the component dependencies
+            if (valid) {
+                // The dependencies are valid
+                if (!initialState) {
+                    // There is a state change
+                    setValidity(true);
+                }
+                // Else do nothing, the component state stay VALID
+            } else {
+                // The dependencies are not valid
+                if (initialState) {
+                    // There is a state change
+                    setValidity(false);
+                }
+                // Else do nothing, the component state stay UNRESOLVED
+            }
+
+        }
+    }
+
+    /**
+     * Check if the dependency given is valid in the sense that metadata are consistent.
+     * @param dep : the dependency to check
+     * @param manipulation : the component-type manipulation metadata
+     * @return true if the dependency is valid
+     * @throws ConfigurationException : the checked dependency is not correct
+     */
+    private boolean checkDependency(Dependency dep, PojoMetadata manipulation) throws ConfigurationException {
+        // Check the internal type of dependency
+        String field = dep.getField();
+        DependencyCallback[] callbacks = dep.getCallbacks();
+        int index = dep.getConstructorParameterIndex();
+
+        if (callbacks == null && field == null  && index == -1) {
+            throw new ConfigurationException("A service requirement requires at least binding methods, " +
+            		"a field or a constructor parameter");
+        }
+
+        for (int i = 0; callbacks != null && i < callbacks.length; i++) {
+            MethodMetadata[] mets = manipulation.getMethods(callbacks[i].getMethodName());
+            if (mets.length == 0) {
+                debug("A requirement callback " + callbacks[i].getMethodName() + " does not exist in the implementation class, will try the super classes");
+            } else {
+                if (mets[0].getMethodArguments().length > 2) {
+                    throw new ConfigurationException("Requirement Callback : A requirement callback "
+                            + callbacks[i].getMethodName()
+                            + " must have 0, 1 or 2 arguments");
+                }
+
+                callbacks[i].setArgument(mets[0].getMethodArguments());
+
+                if (mets[0].getMethodArguments().length == 1) {
+                    if (!mets[0].getMethodArguments()[0].equals(ServiceReference.class.getName())) {
+                        // The callback receives the service object.
+                        setSpecification(dep, mets[0].getMethodArguments()[0], false); // Just warn if a mismatch is discovered.
+                    }
+                } else if (mets[0].getMethodArguments().length == 2) {
+                    // The callback receives service object, service reference. Check that the second argument is a service reference
+                    if (!(mets[0].getMethodArguments()[1].equals(ServiceReference.class.getName()) // callback with (service object, service reference)
+                           || mets[0].getMethodArguments()[1].equals(Dictionary.class.getName()) // callback with (service object, service properties in a dictionary)
+                           || mets[0].getMethodArguments()[1].equals(Map.class.getName()))) { // callback with (service object, service properties in a map)
+                        String message =
+                                "The requirement callback " + callbacks[i].getMethodName() + " must have a ServiceReference, a Dictionary or a Map as the second argument";
+                        throw new ConfigurationException(message);
+                    }
+                    setSpecification(dep, mets[0].getMethodArguments()[0], false); // Just warn if a mismatch is discovered.
+                }
+            }
+
+        }
+
+        if (field != null) {
+            FieldMetadata meta = manipulation.getField(field);
+            if (meta == null) {
+                throw new ConfigurationException("Requirement Callback : A requirement field "
+                        + field
+                        + " does not exist in the implementation class");
+            }
+            String type = meta.getFieldType();
+            if (type.endsWith("[]")) {
+                if (dep.isProxy()) {
+                    info("Arrays cannot be used for proxied dependencies - Disabling the proxy mode");
+                    dep.setProxy(false);
+                }
+                // Set the dependency to multiple
+                dep.setAggregate(true);
+                type = type.substring(0, type.length() - 2);
+            } else if (type.equals(List.class.getName()) || type.equals(Collection.class.getName())) {
+                dep.setType(LIST);
+                type = null;
+            } else if (type.equals(Vector.class.getName())) {
+                dep.setType(VECTOR);
+                if (dep.isProxy()) {
+                    warn("Vectors cannot be used for proxied dependencies - Disabling the proxy mode");
+                    dep.setProxy(false);
+                }
+                type = null;
+            } else if (type.equals(Set.class.getName())) {
+                dep.setType(SET);
+                type = null;
+            } else {
+                if (dep.isAggregate()) {
+                    throw new ConfigurationException("A required service is not correct : the field "
+                            + meta.getFieldName()
+                            + " must be an array to support aggregate injections");
+                }
+            }
+            setSpecification(dep, type, true); // Throws an exception if the field type mismatch.
+        }
+
+        // Constructor parameter
+        if (index != -1) {
+        	if (! dep.isProxy()) {
+        		throw new ConfigurationException("Services injected into constructor must be proxied");
+        	}
+
+    		MethodMetadata[] cts = manipulation.getConstructors();
+    		// If we don't have a type, try to get the first constructor and get the type of the parameter
+    		// we the index 'index'.
+    		if (cts.length > 0  && cts[0].getMethodArguments().length > index) {
+        		String type = cts[0].getMethodArguments()[index];
+        		if (type.endsWith("[]")) {
+                    throw new ConfigurationException("Services injected into constructor cannot be arrays");
+                } else if (type.equals(List.class.getName()) || type.equals(Collection.class.getName())) {
+                    dep.setType(LIST);
+                    type = null;
+                } else if (type.equals(Vector.class.getName())) {
+                	throw new ConfigurationException("Services injected into constructor cannot be Vectors");
+                } else if (type.equals(Set.class.getName())) {
+                    dep.setType(SET);
+                    type = null;
+                } else {
+                    if (dep.isAggregate()) {
+                        throw new ConfigurationException("A required service is not correct : the constructor parameter "
+                                + index
+                                + " must be an aggregate type to support aggregate injections");
+                    }
+                }
+                setSpecification(dep, type, true); // Throws an exception if the field type mismatch.
+        	} else {
+        		throw new ConfigurationException("Cannot determine the specification of the dependency " + index +
+        				", please use the specification attribute");
+        	}
+        }
+
+        // Disable proxy on scalar dependency targeting non-interface specification
+        if (! dep.isAggregate()  && dep.isProxy()) {
+        	if (! dep.getSpecification().isInterface()) {
+        		warn("Proxies cannot be used on service dependency targetting non interface " +
+        				"service specification " + dep.getSpecification().getName());
+        		dep.setProxy(false);
+        	}
+        }
+
+        // Disables proxy on null (nullable=false)
+//        if (dep.isProxy()  && dep.isOptional() && ! dep.supportsNullable()) {
+//            dep.setProxy(false);
+//            warn("Optional Null Dependencies do not support proxying - Disable the proxy mode");
+//        }
+
+        // Check that all required info are set
+        return dep.getSpecification() != null;
+    }
+
+    /**
+     * Check if we have to set the dependency specification with the given class name.
+     * @param dep : dependency to check
+     * @param className : class name
+     * @param error : set to true to throw an error if the set dependency specification and the given specification are different.
+     * @throws ConfigurationException : the specification class cannot be loaded correctly
+     */
+    private void setSpecification(Dependency dep, String className, boolean error) throws ConfigurationException {
+        if (className == null) {
+            // No found type (list and vector)
+            if (dep.getSpecification() == null) {
+                if (error) {
+                	String id = dep.getId();
+                	if (id == null) {
+                		id = dep.getField();
+                		if (id == null) {
+                			id = Integer.toString(dep.getConstructorParameterIndex());
+                		}
+                	}
+                    throw new ConfigurationException("Cannot discover the required specification for " + id);
+                } else {
+                    // If the specification is different, warn that we will override it.
+                    info("Cannot discover the required specification for " + dep.getField());
+                }
+            }
+        } else { // In all other case, className is not null.
+            if (dep.getSpecification() == null || !dep.getSpecification().getName().equals(className)) {
+                if (dep.getSpecification() != null) {
+                    if (error) {
+                        throw new ConfigurationException("A required service is not correct : the discovered type ["
+                            + className
+                            + "] and the specified (or already discovered)  service interface ["
+                            + dep.getSpecification().getName()
+                            + "] are not the same");
+                    } else {
+                        // If the specification is different, warn that we will override it.
+                        warn("["
+                            + getInstanceManager().getInstanceName()
+                            + "] The field type ["
+                            + className
+                            + "] and the required service interface ["
+                            + dep.getSpecification()
+                            + "] are not the same");
+                    }
+                }
+
+                try {
+                    dep.setSpecification(getInstanceManager().getContext().getBundle().loadClass(className));
+                } catch (ClassNotFoundException e) {
+                    throw new ConfigurationException("The required service interface cannot be loaded : " + e.getMessage());
+                }
+            }
+        }
+    }
+
+    /**
+     * Configure the handler.
+     * @param componentMetadata : the component type metadata
+     * @param configuration : the instance configuration
+     * @throws ConfigurationException : one dependency metadata is not correct.
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element componentMetadata, Dictionary configuration) throws ConfigurationException {
+        PojoMetadata manipulation = getFactory().getPojoMetadata();
+        boolean atLeastOneField = false;
+
+        // Create the dependency according to the component metadata
+        Element[] deps = componentMetadata.getElements("Requires");
+
+        // Get instance filters.
+        Dictionary filtersConfiguration = getRequiresFilters(configuration.get("requires.filters"));
+        Dictionary fromConfiguration = (Dictionary) configuration.get("requires.from");
+
+        for (int i = 0; deps != null && i < deps.length; i++) {
+            // Create the dependency metadata
+            String field = deps[i].getAttribute("field");
+
+            String serviceSpecification = deps[i].getAttribute("interface");
+            // the 'interface' attribute is deprecated
+            if (serviceSpecification != null) {
+                warn("The 'interface' attribute is deprecated, use the 'specification' attribute instead");
+            } else {
+                serviceSpecification = deps[i].getAttribute("specification");
+            }
+
+            String filter = deps[i].getAttribute("filter");
+            String opt = deps[i].getAttribute("optional");
+            boolean optional = opt != null && opt.equalsIgnoreCase("true");
+            String defaultImplem = deps[i].getAttribute("default-implementation");
+
+            String agg = deps[i].getAttribute("aggregate");
+            boolean aggregate = agg != null && agg.equalsIgnoreCase("true");
+            String identitity = deps[i].getAttribute("id");
+
+            String nul = deps[i].getAttribute("nullable");
+            boolean nullable = nul == null || nul.equalsIgnoreCase("true");
+
+            boolean isProxy = true;
+            // Detect proxy default value.
+            String setting = getInstanceManager().getContext().getProperty(PROXY_SETTINGS_PROPERTY);
+            if (setting == null || PROXY_ENABLED.equals(setting)) { // If not set => Enabled
+                isProxy = true;
+            } else if (setting != null  && PROXY_DISABLED.equals(setting)) {
+                isProxy = false;
+            }
+
+            String proxy = deps[i].getAttribute("proxy");
+            // If proxy == null, use default value
+            if (proxy != null) {
+                if (proxy.equals("false")) {
+                    isProxy = false;
+                } else if (proxy.equals("true")) {
+                    if (! isProxy) { // The configuration overrides the system setting
+                        warn("The configuration of a service dependency overrides the proxy mode");
+                    }
+                    isProxy = true;
+                }
+            }
+
+            String scope = deps[i].getAttribute("scope");
+            BundleContext context = getInstanceManager().getContext(); // Get the default bundle context.
+            if (scope != null) {
+                // If we are not in a composite, the policy is set to global.
+                if (scope.equalsIgnoreCase("global") || ((((IPojoContext) getInstanceManager().getContext()).getServiceContext()) == null)) {
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.GLOBAL);
+                } else if (scope.equalsIgnoreCase("composite")) {
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.LOCAL);
+                } else if (scope.equalsIgnoreCase("composite+global")) {
+                    context =
+                            new PolicyServiceContext(getInstanceManager().getGlobalContext(), getInstanceManager().getLocalServiceContext(),
+                                    PolicyServiceContext.LOCAL_AND_GLOBAL);
+                }
+            }
+
+            // Get instance filter if available
+            if (filtersConfiguration != null && identitity != null && filtersConfiguration.get(identitity) != null) {
+                filter = (String) filtersConfiguration.get(identitity);
+            }
+
+            // Compute the 'from' attribute
+            String from = deps[i].getAttribute("from");
+            if (fromConfiguration != null && identitity != null && fromConfiguration.get(identitity) != null) {
+                from = (String) fromConfiguration.get(identitity);
+            }
+            if (from != null) {
+                String fromFilter = "(|(instance.name=" + from + ")(service.pid=" + from + "))";
+                if (aggregate) {
+                    warn("The 'from' attribute is incompatible with aggregate requirements: only one provider will match : " + fromFilter);
+                }
+                if (filter != null) {
+                    filter = "(&" + fromFilter + filter + ")"; // Append the two filters
+                } else {
+                    filter = fromFilter;
+                }
+            }
+
+            Filter fil = null;
+            if (filter != null) {
+                try {
+                    fil = getInstanceManager().getContext().createFilter(filter);
+                } catch (InvalidSyntaxException e) {
+                    throw new ConfigurationException("A requirement filter is invalid : " + filter + " - " + e.getMessage());
+                }
+            }
+
+
+            Class spec = null;
+            if (serviceSpecification != null) {
+                spec = DependencyModel.loadSpecification(serviceSpecification, getInstanceManager().getContext());
+            }
+
+            int policy = DependencyModel.getPolicy(deps[i]);
+            Comparator cmp = DependencyModel.getComparator(deps[i], getInstanceManager().getGlobalContext());
+
+
+            Dependency dep = new Dependency(this, field, spec, fil, optional, aggregate, nullable, isProxy, identitity, context, policy, cmp, defaultImplem);
+
+            // Look for dependency callback :
+            Element[] cbs = deps[i].getElements("Callback");
+            for (int j = 0; cbs != null && j < cbs.length; j++) {
+                if (!cbs[j].containsAttribute("method") && cbs[j].containsAttribute("type")) {
+                    throw new ConfigurationException("Requirement Callback : a dependency callback must contain a method and a type (bind or unbind) attribute");
+                }
+                String method = cbs[j].getAttribute("method");
+                String type = cbs[j].getAttribute("type");
+                int methodType = 0;
+                if ("bind".equalsIgnoreCase(type)) {
+                    methodType = DependencyCallback.BIND;
+                } else if ("modified".equalsIgnoreCase(type)) {
+                    methodType = DependencyCallback.MODIFIED;
+                } else {
+                    methodType = DependencyCallback.UNBIND;
+                }
+
+                DependencyCallback callback = new DependencyCallback(dep, method, methodType);
+                dep.addDependencyCallback(callback);
+            }
+
+            // Add the constructor parameter if needed
+            String paramIndex = deps[i].getAttribute("constructor-parameter");
+            if (paramIndex != null) {
+            	int index = Integer.parseInt(paramIndex);
+            	dep.addConstructorInjection(index);
+            }
+
+            // Check the dependency :
+            if (checkDependency(dep, manipulation)) {
+                addDependency(dep);
+                if (dep.getField() != null) {
+                    getInstanceManager().register(manipulation.getField(dep.getField()), dep);
+                    atLeastOneField = true;
+                }
+            }
+        }
+
+        if (atLeastOneField) { // Does register only if we have fields
+            MethodMetadata[] methods = manipulation.getMethods();
+            for (int i = 0; i < methods.length; i++) {
+                for (int j = 0; j < m_dependencies.length; j++) {
+                    getInstanceManager().register(methods[i], m_dependencies[j]);
+                }
+            }
+        }
+
+        m_description = new DependencyHandlerDescription(this, m_dependencies); // Initialize the description.
+    }
+
+	/**
+	 * Gets the requires filter configuration from the given object.
+	 * The given object must come from the instance configuration.
+	 * This method was made to fix FELIX-2688. It supports filter configuration using
+	 * an array:
+	 * <code>{"myFirstDep", "(property1=value1)", "mySecondDep", "(property2=value2)"});</code>
+	 * @param requiresFiltersValue the value contained in the instance
+	 * configuration.
+	 * @return the dictionary. If the object in already a dictionary, just returns it,
+	 * if it's an array, builds the dictionary.
+	 * @throws ConfigurationException the dictionary cannot be built
+	 */
+	private Dictionary getRequiresFilters(Object requiresFiltersValue)
+			throws ConfigurationException {
+		if (requiresFiltersValue != null
+				&& requiresFiltersValue.getClass().isArray()) {
+			String[] filtersArray = (String[]) requiresFiltersValue;
+			if (filtersArray.length % 2 != 0) {
+				throw new ConfigurationException(
+						"A requirement filter is invalid : "
+								+ requiresFiltersValue);
+			}
+			Dictionary requiresFilters = new Hashtable();
+			for (int i = 0; i < filtersArray.length; i += 2) {
+				requiresFilters.put(filtersArray[i], filtersArray[i + 1]);
+			}
+			return requiresFilters;
+		}
+
+		return (Dictionary) requiresFiltersValue;
+	}
+
+    /**
+     * Handler start method.
+     * @see org.apache.felix.ipojo.Handler#start()
+     */
+    public void start() {
+        // Start the dependencies
+        for (int i = 0; i < m_dependencies.length; i++) {
+            Dependency dep = m_dependencies[i];
+
+            dep.start();
+        }
+        // Check the state
+        m_started = true;
+        setValidity(false);
+        checkContext();
+    }
+
+    /**
+     * Handler stop method.
+     * @see org.apache.felix.ipojo.Handler#stop()
+     */
+    public void stop() {
+        m_started = false;
+        for (int i = 0; i < m_dependencies.length; i++) {
+            m_dependencies[i].stop();
+        }
+    }
+
+    /**
+     * Handler createInstance method. This method is override to allow delayed callback invocation.
+     * @param instance : the created object
+     * @see org.apache.felix.ipojo.PrimitiveHandler#onCreation(Object)
+     */
+    public void onCreation(Object instance) {
+        for (int i = 0; i < m_dependencies.length; i++) {
+            m_dependencies[i].onObjectCreation(instance);
+        }
+    }
+
+    /**
+     * Get the dependency handler description.
+     * @return the dependency handler description.
+     * @see org.apache.felix.ipojo.Handler#getDescription()
+     */
+    public HandlerDescription getDescription() {
+        return m_description;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
new file mode 100644
index 0000000..0e6d77d
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/DependencyHandlerDescription.java
@@ -0,0 +1,165 @@
+/* 
+ * 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.handlers.dependency;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.util.DependencyModel;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Dependency Handler Description.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class DependencyHandlerDescription extends HandlerDescription {
+
+    /**
+     * Dependencies managed by the dependency handler.
+     */
+    private DependencyDescription[] m_dependencies = new DependencyDescription[0];
+    
+    // TODO Define the DependencyStateListener Interface (in ipojo utils)
+    
+    // TODO Add the list of listener.
+    
+    // TODO Add register listener method.
+    
+    // TODO Add unregister listener method.
+    
+    // TODO Implement the validate method.
+    
+    // TODO Implement the invalidate method.
+    
+    // TODO Implement the onServiceArrival method.
+    
+    // TODO Implement the onServiceDeparture method.
+    
+    // TODO Implement the onServiceBound method.
+    
+    // TODO Implement the onServiceUnbound method.
+
+    /**
+     * Creates the Dependency Handler description.
+     * @param handler the Dependency Handler.
+     * @param deps the Dependencies
+     */
+    public DependencyHandlerDescription(DependencyHandler handler, Dependency[] deps) {
+        super(handler);
+        m_dependencies = new DependencyDescription[deps.length];
+        for (int i = 0; i < m_dependencies.length; i++) {
+            m_dependencies[i] = new DependencyDescription(deps[i]);
+            //TODO Register callback there on the dependency model.
+        }
+    }
+
+    /**
+     * Get dependencies description.
+     * @return the dependencies list.
+     */
+    public DependencyDescription[] getDependencies() {
+        return m_dependencies;
+    }
+
+    /**
+     * Builds the Dependency Handler description.
+     * @return the handler description.
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element deps = super.getHandlerInfo();
+        for (int i = 0; i < m_dependencies.length; i++) {
+            String state = "resolved";
+            if (m_dependencies[i].getState() == DependencyModel.UNRESOLVED) {
+                state = "unresolved";
+            }
+            if (m_dependencies[i].getState() == DependencyModel.BROKEN) {
+                state = "broken";
+            }
+            Element dep = new Element("Requires", "");
+            dep.addAttribute(new Attribute("Specification", m_dependencies[i].getInterface()));
+            dep.addAttribute(new Attribute("Id", m_dependencies[i].getId()));
+            
+            if (m_dependencies[i].getFilter() != null) {
+                dep.addAttribute(new Attribute("Filter", m_dependencies[i].getFilter()));
+            }
+            
+            if (m_dependencies[i].isOptional()) {
+                dep.addAttribute(new Attribute("Optional", "true"));
+                if (m_dependencies[i].supportsNullable()) {
+                    dep.addAttribute(new Attribute("Nullable", "true"));    
+                }
+                if (m_dependencies[i].getDefaultImplementation() != null) {
+                    dep.addAttribute(new Attribute("Default-Implementation", m_dependencies[i].getDefaultImplementation()));
+                }
+            } else {
+                dep.addAttribute(new Attribute("Optional", "false"));
+            }
+
+            if (m_dependencies[i].isMultiple()) {
+                dep.addAttribute(new Attribute("Aggregate", "true"));
+            } else {
+                dep.addAttribute(new Attribute("Aggregate", "false"));
+            }
+            
+            if (m_dependencies[i].isProxy()) {
+                dep.addAttribute(new Attribute("Proxy", "true"));
+            } else {
+                dep.addAttribute(new Attribute("Proxy", "false"));
+            }
+            
+            String policy = "dynamic";
+            if (m_dependencies[i].getPolicy() == DependencyModel.STATIC_BINDING_POLICY) {
+                policy = "static";
+            } else if (m_dependencies[i].getPolicy() == DependencyModel.DYNAMIC_PRIORITY_BINDING_POLICY) {
+                policy = "dynamic-priority";
+            }
+            dep.addAttribute(new Attribute("Binding-Policy", policy));
+            
+            if (m_dependencies[i].getComparator() != null) {
+                dep.addAttribute(new Attribute("Comparator", m_dependencies[i].getComparator()));
+            }
+            
+            dep.addAttribute(new Attribute("State", state));
+            List set = m_dependencies[i].getUsedServices();
+            if (set != null) {
+                Iterator iterator = set.iterator();
+                while (iterator.hasNext()) {
+                    Element use = new Element("Uses", "");
+                    ServiceReference ref = (ServiceReference) iterator.next();
+                    use.addAttribute(new Attribute("service.id", ref.getProperty(Constants.SERVICE_ID).toString()));                
+                    String instance = (String) ref.getProperty("instance.name");
+                    if (instance != null) {
+                        use.addAttribute(new Attribute("instance.name", instance));
+                    }
+                    dep.addElement(use);
+                }
+            }
+            
+            deps.addElement(dep);
+        }
+        return deps;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
new file mode 100644
index 0000000..b11419f
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/NullableObject.java
@@ -0,0 +1,94 @@
+/* 
+ * 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.handlers.dependency;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+/**
+ * Default nullable object.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class NullableObject implements InvocationHandler {
+
+    /**
+     * Default boolean value.
+     */
+    private static final Boolean DEFAULT_BOOLEAN = Boolean.FALSE;
+
+    /**
+     * Default byte value.
+     */
+    private static final Byte DEFAULT_BYTE = new Byte((byte) 0);
+
+    /**
+     * Default short value.
+     */
+    private static final Short DEFAULT_SHORT = new Short((short) 0);
+
+    /**
+     * Default integer value.
+     */
+    private static final Integer DEFAULT_INT = new Integer(0);
+
+    /**
+     * Default long value.
+     */
+    private static final Long DEFAULT_LONG = new Long(0);
+
+    /**
+     * Default float value.
+     */
+    private static final Float DEFAULT_FLOAT = new Float(0.0f);
+
+    /**
+     * Default double value.
+     */
+    private static final Double DEFAULT_DOUBLE = new Double(0.0);
+
+    /**
+     * Invokes a method on this null object. The method will return a default
+     * value without doing anything.
+     * @param proxy : proxy object
+     * @param method : invoked method
+     * @param args : arguments.
+     * @return the returned value.
+     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+     */
+    public Object invoke(Object proxy, Method method, Object[] args) {
+        Class returnType = method.getReturnType();
+        if (Boolean.TYPE.equals(returnType)) {
+            return DEFAULT_BOOLEAN;
+        } else if (Byte.TYPE.equals(returnType)) {
+            return DEFAULT_BYTE;
+        } else if (Short.TYPE.equals(returnType)) {
+            return DEFAULT_SHORT;
+        } else if (Integer.TYPE.equals(returnType)) {
+            return DEFAULT_INT;
+        } else if (Long.TYPE.equals(returnType)) {
+            return DEFAULT_LONG;
+        } else if (Float.TYPE.equals(returnType)) {
+            return DEFAULT_FLOAT;
+        } else if (Double.TYPE.equals(returnType)) {
+            return DEFAULT_DOUBLE;
+        } else {
+            return null;
+        }
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ProxyGenerator.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ProxyGenerator.java
new file mode 100644
index 0000000..1dd2cf3
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ProxyGenerator.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.handlers.dependency;
+
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
+
+/**
+ * Generates proxy class delegating operation invocations thanks to a
+ * a dependency.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProxyGenerator implements Opcodes {
+
+    /**
+     * The dependency name.
+     */
+    private static final String DEPENDENCY = "m_dependency";
+
+    /**
+     * The dependency descriptor.
+     */
+    private static final String DEPENDENCY_DESC = Type.getDescriptor(Dependency.class);
+
+    /**
+     * Dependency internal class name.
+     */
+    private static final String DEPENDENCY_INTERNAL_NAME = "org/apache/felix/ipojo/handlers/dependency/Dependency";
+
+    /**
+     * Gets the internal names of the given class objects.
+     * @param classes the classes
+     * @return the array containing internal names of the given class array.
+     */
+    private static String[] getInternalClassNames(Class[] classes) {
+        final String[] names = new String[classes.length];
+        for (int i = 0; i < names.length; i++) {
+            names[i] = Type.getInternalName(classes[i]);
+        }
+        return names;
+    }
+
+    /**
+     * Generates a proxy class.
+     * @param spec the proxied service specification
+     * @return the byte[] for the generated proxy class.
+     */
+    public static byte[] dumpProxy(Class spec) {
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        String internalClassName = Type.getInternalName(spec); // Specification class internal name.
+        String[] itfs = new String[0];
+        String parent = "java/lang/Object";
+        if (spec.isInterface()) {
+        	itfs = new String[] {internalClassName};  // Implemented interface.
+        } else {
+        	parent = internalClassName;
+        }
+        String className = internalClassName + "$$Proxy"; // Unique name.
+
+        // Turn around the VM changes (FELIX-2716) about java.* classes.
+        if (className.startsWith("java/")) {
+        	className = "$" + className;
+        }
+
+        Method[] methods = spec.getMethods(); // Method to delegate
+
+        cw.visit(Opcodes.V1_3, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, className, null, parent, itfs);
+        addDependencyField(cw);
+
+        // We try to call super() on the parent, however this should not be used as proxing does work only for interface.
+        generateConstructor(cw, className, parent);
+
+        // For each method, create the delegator code.
+        for (int i = 0; i < methods.length; i++) {
+            if ((methods[i].getModifiers() & (Modifier.STATIC | Modifier.FINAL)) == 0) {
+                generateDelegator(cw, methods[i], className, internalClassName);
+            }
+        }
+
+        cw.visitEnd();
+
+        return cw.toByteArray();
+
+    }
+
+    /**
+     * Generates a delegated method.
+     * @param cw the class writer
+     * @param method the method object to delegate
+     * @param className the generated class name
+     * @param itfName the internal specification class name
+     */
+    private static void generateDelegator(ClassWriter cw, Method method,
+            String className, String itfName) {
+        String methodName = method.getName();
+        String desc = Type.getMethodDescriptor(method);
+        String[] exceptions = getInternalClassNames(method.getExceptionTypes());
+        int modifiers = method.getModifiers()
+                & ~(Modifier.ABSTRACT | Modifier.NATIVE | Modifier.SYNCHRONIZED);
+        Type[] types = Type.getArgumentTypes(method);
+
+        int freeRoom = 1;
+        for (int t = 0; t < types.length; t++) {
+            freeRoom = freeRoom + types[t].getSize();
+        }
+
+        MethodVisitor mv = cw.visitMethod(modifiers, methodName, desc, null,
+                exceptions);
+        mv.visitCode();
+
+        mv.visitVarInsn(ALOAD, 0);
+        mv.visitFieldInsn(GETFIELD, className, DEPENDENCY, DEPENDENCY_DESC);  // The dependency is on the stack.
+        mv.visitMethodInsn(INVOKEVIRTUAL, DEPENDENCY_INTERNAL_NAME, "getService", // Call getService
+                "()Ljava/lang/Object;"); // The service object is on the stack.
+        int varSvc = freeRoom;
+        freeRoom = freeRoom + 1; // Object Reference.
+        mv.visitVarInsn(ASTORE, varSvc); // Store the service object.
+
+        Label notNull = new Label();
+        Label isNull = new Label();
+        mv.visitVarInsn(ALOAD, varSvc); // Load the service
+        mv.visitJumpInsn(IFNONNULL, notNull); // If not null go to not null
+        // Null branch - throw the exception
+        mv.visitLabel(isNull);
+        mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
+        mv.visitInsn(DUP);
+        mv.visitLdcInsn("No service available");
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V");
+        mv.visitInsn(ATHROW);
+        // End of the null branch
+
+        // Not null, go one the execution
+        mv.visitLabel(notNull);
+
+        // Invoke the method on the service object.
+        mv.visitVarInsn(ALOAD, varSvc);
+        // Push argument on the stack.
+        int i = 1; // Arguments. (non static method)
+        for (int t = 0; t < types.length; t++) {
+            mv.visitVarInsn(types[t].getOpcode(ILOAD), i);
+            i = i + types[t].getSize();
+        }
+        // Invocation
+        mv.visitMethodInsn(INVOKEINTERFACE, itfName, methodName, desc);
+
+        // Return the result
+        Type returnType = Type.getReturnType(desc);
+        if (returnType.getSort() != Type.VOID) {
+            mv.visitInsn(returnType.getOpcode(IRETURN));
+        } else {
+            mv.visitInsn(RETURN);
+        }
+
+        // End of the method.
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    /**
+     * Generates the constructors. The constructor receives a dependency
+     * and set the {@link ProxyGenerator#DEPENDENCY} field.
+     * @param cw the class writer
+     * @param className the generated class name.
+     */
+    private static void generateConstructor(ClassWriter cw, String className, String parent) {
+        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", '(' + DEPENDENCY_DESC + ")V", null, null);
+        mv.visitCode();
+
+        mv.visitVarInsn(ALOAD, 0); // Load this
+        mv.visitInsn(DUP); // Dup
+        mv.visitMethodInsn(INVOKESPECIAL, parent, "<init>", "()V"); // Call  super
+        mv.visitVarInsn(ALOAD, 1); // Load the argument
+        mv.visitFieldInsn(PUTFIELD, className, DEPENDENCY, DEPENDENCY_DESC); // Assign the dependency field
+        mv.visitInsn(RETURN); // Return void
+
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    /**
+     * Adds the dependency field {@link ProxyGenerator#DEPENDENCY}.
+     * @param cw the class writer
+     */
+    private static void addDependencyField(ClassWriter cw) {
+        cw.visitField(Opcodes.ACC_FINAL, DEPENDENCY, DEPENDENCY_DESC, null, null);
+        cw.visitEnd();
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceCollection.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceCollection.java
new file mode 100644
index 0000000..46451aa
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceCollection.java
@@ -0,0 +1,422 @@
+/* 
+ * 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.handlers.dependency;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+
+/**
+* Maintains a service object collection.
+* This collection wrap the temporal dependency to be accessible from a
+* {@link Collection}, that can be passed to helper objects (Collaborators).
+* 
+* 
+* The {@link Collection#iterator()} method returns an {@link Iterator} iterating
+* on a cached copy of available service objects. In the case that there are no 
+* available services, the policies act as follows:
+* <ul>
+* <li>'null' returns a null iterator</li>
+* <li>'nullable' and default-implementation returns an iterator iterating on one object (the
+*  nullable or default-implementation object</li>
+* <li>'empty' returns an empty iterator.</li>
+* </ul>
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+*/
+public class ServiceCollection implements Collection, List, Set {
+    
+    /**
+     * The wrapped dependency.
+     */
+    private Dependency m_dependency;
+        
+    /**
+     * Creates a Service Collection.
+     * @param dep the wrapped dependency
+     */
+    public ServiceCollection(Dependency dep) {
+        m_dependency = dep;
+    }
+
+    /**
+     * Unsupported method.
+     * @param o an object
+     * @return N/A
+     * @see java.util.Collection#add(java.lang.Object)
+     */
+    public boolean add(Object o) {
+        throw new UnsupportedOperationException("Cannot add elements inside this collection");
+    }
+
+    /**
+     * Unsupported method.
+     * @param c an object
+     * @return N/A
+     * @see java.util.Collection#addAll(java.util.Collection)
+     */
+    public boolean addAll(Collection c) {
+        throw new UnsupportedOperationException("Cannot add elements inside this collection");
+    }
+    
+    /**
+     * Unsupported method.
+     * @param index an index
+     * @param obj an object
+     * @see java.util.List#add(int, java.lang.Object)
+     */
+    public void add(int index, Object obj) {
+        throw new UnsupportedOperationException("Cannot add elements inside this collection");
+    }
+
+    /**
+     * Unsupported method.
+     * @param index an index
+     * @param c an object
+     * @return N/A
+     * @see java.util.List#addAll(int, java.util.Collection)
+     */
+    public boolean addAll(int index, Collection c) {
+        throw new UnsupportedOperationException("Cannot add elements inside this collection");
+    }
+
+    /**
+     * Unsupported method.
+     * @see java.util.Collection#clear()
+     */
+    public void clear() {
+        throw new UnsupportedOperationException("Cannot remove elements from this collection");
+    }
+
+    /**
+     * Checks if the wrapped dependency has always access to the
+     * given service object.The method allows knowing if the provider returning the
+     * service object has left. 
+     * @param o  the service object
+     * @return <code>true</code> if the object is still available,
+     * <code>false</code> otherwise.
+     * @see java.util.Collection#contains(java.lang.Object)
+     */
+    public boolean contains(Object o) {
+        List list = (List) m_dependency.getService();
+        return list.contains(o);
+    }
+
+    /**
+     * Checks if the wrapped dependencies has always access to the
+     * given service objects.The method allows knowing if providers returning the
+     * service objects have left. 
+     * @param c the set of service object
+     * @return <code>true</code> if the objects are still available,
+     * <code>false</code> otherwise.
+     * @see java.util.Collection#contains(java.lang.Object)
+     */
+    public boolean containsAll(Collection c) {
+        List list = (List) m_dependency.getService();
+        return list.containsAll(c);
+    }
+
+    /**
+     * Checks if at least one provider matching with the dependency
+     * is available.
+     * @return <code>true</code> if one provider or more satisfying the
+     * dependency are available. Otherwise, returns <code>false</code> 
+     * @see java.util.Collection#isEmpty()
+     */
+    public boolean isEmpty() {
+        return m_dependency.getSize() == 0;
+    }
+
+    /**
+     * Gets an iterator on the current list of available service objects.
+     * The returned iterator iterates on a cached copy of the service
+     * objects.
+     * @return a iterator giving access to service objects.
+     * @see java.util.Collection#iterator()
+     */
+    public Iterator iterator() {
+        List obj = (List) m_dependency.getService();
+        return new ServiceIterator(obj); // Create the service iterator with the service reference list.
+    }
+    
+    /**
+     * Unsupported method.
+     * @param o a object
+     * @return N/A
+     * @see java.util.Collection#remove(java.lang.Object)
+     */
+    public boolean remove(Object o) {
+        throw new UnsupportedOperationException("Cannot remove elements from this collection");
+    }
+
+    /**
+     * Unsupported method.
+     * @param index the index
+     * @return N/A
+     * @see java.util.Collection#remove(java.lang.Object)
+     */
+    public Object remove(int index) {
+        throw new UnsupportedOperationException("Cannot remove elements from this collection");
+    }
+
+    /**
+     * Unsupported method.
+     * @param c a set of objects
+     * @return N/A
+     * @see java.util.Collection#removeAll(java.util.Collection)
+     */
+    public boolean removeAll(Collection c) {
+        throw new UnsupportedOperationException("Cannot remove elements from this collection");
+    }
+
+    /**
+     * Unsupported method.
+     * @param c a set of objects
+     * @return N/A
+     * @see java.util.Collection#retainAll(java.util.Collection)
+     */
+    public boolean retainAll(Collection c) {
+        throw new UnsupportedOperationException("Cannot remove elements from this collection");
+    }
+
+    /**
+     * Gets the number of available providers.
+     * @return the number of matching service providers.
+     * @see java.util.Collection#size()
+     */
+    public int size() {
+        return m_dependency.getSize();
+    }
+
+    /**
+     * Returns an array containing available service objects.
+     * This method executed on timeout policies if no matching
+     * providers when the timeout is reached. 
+     * @return a array containing available service objects.
+     * @see java.util.Collection#toArray()
+     */
+    public Object[] toArray() {
+        return toArray(new Object[0]);
+    }
+    
+    /**
+     * Returns an array containing available service objects.
+     * This method executed on timeout policies if no matching
+     * providers when the timeout is reached. 
+     * @param a the array into which the elements of this collection 
+     * are to be stored, if it is big enough; otherwise, a new array
+     * of the same runtime type is allocated for this purpose. 
+     * @return a array containing available service objects.
+     * @see java.util.Collection#toArray(java.lang.Object[])
+     */
+    public Object[] toArray(Object[] a) {
+        List list = (List) m_dependency.getService();
+        return list.toArray(a);
+    }
+    
+    /**
+     * Gets the object stored at the given index.
+     * @param index the index
+     * @return the service object
+     * @see java.util.List#get(int)
+     */
+    public Object get(int index) {
+        List list = (List) m_dependency.getService();
+        return list.get(index);
+    }
+
+    /**
+     * Gets the index of the given object in the current
+     * collection.
+     * @param o the object 
+     * @return the index of the object of <code>-1</code>
+     * if not found.
+     * @see java.util.List#indexOf(java.lang.Object)
+     */
+    public int indexOf(Object o) {
+        List list = (List) m_dependency.getService();
+        return list.indexOf(o);
+    }
+
+    /**
+     * Gets the last index of the given object in the current
+     * collection.
+     * @param o the object 
+     * @return the index of the object of <code>-1</code>
+     * if not found.
+     * @see java.util.List#lastIndexOf(java.lang.Object)
+     */
+    public int lastIndexOf(Object o) {
+        List list = (List) m_dependency.getService();
+        return list.lastIndexOf(o);
+    }
+
+    /**
+     * Gets a list iterator on the current list of available service objects.
+     * The returned iterator iterates on a cached copy of the service
+     * objects.
+     * @return a iterator giving access to service objects.
+     * @see java.util.List#listIterator()
+     */
+    public ListIterator listIterator() {
+        List obj = (List) m_dependency.getService();
+        return new ServiceIterator(obj); // Create the service iterator with the service reference list.
+    }
+
+    /**
+     * Unsupported Method.
+     * @param index an index
+     * @return N/A
+     * @see java.util.List#listIterator(int)
+     */
+    public ListIterator listIterator(int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Unsupported Method.
+     * @param arg0 an index
+     * @param arg1 an object
+     * @return N/A
+     * @see java.util.List#set(int, E)
+     */
+    public Object set(int arg0, Object arg1) {
+        throw new UnsupportedOperationException("Cannot add elements inside this collection");
+    }
+
+    /**
+     * Returns a sublist from the current list.
+     * @param fromIndex the index of the list beginning
+     * @param toIndex the index of the list end
+     * @return the sub-list
+     * @see java.util.List#subList(int, int)
+     */
+    public List subList(int fromIndex, int toIndex) {
+        List list = (List) m_dependency.getService();
+        return list.subList(fromIndex, toIndex);
+    }
+
+    /**
+     * Iterator on a set of service objects.
+     * This iterator iterates on a cached copy of service objects.
+     */
+    private final class ServiceIterator implements ListIterator {
+        
+        /**
+         * Underlying iterator.
+         */
+        private ListIterator m_iterator;
+        
+        /**
+         * Creates a Service Iterator iterating
+         * on the given set of providers.
+         * @param list the list of service object.
+         */
+        private ServiceIterator(List list) {           
+            m_iterator = list.listIterator();
+        }
+
+        /**
+         * Returns <code>true</code> if the iteration has 
+         * more service objects. 
+         * @return <code>true</code> if the iterator has more elements.
+         * @see java.util.Iterator#hasNext()
+         */
+        public boolean hasNext() {
+            return m_iterator.hasNext();
+        }
+
+        /**
+         * Returns the next service objects in the iteration. 
+         * @return the next service object in the iteration. 
+         * @see java.util.Iterator#next()
+         */
+        public Object next() {
+            return m_iterator.next();
+        }
+
+        /**
+         * Unsupported operation.
+         * @see java.util.Iterator#remove()
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();            
+        }
+
+        /**
+         * Unsupported operation.
+         * @param obj an object
+         * @see java.util.ListIterator#add(E)
+         */
+        public void add(Object obj) {
+            throw new UnsupportedOperationException();                        
+        }
+
+        /**
+         * Checks if the is an element before the currently 
+         * pointed one.
+         * @return true if there is an element before the
+         * current one.
+         * @see java.util.ListIterator#hasPrevious()
+         */
+        public boolean hasPrevious() {
+            return m_iterator.hasPrevious();
+        }
+
+        /**
+         * Gets the index of the next element.
+         * @return the index of the next element.
+         * @see java.util.ListIterator#nextIndex()
+         */
+        public int nextIndex() {
+            return m_iterator.nextIndex();
+        }
+
+        
+        /**
+         * Gets the previous elements.
+         * @return the previous element
+         * @see java.util.ListIterator#previous()
+         */
+        public Object previous() {
+            return m_iterator.previous();
+        }
+
+        /**
+         * Gets the index of the previous element.
+         * @return the index of the previous element.
+         * @see java.util.ListIterator#previousIndex()
+         */
+        public int previousIndex() {
+            return m_iterator.previousIndex();
+        }
+
+        /**
+         * Unsupported operation.
+         * @param obj an object
+         * @see java.util.ListIterator#set(E)
+         */
+        public void set(Object obj) {
+            throw new UnsupportedOperationException();  
+        }
+                  
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
new file mode 100644
index 0000000..3757e77
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/dependency/ServiceUsage.java
@@ -0,0 +1,100 @@
+/* 
+ * 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.handlers.dependency;
+
+
+/**
+ * Object managing thread local copy of required services.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceUsage extends ThreadLocal {
+    
+    /**
+     * Structure contained in the Thread Local.
+     */
+    public static class Usage {
+        
+        /**
+         * Stack Size.
+         */
+        int m_stack = 0;
+        /**
+         * Object to inject.
+         */
+        Object m_object;
+        
+        /**
+         * Tracks the number of component method called
+         * in the current thread.
+         */
+        int m_componentStack = 0;
+        
+        /**
+         * Increment the stack level from the first
+         * service get.
+         */
+        public void inc() {
+            m_stack++;
+        }
+        
+        /**
+         * Increment the component stack level.
+         */
+        public void incComponentStack() {
+            m_componentStack++;
+        }
+        
+        /**
+         * Decrement the stack level.
+         * @return  true if the stack is 0 after the decrement.
+         */
+        public boolean dec() {
+            m_stack--;
+            return m_stack == 0;
+        }
+        
+        /**
+         * Decrement the component stack level.
+         * @return  true if the stack is 0 after the decrement.
+         */
+        public boolean decComponentStack() {
+            m_componentStack--;
+            return m_componentStack == 0;
+        }
+        
+        /**
+         * Clear the service object array.
+         */
+        public void clear() {
+            m_object = null;
+        }
+        
+    }
+    
+    /**
+     * Initialize the cached object.
+     * @return an empty Usage object.
+     * @see java.lang.ThreadLocal#initialValue()
+     */
+    public Object initialValue() {
+        return new Usage();
+    }   
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
new file mode 100644
index 0000000..cd86798
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallback.java
@@ -0,0 +1,101 @@
+/* 
+ * 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.handlers.lifecycle.callback;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.felix.ipojo.parser.MethodMetadata;
+import org.apache.felix.ipojo.util.Callback;
+
+/**
+ * This class is the implementation of callback on lifecycle transition.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class LifecycleCallback {
+    
+    /**
+     * Invalid to Valid transition.
+     */
+    protected static final int VALIDATE = 1;
+    
+    /**
+     * Valid to Invalid transition.
+     */
+    protected static final int INVALIDATE = 0;
+    
+    /**
+     * Transition on which calling the callback.
+     */
+    private int m_transition;
+
+    /**
+     * Callback object.
+     */
+    private Callback m_callback;
+
+    /**
+     * LifecycleCallback constructor.
+     * 
+     * @param handler : the callback handler calling the callback
+     * @param transition : transition on which calling the callback
+     * @param method : method metadata to invoke
+     */
+    public LifecycleCallback(LifecycleCallbackHandler handler, int transition, MethodMetadata method) {
+        m_transition = transition;
+        m_callback = new Callback(method, handler.getInstanceManager());
+    }
+    
+    /**
+     * LifecycleCallback constructor.
+     * 
+     * @param handler : the callback handler calling the callback
+     * @param transition : transition on which calling the callback
+     * @param method : method name to invoke
+     */
+    public LifecycleCallback(LifecycleCallbackHandler handler, int transition, String method) {
+        m_transition = transition;
+        m_callback = new Callback(method, new String[0], false, handler.getInstanceManager());
+    }
+
+    /**
+     * Call the callback method when the transition from inital tostate is
+     * detected.
+     * 
+     * @throws NoSuchMethodException : Method is not found in the class
+     * @throws InvocationTargetException : The method is not static
+     * @throws IllegalAccessException : The method can not be invoked
+     */
+    protected void call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        m_callback.call();
+    }
+    
+    protected int getTransition() {
+        return m_transition;
+    }
+    
+    /**
+     * Get the method name of the callback.
+     * @return the method name
+     */
+    protected String getMethod() {
+        return m_callback.getMethod();
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
new file mode 100644
index 0000000..16f8e09
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/callback/LifecycleCallbackHandler.java
@@ -0,0 +1,178 @@
+/* 
+ * 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.handlers.lifecycle.callback;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.PrimitiveHandler;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.MethodMetadata;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+
+/**
+ * Lifecycle callback handler.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class LifecycleCallbackHandler extends PrimitiveHandler {
+
+    /**
+     * The list of the callback of the component.
+     */
+    private LifecycleCallback[] m_callbacks = new LifecycleCallback[0];
+
+    /**
+     * State of the instance manager (unresolved at the beginning).
+     */
+    private int m_state = InstanceManager.INVALID;
+    /**
+     * Does a POJO object be created at starting.
+     */
+    private boolean m_immediate = false;
+
+    /**
+     * Add the given callback to the callback list.
+     * 
+     * @param callback : the element to add
+     */
+    private void addCallback(LifecycleCallback callback) {
+        for (int i = 0; (m_callbacks != null) && (i < m_callbacks.length); i++) {
+            if (m_callbacks[i] == callback) {
+                return;
+            }
+        }
+
+        if (m_callbacks != null && m_callbacks.length > 0) { //TODO check here if we can improve the test
+            LifecycleCallback[] newHk = new LifecycleCallback[m_callbacks.length + 1];
+            System.arraycopy(m_callbacks, 0, newHk, 0, m_callbacks.length);
+            newHk[m_callbacks.length] = callback;
+            m_callbacks = newHk;
+        } else {
+            m_callbacks = new LifecycleCallback[] { callback };
+        }
+    }
+
+    /**
+     * Configure the handler.
+     * @param metadata : the component type metadata
+     * @param configuration : the instance configuration
+     * @throws ConfigurationException : one callback metadata is not correct (either the transition or the method are not correct).
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+        m_callbacks = new LifecycleCallback[0];
+
+        String imm = metadata.getAttribute("immediate");
+        m_immediate = imm != null && imm.equalsIgnoreCase("true");
+        
+        PojoMetadata meta = getFactory().getPojoMetadata();
+
+        Element[] hooksMetadata = metadata.getElements("callback");
+        for (int i = 0; hooksMetadata != null && i < hooksMetadata.length; i++) {
+            String method = hooksMetadata[i].getAttribute("method");
+            if (method == null) {
+                throw new ConfigurationException("Lifecycle callback : A callback needs to contain a method attribute");
+            }
+            
+            MethodMetadata met = meta.getMethod(method, new String[0]);
+            
+            int transition = -1;
+            String trans = hooksMetadata[i].getAttribute("transition");
+            if (trans == null) {
+                throw new ConfigurationException("Lifecycle callback : the transition attribute is missing");
+            } else {
+                if (trans.equalsIgnoreCase("validate")) {
+                    transition = LifecycleCallback.VALIDATE;
+                } else if (trans.equalsIgnoreCase("invalidate")) {
+                    transition = LifecycleCallback.INVALIDATE; 
+                } else {
+                    throw new ConfigurationException("Lifecycle callback : Unknown or malformed transition : " + trans);
+                }
+            }
+            
+            LifecycleCallback callback = null;
+            if (met == null) {
+                callback = new LifecycleCallback(this, transition, method);
+            } else {
+                callback = new LifecycleCallback(this, transition, met);
+            }
+            addCallback(callback);
+        }
+    }
+
+    /**
+     * Start the handler. 
+     * @see org.apache.felix.ipojo.Handler#start()
+     */
+    public void start() {
+     // Do nothing during the start
+    } 
+
+    /**
+     * Stop the handler.
+     * @see org.apache.felix.ipojo.Handler#stop()
+     */
+    public void stop() {
+        m_state = InstanceManager.INVALID;
+    }
+
+    /**
+     * When the state change call the associated callback.
+     * 
+     * @param state : the new instance state.
+     * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+     */
+    public void stateChanged(int state) {
+        int transition = -1;
+        if (m_state == ComponentInstance.INVALID && state == ComponentInstance.VALID) {
+            transition = LifecycleCallback.VALIDATE;
+        }
+        if (m_state == ComponentInstance.VALID && state == ComponentInstance.INVALID) {
+            transition = LifecycleCallback.INVALIDATE;
+        }
+        
+        // Manage immediate component
+        if (m_immediate && transition == LifecycleCallback.VALIDATE && getInstanceManager().getPojoObjects() == null) {
+            getInstanceManager().getPojoObject();
+        }
+
+        for (int i = 0; i < m_callbacks.length; i++) {
+            if (m_callbacks[i].getTransition() == transition) {
+                try {
+                    m_callbacks[i].call();
+                } catch (NoSuchMethodException e) {
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not found");
+                    throw new IllegalStateException(e.getMessage());
+                } catch (IllegalAccessException e) {
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " is not accessible");
+                    throw new IllegalStateException(e.getMessage());
+                } catch (InvocationTargetException e) {
+                    error("[" + getInstanceManager().getInstanceName() + "] The callback method " + m_callbacks[i].getMethod() + " has thrown an exception : " + e.getTargetException().getMessage(), e.getTargetException());
+                    throw new IllegalStateException(e.getTargetException().getMessage());
+                }
+            }
+        }
+        // Update to internal state
+        m_state = state;
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
new file mode 100644
index 0000000..08bdbe2
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/lifecycle/controller/ControllerHandler.java
@@ -0,0 +1,162 @@
+/*
+ * 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.handlers.lifecycle.controller;
+
+import java.util.Dictionary;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.PrimitiveHandler;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.FieldMetadata;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+
+/**
+ * Lifecycle Controller handler.
+ * This handler allow a POJO  to vote for the instance state. By setting a boolean field to true or false, the handler state changed.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ControllerHandler extends PrimitiveHandler {
+
+    /**
+     * Actual handler (i.e. field value) state
+     */
+    private boolean m_state;
+	/**
+	 * The controller field name.
+	 */
+	private String m_field;
+
+    /**
+     * Configure method.
+     * Look for the first 'controller' element.
+     * @param metadata : metadata
+     * @param configuration : configuration
+     * @throws ConfigurationException : the field attribute is missing or does not exist in the class.
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element metadata, Dictionary configuration) throws ConfigurationException {
+        Element[] controller = metadata.getElements("controller");
+        m_field = controller[0].getAttribute("field");
+        getInstanceManager().register(new FieldMetadata(m_field, "boolean"), this);
+    }
+
+    /**
+     * Start method.
+     * This methods initializes the controller value.
+     * @see org.apache.felix.ipojo.Handler#start()
+     */
+    public void start() {
+    	// On start we should ask for the value
+    	Object o = getInstanceManager().getFieldValue(m_field);
+    	if (o == null || ! (o instanceof Boolean)) {
+    		m_state = true;
+    	} else {
+    		m_state = ((Boolean) o).booleanValue();
+    	}
+
+    	if ( ! m_state) {
+    		setValidity(false);
+    	}
+    }
+
+    /**
+     * Stop method.
+     * Nothing to do.
+     * @see org.apache.felix.ipojo.Handler#stop()
+     */
+    public void stop() {
+        // Nothing to do.
+    }
+
+
+
+    /**
+     * GetterCallback.
+     * @param pojo : the pojo object on which the field is accessed
+     * Return the stored value.
+     * @param field : field name.
+     * @param value : value given by the previous handler.
+     * @return : the handler state.
+     */
+    public Object onGet(Object pojo, String field, Object value) {
+        if (m_state) {
+            return Boolean.TRUE;
+        } else {
+            return Boolean.FALSE;
+        }
+    }
+
+    /**
+     * SetterCallback.
+     * @param pojo : the pojo object on which the field is accessed
+     * Store the new field value & invalidate / validate the handler is required.
+     * @param field : field name.
+     * @param value : new value.
+     */
+    public void onSet(Object pojo, String field, Object value) {
+        if (value instanceof Boolean) {
+            boolean newValue = ((Boolean) value).booleanValue();
+            if (newValue != m_state) {
+                m_state = newValue;
+                if (m_state) {
+                    ((InstanceManager) getHandlerManager()).setState(ComponentInstance.VALID);
+                    setValidity(true);
+                } else {
+                    ((InstanceManager) getHandlerManager()).setState(ComponentInstance.INVALID);
+                    setValidity(false);
+                }
+            }
+        } else {
+            error("Boolean expected for the lifecycle controller");
+            getInstanceManager().stop();
+        }
+    }
+
+    /**
+     * Initialize the component factory.
+     * The controller field is checked to avoid configure check.
+     * @param desc : component description
+     * @param metadata : component type metadata
+     * @throws ConfigurationException : occurs if the controller field is not in the POJO class or is not a boolean.
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
+     */
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
+        String field = null;
+        Element[] controller = metadata.getElements("controller");
+        // Use only the first controller
+        field = controller[0].getAttribute("field");
+        if (field == null) {
+            throw new ConfigurationException("Lifecycle controller : the controller element needs to contain a field attribute");
+        }
+
+        PojoMetadata method = getFactory().getPojoMetadata();
+        FieldMetadata fieldMetadata = method.getField(field);
+        if (fieldMetadata == null) {
+            throw new ConfigurationException("Lifecycle controller : The field " + field + " does not exist in the implementation class");
+        }
+
+        if (!fieldMetadata.getFieldType().equalsIgnoreCase("boolean")) {
+            throw new ConfigurationException("Lifecycle controller : The field " + field + " must be a boolean (" + fieldMetadata.getFieldType() + " found)");
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/CreationStrategy.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/CreationStrategy.java
new file mode 100644
index 0000000..d0f1ae8
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/CreationStrategy.java
@@ -0,0 +1,76 @@
+/* 
+ * 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.handlers.providedservice;
+
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.InstanceManager;
+import org.osgi.framework.ServiceFactory;
+
+/**
+ * Creation strategy to creation service object.
+ * This class is extended by all service object
+ * creation policy.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class CreationStrategy implements ServiceFactory {
+    /**
+     * Method called when the service is registered. 
+     * @param instance the instance registering the service.
+     * @param interfaces the exposed service specification interfaces
+     * @param props the published properties. 
+     */
+    public abstract void onPublication(InstanceManager instance, String[] interfaces, Properties props);
+    /**
+     * Method called when the service in unregistered. 
+     */
+    public abstract void onUnpublication();
+    
+    /**
+     * Checks if the given method object is the
+     * {@link IPOJOServiceFactory#getService(ComponentInstance)}
+     * method.
+     * @param method the method to check
+     * @return <code>true</code> if the method is the getService method
+     * <code>false</code> otherwise.
+     */
+    public static boolean isGetServiceMethod(Method method) {
+        Class[] params = method.getParameterTypes();
+        return method.getName().equals("getService") 
+            && params.length == 1 
+            && params[0].getName().equals(ComponentInstance.class.getName());
+    }
+    
+    /**
+     * Checks if the given method object is the
+     * {@link IPOJOServiceFactory#ungetService(ComponentInstance, Object)}
+     * method.
+     * @param method the method to check
+     * @return <code>true</code> if the method is the ungetService method
+     * <code>false</code> otherwise.
+     */
+    public static boolean isUngetServiceMethod(Method method) {
+        Class[] params = method.getParameterTypes();
+        return method.getName().equals("ungetService") 
+            && params.length == 2 
+            && params[0].getName().equals(ComponentInstance.class.getName());
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
new file mode 100644
index 0000000..a539984
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedService.java
@@ -0,0 +1,1005 @@
+/*
+ * 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.handlers.providedservice;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+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.Properties;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.IPOJOServiceFactory;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.util.Callback;
+import org.apache.felix.ipojo.util.Property;
+import org.apache.felix.ipojo.util.SecurityHelper;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.cm.ConfigurationAdmin;
+
+/**
+ * Provided Service represent a provided service by the component.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProvidedService implements ServiceFactory {
+
+    /**
+     * Service State : REGISTRED.
+     */
+    public static final int REGISTERED = 1;
+
+    /**
+     * Service State : UNREGISTRED.
+     */
+    public static final int UNREGISTERED = 0;
+
+    /**
+     * Factory Policy : SINGLETON_FACTORY.
+     */
+    public static final int SINGLETON_STRATEGY = 0;
+
+    /**
+     * Factory policy : SERVICE_FACTORY.
+     */
+    public static final int SERVICE_STRATEGY = 1;
+
+    /**
+     * Factory policy : STATIC_FACTORY.
+     */
+    public static final int STATIC_STRATEGY = 2;
+
+    /**
+     * Factory policy : INSTANCE.
+     * Creates one service object per instance consuming the service.
+     */
+    public static final int INSTANCE_STRATEGY = 3;
+
+    /**
+     * At this time, it is only the java interface full name.
+     */
+    private String[] m_serviceSpecifications = new String[0];
+
+    /**
+     * The service registration. is null when the service is not registered.
+     * m_serviceRegistration : ServiceRegistration
+     */
+    private ServiceRegistration m_serviceRegistration;
+
+    /**
+     * Link to the owner handler. m_handler : Provided Service Handler
+     */
+    private ProvidedServiceHandler m_handler;
+
+    /**
+     * Properties Array.
+     */
+    private Property[] m_properties;
+
+    /**
+     * Service Object creation policy.
+     */
+    private CreationStrategy m_strategy;
+
+    /**
+     * Were the properties updated during the processing.
+     */
+    private volatile boolean m_wasUpdated;
+
+    /**
+     * Service Controller.
+     */
+    private Map /*<Specification, ServiceController>*/ m_controllers = new HashMap/*<Specification, ServiceController>*/();
+
+    /**
+     * Post-Registration callback.
+     */
+    private Callback m_postRegistration;
+
+    /**
+     * Post-Unregistration callback.
+     */
+    private Callback m_postUnregistration;
+
+    /**
+     * The published properties.
+     */
+    private Dictionary m_publishedProperties = new Properties();
+
+    /**
+     * Creates a provided service object.
+     *
+     * @param handler the the provided service handler.
+     * @param specification the specifications provided by this provided service
+     * @param factoryPolicy the service providing policy
+     * @param creationStrategyClass the customized service object creation strategy.
+     * @param conf the instance configuration.
+     */
+    public ProvidedService(ProvidedServiceHandler handler, String[] specification, int factoryPolicy, Class creationStrategyClass, Dictionary conf) {
+        m_handler = handler;
+
+        m_serviceSpecifications = specification;
+
+        // Add instance name, factory name and factory version is set.
+        try {
+            addProperty(new Property("instance.name", null, null, handler.getInstanceManager().getInstanceName(), String.class.getName(), handler.getInstanceManager(), handler));
+            addProperty(new Property("factory.name", null, null, handler.getInstanceManager().getFactory().getFactoryName(), String.class.getName(), handler.getInstanceManager(), handler));
+
+            if (handler.getInstanceManager().getFactory().getVersion() != null) {
+                addProperty(new Property("factory.version", null, null, handler.getInstanceManager().getFactory().getVersion(), String.class.getName(), handler.getInstanceManager(), handler));
+            }
+
+            // Add the service.* if defined
+            if (conf.get(Constants.SERVICE_PID) != null) {
+                addProperty(new Property(Constants.SERVICE_PID, null, null, (String) conf.get(Constants.SERVICE_PID), String.class.getName(), handler.getInstanceManager(), handler));
+            }
+            if (conf.get(Constants.SERVICE_RANKING) != null) {
+                addProperty(new Property(Constants.SERVICE_RANKING, null, null, (String) conf.get(Constants.SERVICE_RANKING), "int", handler.getInstanceManager(), handler));
+            }
+            if (conf.get(Constants.SERVICE_VENDOR) != null) {
+                addProperty(new Property(Constants.SERVICE_VENDOR, null, null, (String) conf.get(Constants.SERVICE_VENDOR), String.class.getName(), handler.getInstanceManager(), handler));
+            }
+            if (conf.get(Constants.SERVICE_DESCRIPTION) != null) {
+                addProperty(new Property(Constants.SERVICE_DESCRIPTION, null, null, (String) conf.get(Constants.SERVICE_DESCRIPTION), String.class.getName(), handler.getInstanceManager(), handler));
+            }
+
+        } catch (ConfigurationException e) {
+            m_handler.error("An exception occurs when adding instance.name and factory.name property : " + e.getMessage());
+        }
+
+        if (creationStrategyClass != null) {
+            try {
+                m_strategy = (CreationStrategy) creationStrategyClass.newInstance();
+            } catch (IllegalAccessException e) {
+                m_handler.error("["
+                        + m_handler.getInstanceManager().getInstanceName()
+                        + "] The customized service object creation policy "
+                        + "(" + creationStrategyClass.getName() + ") is not accessible: "
+                        + e.getMessage(), e);
+                getInstanceManager().stop();
+                return;
+            } catch (InstantiationException e) {
+                m_handler.error("["
+                        + m_handler.getInstanceManager().getInstanceName()
+                        + "] The customized service object creation policy "
+                        + "(" + creationStrategyClass.getName() + ") cannot be instantiated: "
+                        + e.getMessage(), e);
+                getInstanceManager().stop();
+                return;
+            }
+        } else {
+            switch (factoryPolicy) {
+                case SINGLETON_STRATEGY:
+                    m_strategy = new SingletonStrategy();
+                    break;
+                case SERVICE_STRATEGY:
+                case STATIC_STRATEGY:
+                    // In this case, we need to try to create a new pojo object,
+                    // the factory method will handle the creation.
+                    m_strategy = new FactoryStrategy();
+                    break;
+                case INSTANCE_STRATEGY:
+                    m_strategy = new PerInstanceStrategy();
+                    break;
+                // Other policies:
+                // Thread : one service object per asking thread
+                // Consumer : one service object per consumer
+                default:
+                    List specs = Arrays.asList(m_serviceSpecifications);
+                    m_handler.error("["
+                            + m_handler.getInstanceManager().getInstanceName()
+                            + "] Unknown creation policy for " + specs + " : "
+                            + factoryPolicy);
+                    getInstanceManager().stop();
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Add properties to the provided service.
+     * @param props : the properties to attached to the service registration
+     */
+    protected void setProperties(Property[] props) {
+        for (int i = 0; i < props.length; i++) {
+            addProperty(props[i]);
+        }
+    }
+
+    /**
+     * Add the given property to the property list.
+     *
+     * @param prop : the element to add
+     */
+    private synchronized void addProperty(Property prop) {
+        for (int i = 0; (m_properties != null) && (i < m_properties.length); i++) {
+            if (m_properties[i] == prop) {
+                return;
+            }
+        }
+
+        if (m_properties == null) {
+            m_properties = new Property[] { prop };
+        } else {
+            Property[] newProp = new Property[m_properties.length + 1];
+            System.arraycopy(m_properties, 0, newProp, 0, m_properties.length);
+            newProp[m_properties.length] = prop;
+            m_properties = newProp;
+        }
+    }
+
+    /**
+     * Remove a property.
+     *
+     * @param name : the property to remove
+     * @return <code>true</code> if the property was removed,
+     * <code>false</code> otherwise.
+     */
+    private synchronized boolean removeProperty(String name) {
+        int idx = -1;
+        for (int i = 0; i < m_properties.length; i++) {
+            if (m_properties[i].getName().equals(name)) {
+                idx = i;
+                break;
+            }
+        }
+
+        if (idx >= 0) {
+            if ((m_properties.length - 1) == 0) {
+                m_properties = null;
+            } else {
+                Property[] newPropertiesList = new Property[m_properties.length - 1];
+                System.arraycopy(m_properties, 0, newPropertiesList, 0, idx);
+                if (idx < newPropertiesList.length) {
+                    System.arraycopy(m_properties, idx + 1, newPropertiesList, idx, newPropertiesList.length - idx);
+                }
+                m_properties = newPropertiesList;
+
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Get the service reference of the service registration.
+     * @return the service reference of the provided service (null if the
+     * service is not published).
+     */
+    public ServiceReference getServiceReference() {
+        if (m_serviceRegistration == null) {
+            return null;
+        } else {
+            return m_serviceRegistration.getReference();
+        }
+    }
+
+    /**
+     * Returns a service object for the dependency.
+     * @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
+     * @param bundle : the bundle
+     * @param registration : the service registration of the registered service
+     * @return a new service object or a already created service object (in the case of singleton) or <code>null</code>
+     * if the instance is no more valid.
+     */
+    public Object getService(Bundle bundle, ServiceRegistration registration) {
+        if (getInstanceManager().getState() == InstanceManager.VALID) {
+            return m_strategy.getService(bundle, registration);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * The unget method.
+     *
+     * @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle,
+     * org.osgi.framework.ServiceRegistration, java.lang.Object)
+     * @param bundle : bundle
+     * @param registration : service registration
+     * @param service : service object
+     */
+    public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
+        m_strategy.ungetService(bundle, registration, service);
+    }
+
+    /**
+     * Registers the service. The service object must be able to serve this
+     * service.
+     * This method also notifies the creation strategy of the publication.
+     */
+    protected void registerService() {
+        ServiceRegistration reg = null;
+        Properties serviceProperties = null;
+        synchronized (this) {
+            if (m_serviceRegistration != null) {
+                return;
+            } else {
+                if (m_handler.getInstanceManager().getState() == ComponentInstance.VALID
+                        && m_serviceRegistration == null
+                        && isAtLeastAServiceControllerValid()) {
+                    // Build the service properties list
+
+                    BundleContext bc = m_handler.getInstanceManager().getContext();
+                    // Security check
+                    if (SecurityHelper.hasPermissionToRegisterServices(
+                            m_serviceSpecifications, bc)) {
+                        serviceProperties = getServiceProperties();
+                        m_strategy.onPublication(getInstanceManager(),
+                                getServiceSpecificationsToRegister(),
+                                serviceProperties);
+                        m_serviceRegistration = bc.registerService(
+                                getServiceSpecificationsToRegister(), this,
+                                (Dictionary) serviceProperties);
+                        reg = m_serviceRegistration; // Stack confinement
+                    } else {
+                        throw new SecurityException("The bundle "
+                                + bc.getBundle().getBundleId()
+                                + " does not have the"
+                                + " permission to register the services "
+                                + Arrays.asList(m_serviceSpecifications));
+                    }
+                }
+            }
+        }
+
+        // An update may happen during the registration, re-check and apply.
+        // This must be call outside the synchronized block.
+        if (reg != null && m_wasUpdated) {
+            Properties updated = getServiceProperties();
+            reg.setProperties((Dictionary) updated);
+            m_publishedProperties = updated;
+            m_wasUpdated = false;
+        }
+
+        synchronized (this) {
+            // Call the post-registration callback in the same thread holding
+            // the monitor lock.
+            // This allows to be sure that the callback is called once per
+            // registration.
+            // But the callback must take care to not create a deadlock
+            if (m_postRegistration != null) {
+                try {
+                    m_postRegistration
+                            .call(new Object[] { m_serviceRegistration
+                                    .getReference() });
+                } catch (Exception e) {
+                    m_handler.error(
+                            "Cannot invoke the post-registration callback "
+                                    + m_postRegistration.getMethod(), e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Unregisters the service.
+     */
+    protected synchronized void unregisterService() {
+        // Create a copy of the service reference in the case we need
+        // to inject it to the post-unregistration callback.
+        ServiceReference ref = null;
+        if (m_serviceRegistration != null) {
+            ref = m_serviceRegistration.getReference();
+            m_serviceRegistration.unregister();
+            m_serviceRegistration = null;
+        }
+
+        m_strategy.onUnpublication();
+
+        // Call the post-unregistration callback in the same thread holding the monitor lock.
+        // This allows to be sure that the callback is called once per unregistration.
+        // But the callback must take care to not create a deadlock
+        if (m_postUnregistration != null   && ref != null) {
+            try {
+                m_postUnregistration.call(new Object[] { ref });
+            } catch (Exception e) {
+                m_handler.error("Cannot invoke the post-unregistration callback " + m_postUnregistration.getMethod(), e);
+            }
+        }
+
+    }
+
+    /**
+     * Get the current provided service state.
+     * @return The state of the provided service.
+     */
+    public int getState() {
+        if (m_serviceRegistration == null) {
+            return UNREGISTERED;
+        } else {
+            return REGISTERED;
+        }
+    }
+
+    protected InstanceManager getInstanceManager() {
+        return m_handler.getInstanceManager();
+    }
+
+    /**
+     * Return the list of properties attached to this service. This list
+     * contains only property where a value are assigned.
+     *
+     * @return the properties attached to the provided service.
+     */
+    private Properties getServiceProperties() {
+        // Build the service properties list
+        Properties serviceProperties = new Properties();
+        for (int i = 0; i < m_properties.length; i++) {
+            Object value = m_properties[i].getValue();
+            if (value != null && value != Property.NO_VALUE) {
+                serviceProperties.put(m_properties[i].getName(), value);
+            }
+        }
+        return serviceProperties;
+    }
+
+    /**
+     * Get the list of properties attached to the service registration.
+     * @return the properties attached to the provided service.
+     */
+    public Property[] getProperties() {
+        return m_properties;
+    }
+
+    /**
+     * Update the service properties. The new list of properties is sent to
+     * the service registry.
+     */
+    public synchronized void update() {
+        // Update the service registration
+        if (m_serviceRegistration != null) {
+            Properties updated = getServiceProperties();
+            Dictionary oldProps = (Dictionary) ((Properties) m_publishedProperties).clone();
+            Dictionary newProps = (Dictionary) (updated.clone());
+
+            // Remove keys that must not be compared
+            newProps.remove("instance.name");
+            oldProps.remove("instance.name");
+            newProps.remove(Constants.SERVICE_ID);
+            oldProps.remove(Constants.SERVICE_ID);
+            newProps.remove(Constants.SERVICE_PID);
+            oldProps.remove(Constants.SERVICE_PID);
+            newProps.remove("factory.name");
+            oldProps.remove("factory.name");
+            newProps.remove(ConfigurationAdmin.SERVICE_FACTORYPID);
+            oldProps.remove(ConfigurationAdmin.SERVICE_FACTORYPID);
+
+            // Trigger the update only if the properties have changed.
+
+            // First check, are the size equals
+            if (oldProps.size() != newProps.size()) {
+                m_handler.info("Updating Registration : " + oldProps.size() + " / " + newProps.size());
+                m_publishedProperties = updated;
+                m_serviceRegistration.setProperties((Dictionary) updated);
+            } else {
+                // Check changes
+                Enumeration keys = oldProps.keys();
+                while (keys.hasMoreElements()) {
+                    String k = (String) keys.nextElement();
+                    Object val = oldProps.get(k);
+                    if (! val.equals(updated.get(k))) {
+                        m_handler.info("Updating Registration : " + k);
+                        m_publishedProperties = updated;
+                        m_serviceRegistration.setProperties((Dictionary) updated);
+                        return;
+                    }
+                }
+            }
+        } else {
+            // Need to be updated later.
+            m_wasUpdated = true;
+        }
+    }
+
+    /**
+     * Add properties to the list.
+     * @param props : properties to add
+     */
+    protected void addProperties(Dictionary props) {
+        Enumeration keys = props.keys();
+        boolean updated = false;
+        while (keys.hasMoreElements()) {
+            String key = (String) keys.nextElement();
+            Object value = props.get(key);
+
+            boolean alreadyExisting = false;
+            for (int i = 0; i < m_properties.length; i++) {
+                if (key.equals(m_properties[i].getName())) {
+                    alreadyExisting = true;
+                    // Check whether the value changed.
+                    if (m_properties[i].getValue() == null
+                            || ! value.equals(m_properties[i].getValue())) {
+                        m_properties[i].setValue(value);
+                        updated = true;
+                    }
+                }
+            }
+
+            if (! alreadyExisting) {
+                try {
+                    Property prop = new Property(key, null, null, value, getInstanceManager(), m_handler);
+                    addProperty(prop);
+                    updated = true;
+                } catch (ConfigurationException e) {
+                    m_handler.error("The propagated property " + key + " cannot be created correctly : " + e.getMessage());
+                }
+            }
+        }
+
+        if (updated) {
+            m_handler.info("Update triggered by adding properties " + props);
+            update();
+        }
+    }
+
+    /**
+     * Remove properties from the list.
+     * @param props : properties to remove
+     */
+    protected void deleteProperties(Dictionary props) {
+        Enumeration keys = props.keys();
+        boolean mustUpdate = false;
+        while (keys.hasMoreElements()) {
+            String key = (String) keys.nextElement();
+            mustUpdate = mustUpdate || removeProperty(key);
+        }
+
+        if (mustUpdate) {
+            m_handler.info("Update triggered when removing properties : " + props);
+            update();
+        }
+    }
+
+    /**
+     * Get the published service specifications.
+     * @return the list of provided service specifications (i.e. java
+     * interface).
+     */
+    public String[] getServiceSpecifications() {
+        return m_serviceSpecifications;
+    }
+
+    /**
+     * Get the service registration.
+     * @return the service registration of this service.
+     */
+    public ServiceRegistration getServiceRegistration() {
+        return m_serviceRegistration;
+    }
+
+    /**
+     * Sets the service controller on this provided service.
+     * @param field the field attached to this controller
+     * @param value the value the initial value
+     * @param specification the target specification, if <code>null</code>
+     * affect all specifications.
+     */
+    public void setController(String field, boolean value, String specification) {
+        if (specification == null) {
+            m_controllers.put("ALL", new ServiceController(field, value));
+        } else {
+            m_controllers.put(specification, new ServiceController(field, value));
+
+        }
+    }
+
+    public ServiceController getController(String field) {
+        Collection controllers = m_controllers.values();
+        Iterator iterator = controllers.iterator();
+        while (iterator.hasNext()) {
+            ServiceController controller = (ServiceController) iterator.next();
+            if (field.equals(controller.m_field)) {
+                return controller;
+            }
+        }
+        return null;
+    }
+
+    public ServiceController getControllerBySpecification(String spec) {
+        return (ServiceController) m_controllers.get(spec);
+    }
+
+    /**
+     * Checks if at least one service controller is valid.
+     * @return <code>true</code> if one service controller at least
+     * is valid.
+     */
+    private boolean isAtLeastAServiceControllerValid() {
+        Collection controllers = m_controllers.values();
+
+        // No controller
+        if (controllers.isEmpty()) {
+            return true;
+        }
+
+        Iterator iterator = controllers.iterator();
+        while (iterator.hasNext()) {
+            ServiceController controller = (ServiceController) iterator.next();
+            if (controller.getValue()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private String[] getServiceSpecificationsToRegister() {
+        if (m_controllers.isEmpty()) {
+            return m_serviceSpecifications;
+        }
+
+        ArrayList l = new ArrayList();
+        if (m_controllers.containsKey("ALL")) {
+            ServiceController ctrl = (ServiceController) m_controllers.get("ALL");
+            if (ctrl.m_value) {
+                l.addAll(Arrays.asList(m_serviceSpecifications));
+            }
+        }
+
+        Iterator iterator = m_controllers.keySet().iterator();
+        while (iterator.hasNext()) {
+            String spec = (String) iterator.next();
+            ServiceController ctrl = (ServiceController) m_controllers.get(spec);
+            if (ctrl.m_value) {
+                if (! "ALL".equals(spec)) { // Already added.
+                    if (! l.contains(spec)) {
+                        l.add(spec);
+                    }
+                }
+            } else {
+                l.remove(spec);
+            }
+        }
+
+        return (String[]) l.toArray(new String[l.size()]);
+
+    }
+
+    public void setPostRegistrationCallback(Callback cb) {
+        m_postRegistration = cb;
+    }
+
+    public void setPostUnregistrationCallback(Callback cb) {
+        m_postUnregistration = cb;
+    }
+
+    /**
+     * Service Controller.
+     */
+    class ServiceController {
+        /**
+         * The controller value.
+         */
+        private boolean m_value;
+        /**
+         * The field attached to this controller.
+         */
+        private final String m_field;
+
+        /**
+         * Creates a ServiceController.
+         * @param field the field
+         * @param value the initial value
+         */
+        public ServiceController(String field, boolean value) {
+            m_field = field;
+            m_value = value;
+        }
+
+        public String getField() {
+            return m_field;
+        }
+
+        /**
+         * Gets the value.
+         * @return the value
+         */
+        public boolean getValue() {
+            synchronized (ProvidedService.this) {
+                return m_value;
+            }
+        }
+
+        /**
+         * Sets the value.
+         * @param value the value
+         */
+        public void setValue(Boolean value) {
+            synchronized (ProvidedService.this) {
+                if (value.booleanValue() != m_value) {
+                    // If there is a change to the ServiceController value then
+                    // we will
+                    // need to modify the registrations.
+                    m_value = value.booleanValue();
+                    unregisterService();
+                    if (getServiceSpecificationsToRegister().length != 0) {
+                        registerService();
+                    }
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Singleton creation strategy.
+     * This strategy just creates one service object and
+     * returns always the same.
+     */
+    private class SingletonStrategy extends CreationStrategy {
+
+        /**
+         * The service is going to be registered.
+         * @param instance the instance manager
+         * @param interfaces the published interfaces
+         * @param props the properties
+         * @see org.apache.felix.ipojo.handlers.providedservice.CreationStrategy#onPublication(InstanceManager, java.lang.String[], java.util.Properties)
+         */
+        public void onPublication(InstanceManager instance, String[] interfaces,
+                Properties props) { }
+
+        /**
+         * The service was unpublished.
+         * @see org.apache.felix.ipojo.handlers.providedservice.CreationStrategy#onUnpublication()
+         */
+        public void onUnpublication() { }
+
+        /**
+         * A service object is required.
+         * @param arg0 the bundle requiring the service object.
+         * @param arg1 the service registration.
+         * @return the first pojo object.
+         * @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
+         */
+        public Object getService(Bundle arg0, ServiceRegistration arg1) {
+            return m_handler.getInstanceManager().getPojoObject();
+        }
+
+        /**
+         * A service object is released.
+         * @param arg0  the bundle
+         * @param arg1 the service registration
+         * @param arg2 the get service object.
+         * @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
+         */
+        public void ungetService(Bundle arg0, ServiceRegistration arg1,
+                Object arg2) {
+        }
+
+    }
+
+    /**
+     * Service object creation policy following the OSGi Service Factory
+     * policy {@link ServiceFactory}.
+     */
+    private class FactoryStrategy extends CreationStrategy {
+
+        /**
+         * The service is going to be registered.
+         * @param instance the instance manager
+         * @param interfaces the published interfaces
+         * @param props the properties
+         * @see org.apache.felix.ipojo.handlers.providedservice.CreationStrategy#onPublication(InstanceManager, java.lang.String[], java.util.Properties)
+         */
+        public void onPublication(InstanceManager instance, String[] interfaces,
+                Properties props) { }
+
+        /**
+         * The service is unpublished.
+         * @see org.apache.felix.ipojo.handlers.providedservice.CreationStrategy#onUnpublication()
+         */
+        public void onUnpublication() { }
+
+        /**
+         * OSGi Service Factory getService method.
+         * Returns a new service object per asking bundle.
+         * This object is then cached by the framework.
+         * @param arg0 the bundle requiring the service
+         * @param arg1 the service registration
+         * @return the service object for the asking bundle
+         * @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
+         */
+        public Object getService(Bundle arg0, ServiceRegistration arg1) {
+            return m_handler.getInstanceManager().createPojoObject();
+        }
+
+        /**
+         * OSGi Service Factory unget method.
+         * Deletes the created object for the asking bundle.
+         * @param arg0 the asking bundle
+         * @param arg1 the service registration
+         * @param arg2 the created service object returned for this bundle
+         * @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
+         */
+        public void ungetService(Bundle arg0, ServiceRegistration arg1,
+                Object arg2) {
+            m_handler.getInstanceManager().deletePojoObject(arg2);
+        }
+    }
+
+
+    /**
+     * Service object creation policy creating a service object per asking iPOJO component
+     * instance. This creation policy follows the iPOJO Service Factory interaction pattern
+     * and does no support 'direct' invocation.
+     */
+    private class PerInstanceStrategy extends CreationStrategy implements IPOJOServiceFactory, InvocationHandler {
+        /**
+         * Map [ComponentInstance->ServiceObject] storing created service objects.
+         */
+        private Map/*<ComponentInstance, ServiceObject>*/ m_instances = new HashMap();
+
+        /**
+         * A method is invoked on the proxy object.
+         * If the method is the {@link IPOJOServiceFactory#getService(ComponentInstance)}
+         * method, this method creates a service object if not already created for the asking
+         * component instance.
+         * If the method is {@link IPOJOServiceFactory#ungetService(ComponentInstance, Object)}
+         * the service object is unget (i.e. removed from the map and deleted).
+         * In all other cases, a {@link UnsupportedOperationException} is thrown as this policy
+         * requires to use  the {@link IPOJOServiceFactory} interaction pattern.
+         * @param arg0 the proxy object
+         * @param arg1 the called method
+         * @param arg2 the arguments
+         * @return the service object attached to the asking instance for 'get',
+         * <code>null</code> for 'unget',
+         * a {@link UnsupportedOperationException} for all other methods.
+         * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+         */
+        public Object invoke(Object arg0, Method arg1, Object[] arg2) {
+            if (isGetServiceMethod(arg1)) {
+                return getService((ComponentInstance) arg2[0]);
+            }
+
+            if (isUngetServiceMethod(arg1)) {
+                ungetService((ComponentInstance) arg2[0], arg2[1]);
+                return null;
+            }
+
+            // Regular methods from java.lang.Object : equals and hashCode
+            if (arg1.getName().equals("equals")  && arg2 != null  && arg2.length == 1) {
+                return this.equals(arg2[0]);
+            }
+
+            if (arg1.getName().equals("hashCode")) {
+                return this.hashCode();
+            }
+
+            throw new UnsupportedOperationException("This service requires an advanced creation policy. "
+                    + "Before calling the service, call the getService(ComponentInstance) method to get "
+                    + "the service object. - Method called: " + arg1.getName());
+        }
+
+        /**
+         * A service object is required.
+         * This policy returns a service object per asking instance.
+         * @param instance the instance requiring the service object
+         * @return the service object for this instance
+         * @see org.apache.felix.ipojo.IPOJOServiceFactory#getService(org.apache.felix.ipojo.ComponentInstance)
+         */
+        public Object getService(ComponentInstance instance) {
+            Object obj = m_instances.get(instance);
+            if (obj == null) {
+                obj = m_handler.getInstanceManager().createPojoObject();
+                m_instances.put(instance, obj);
+            }
+            return obj;
+        }
+
+        /**
+         * A service object is unget.
+         * The service object is removed from the map and deleted.
+         * @param instance the instance releasing the service
+         * @param svcObject the service object
+         * @see org.apache.felix.ipojo.IPOJOServiceFactory#ungetService(org.apache.felix.ipojo.ComponentInstance, java.lang.Object)
+         */
+        public void ungetService(ComponentInstance instance, Object svcObject) {
+            Object pojo = m_instances.remove(instance);
+            m_handler.getInstanceManager().deletePojoObject(pojo);
+        }
+
+        /**
+         * The service is going to be registered.
+         * @param instance the instance manager
+         * @param interfaces the published interfaces
+         * @param props the properties
+         * @see org.apache.felix.ipojo.handlers.providedservice.CreationStrategy#onPublication(InstanceManager, java.lang.String[], java.util.Properties)
+         */
+        public void onPublication(InstanceManager instance, String[] interfaces,
+                Properties props) { }
+
+        /**
+         * The service is going to be unregistered.
+         * The instance map is cleared. Created object are disposed.
+         * @see org.apache.felix.ipojo.handlers.providedservice.CreationStrategy#onUnpublication()
+         */
+        public void onUnpublication() {
+            Collection col = m_instances.values();
+            Iterator it = col.iterator();
+            while (it.hasNext()) {
+                m_handler.getInstanceManager().deletePojoObject(it.next());
+            }
+            m_instances.clear();
+        }
+
+        /**
+         * OSGi Service Factory getService method.
+         * @param arg0 the asking bundle
+         * @param arg1 the service registration
+         * @return a proxy implementing the {@link IPOJOServiceFactory}
+         * @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
+         */
+        public Object getService(Bundle arg0, ServiceRegistration arg1) {
+            Object proxy = Proxy.newProxyInstance(getInstanceManager().getClazz().getClassLoader(),
+                    getSpecificationsWithIPOJOServiceFactory(m_serviceSpecifications, m_handler.getInstanceManager().getContext()), this);
+            return proxy;
+        }
+
+        /**
+         * OSGi Service factory unget method.
+         * Does nothing.
+         * @param arg0 the asking bundle
+         * @param arg1 the service registration
+         * @param arg2 the service object created for this bundle.
+         * @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
+         */
+        public void ungetService(Bundle arg0, ServiceRegistration arg1,
+                Object arg2) { }
+
+        /**
+         * Utility method returning the class array of provided service
+         * specification and the {@link IPOJOServiceFactory} interface.
+         * @param specs the published service interface
+         * @param bc the bundle context, used to load classes
+         * @return the class array containing provided service specification and
+         * the {@link IPOJOServiceFactory} class.
+         */
+        private Class[] getSpecificationsWithIPOJOServiceFactory(String[] specs, BundleContext bc) {
+            Class[] classes = new Class[specs.length + 1];
+            int i = 0;
+            for (i = 0; i < specs.length; i++) {
+                try {
+                    classes[i] = bc.getBundle().loadClass(specs[i]);
+                } catch (ClassNotFoundException e) {
+                    // Should not happen.
+                }
+            }
+            classes[i] = IPOJOServiceFactory.class;
+            return classes;
+        }
+
+
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java
new file mode 100644
index 0000000..2973b41
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceDescription.java
@@ -0,0 +1,159 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.handlers.providedservice;
+
+import java.util.Dictionary;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.util.Property;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Provided Service Description.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProvidedServiceDescription {
+
+    /**
+     * State : the service is unregistered.
+     */
+    public static final int UNREGISTERED = ProvidedService.UNREGISTERED;
+
+    /**
+     * State : the service is registered.
+     */
+    public static final int REGISTERED = ProvidedService.REGISTERED;
+    
+    /**
+     * The describe provided service.
+     */
+    private ProvidedService m_ps;
+
+    /**
+     * Constructor.
+     * @param ps the described provided service.
+     */
+    public ProvidedServiceDescription(ProvidedService ps) {
+        m_ps = ps;
+    }
+
+    /**
+     * Gets the list of provided service specifications.
+     * @return the provided contract name.
+     */
+    public String[] getServiceSpecifications() {
+        return m_ps.getServiceSpecifications();
+    }
+
+    /**
+     * Gets the list of properties.
+     * A copy of the actual property set is returned.
+     * @return the properties.
+     */
+    public Properties getProperties() {
+        Properties props = new Properties();
+        org.apache.felix.ipojo.util.Property[] ps = m_ps.getProperties();
+        for (int i = 0; i < ps.length; i++) {
+            if (ps[i].getValue() != Property.NO_VALUE) {
+                props.put(ps[i].getName(), ps[i].getValue());
+            }
+        }
+        return props;
+    }
+    
+    /**
+     * Adds and Updates service properties.
+     * Existing properties are updated. 
+     * New ones are added.
+     * @param props the new properties
+     */
+    public void addProperties(Dictionary props) {
+        m_ps.addProperties(props);
+    }
+    
+    /**
+     * Removes service properties.
+     * @param props the properties to remove
+     */
+    public void removeProperties(Dictionary props) {
+        m_ps.deleteProperties(props);
+    }
+
+    /**
+     * Gets provided service state.
+     * @return the state of the provided service (UNREGISTERED | REGISTRED).
+     */
+    public int getState() {
+        return m_ps.getState();
+    }
+    
+    /**
+     * Gets the controller value as a String.
+     * @return the value
+     */
+    public String getController() {
+        if (m_ps.getControllerBySpecification("ALL") == null) {
+            return null; 
+        } else {
+            return String.valueOf(m_ps.getControllerBySpecification("ALL").getValue());
+        }
+    }
+    
+    /**
+     * Gets the controller value as a String.
+     * @param specification
+     * @return the value
+     */
+    public String getController(String specification) {
+        if (m_ps.getControllerBySpecification(specification) == null) {
+            return null; 
+        } else {
+            return String.valueOf(m_ps.getControllerBySpecification(specification).getValue());
+        }
+    }
+
+    /**
+     * Gets the service reference.
+     * @return the service reference (null if the service is unregistered).
+     */
+    public ServiceReference getServiceReference() {
+        return m_ps.getServiceReference();
+    }
+    
+    /**
+     * Gets the 'main' service object.
+     * @return the 'main' service object or <code>null</code>
+     * if no service object are created.
+     */
+    public Object getService() {
+        Object[] objs = m_ps.getInstanceManager().getPojoObjects();
+        if (objs == null) { 
+            return null;
+        } else {
+            return objs[0];
+        }
+    }
+    
+    public Object[] getServices() {
+        return m_ps.getInstanceManager().getPojoObjects();
+    }
+    
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
new file mode 100644
index 0000000..170275a
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandler.java
@@ -0,0 +1,684 @@
+/*
+ * 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.handlers.providedservice;
+
+import java.lang.reflect.Field;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.Pojo;
+import org.apache.felix.ipojo.PrimitiveHandler;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.architecture.PropertyDescription;
+import org.apache.felix.ipojo.handlers.dependency.Dependency;
+import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
+import org.apache.felix.ipojo.handlers.providedservice.ProvidedService.ServiceController;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.FieldMetadata;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+import org.apache.felix.ipojo.parser.ParseUtils;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.util.Callback;
+import org.apache.felix.ipojo.util.Logger;
+import org.apache.felix.ipojo.util.Property;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Composite Provided Service Handler.
+ * This handler manage the service providing for a composition.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProvidedServiceHandler extends PrimitiveHandler {
+
+    /**
+     * The list of the provided service.
+     */
+    private ProvidedService[] m_providedServices = new ProvidedService[0];
+
+    /**
+     * The handler description.
+     */
+    private ProvidedServiceHandlerDescription m_description;
+
+    /**
+     * Add a provided service to the list .
+     *
+     * @param svc : the provided service to add
+     */
+    private void addProvidedService(ProvidedService svc) {
+        // Verify that the provided service is not already in the array.
+        for (int i = 0; i < m_providedServices.length; i++) {
+            if (m_providedServices[i] == svc) { return; }
+        }
+
+        if (m_providedServices.length > 0) {
+            ProvidedService[] newPS = new ProvidedService[m_providedServices.length + 1];
+            System.arraycopy(m_providedServices, 0, newPS, 0, m_providedServices.length);
+            newPS[m_providedServices.length] = svc;
+            m_providedServices = newPS;
+        } else {
+            m_providedServices = new ProvidedService[] { svc };
+        }
+    }
+
+    /**
+     * Get the array of provided service.
+     * @return the list of the provided service.
+     */
+    public ProvidedService[] getProvidedServices() {
+        return m_providedServices;
+    }
+
+    /**
+     * Configure the handler.
+     * @param componentMetadata : the component type metadata
+     * @param configuration : the instance configuration
+     * @throws ConfigurationException : the metadata are not correct.
+     * @see org.apache.felix.ipojo.Handler#configure(org.apache.felix.ipojo.InstanceManager, org.apache.felix.ipojo.metadata.Element, java.util.Dictionary)
+     */
+    public void configure(Element componentMetadata, Dictionary configuration) throws ConfigurationException {
+        m_providedServices = new ProvidedService[0];
+        // Create the dependency according to the component metadata
+        Element[] providedServices = componentMetadata.getElements("Provides");
+        for (int i = 0; i < providedServices.length; i++) {
+            String[] serviceSpecifications = ParseUtils.parseArrays(providedServices[i].getAttribute("specifications")); // Set by the initialize component factory.
+
+            // Get the factory policy
+            int factory = ProvidedService.SINGLETON_STRATEGY;
+            Class custom = null;
+            String strategy = providedServices[i].getAttribute("strategy");
+            if (strategy == null) {
+                strategy = providedServices[i].getAttribute("factory");
+            }
+            if (strategy != null) {
+                if ("singleton".equalsIgnoreCase(strategy)) {
+                    factory = ProvidedService.SINGLETON_STRATEGY;
+                } else if ("service".equalsIgnoreCase(strategy)) {
+                    factory = ProvidedService.SERVICE_STRATEGY;
+                } else if ("method".equalsIgnoreCase(strategy)) {
+                    factory = ProvidedService.STATIC_STRATEGY;
+                } else if ("instance".equalsIgnoreCase(strategy)) {
+                    factory = ProvidedService.INSTANCE_STRATEGY;
+                } else {
+                    // Customized policy
+                    try {
+                        custom = getInstanceManager().getContext().getBundle().loadClass(strategy);
+                        if (! CreationStrategy.class.isAssignableFrom(custom)) {
+                            throw new ConfigurationException("The custom creation policy class " + custom.getName() + " does not implement " + CreationStrategy.class.getName());
+                        }
+                    } catch (ClassNotFoundException e) {
+                        throw new ConfigurationException("The custom creation policy class " + strategy + " cannot be loaded " + e.getMessage());
+
+                    }
+
+                }
+            }
+
+
+            // Then create the provided service
+            ProvidedService svc = new ProvidedService(this, serviceSpecifications, factory, custom, configuration);
+
+            // Post-Registration callback
+            String post = providedServices[i].getAttribute("post-registration");
+            if (post != null) {
+                Callback cb = new Callback(post, new Class[] {ServiceReference.class}, false, getInstanceManager());
+                svc.setPostRegistrationCallback(cb);
+            }
+
+            post = providedServices[i].getAttribute("post-unregistration");
+            if (post != null) {
+                // TODO Can we really send the service reference here ?
+                Callback cb = new Callback(post, new Class[] {ServiceReference.class}, false, getInstanceManager());
+                svc.setPostUnregistrationCallback(cb);
+            }
+
+            Element[] props = providedServices[i].getElements("Property");
+            if (props != null) {
+                //Property[] properties = new Property[props.length];
+                Property[] properties = new Property[props.length];
+                for (int j = 0; j < props.length; j++) {
+                    String name = props[j].getAttribute("name");
+                    String value = props[j].getAttribute("value");
+                    String type = props[j].getAttribute("type");
+                    String field = props[j].getAttribute("field");
+
+                    Property prop = new Property(name, field, null, value, type, getInstanceManager(), this);
+                    properties[j] = prop;
+
+                    // Check if the instance configuration has a value for this property
+                    Object object = configuration.get(prop.getName());
+                    if (object != null) {
+                        prop.setValue(object);
+                    }
+
+                    if (field != null) {
+                        getInstanceManager().register(new FieldMetadata(field, type), this);
+                        // Cannot register the property as the interception is necessary
+                        // to deal with registration update.
+                    }
+                }
+
+                // Attach to properties to the provided service
+                svc.setProperties(properties);
+            }
+
+            Element[] controllers = providedServices[i].getElements("Controller");
+            if (controllers != null) {
+                for (int k = 0; k < controllers.length; k++) {
+                    String field = controllers[k].getAttribute("field");
+                    if (field == null) {
+                        throw new ConfigurationException("The field attribute of a controller is mandatory");
+                    }
+
+                    String v = controllers[k].getAttribute("value");
+                    boolean value = ! (v != null  && v.equalsIgnoreCase("false"));
+                    String s = controllers[k].getAttribute("specification");
+                    if (s == null) {
+                        s ="ALL";
+                    }
+                    svc.setController(field, value, s);
+
+                    getInstanceManager().register(new FieldMetadata(field, "boolean"), this);
+                }
+            }
+
+            if (checkProvidedService(svc)) {
+                addProvidedService(svc);
+            } else {
+                StringBuffer itfs = new StringBuffer();
+                for (int j = 0; j < serviceSpecifications.length; j++) {
+                    itfs.append(' ');
+                    itfs.append(serviceSpecifications[j]);
+                }
+                throw new ConfigurationException("The provided service" + itfs + " is not valid");
+            }
+
+            // Initialize the description.
+            m_description = new ProvidedServiceHandlerDescription(this, m_providedServices);
+
+        }
+    }
+
+    /**
+     * Collect interfaces implemented by the POJO.
+     * @param specs : implemented interfaces.
+     * @param parent : parent class.
+     * @param bundle : Bundle object.
+     * @param interfaces : the set of implemented interfaces
+     * @param classes : the set of extended classes
+     * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
+     */
+    private void computeInterfacesAndSuperClasses(String[] specs, String parent, Bundle bundle, Set interfaces, Set classes) throws ClassNotFoundException {
+        // First iterate on found specification in manipulation metadata
+        for (int i = 0; i < specs.length; i++) {
+            interfaces.add(specs[i]);
+            // Iterate on interfaces implemented by the current interface
+            Class clazz = bundle.loadClass(specs[i]);
+            collectInterfaces(clazz, interfaces, bundle);
+        }
+
+        // Look for parent class.
+        if (parent != null) {
+            Class clazz = bundle.loadClass(parent);
+            collectInterfacesFromClass(clazz, interfaces, bundle);
+            classes.add(parent);
+            collectParentClassesFromClass(clazz, classes, bundle);
+        }
+    }
+
+    /**
+     * Look for inherited interfaces.
+     * @param clazz : interface name to explore (class object)
+     * @param acc : set (accumulator)
+     * @param bundle : bundle
+     * @throws ClassNotFoundException : occurs when an interface cannot be loaded.
+     */
+    private void collectInterfaces(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+        Class[] clazzes = clazz.getInterfaces();
+        for (int i = 0; i < clazzes.length; i++) {
+            acc.add(clazzes[i].getName());
+            collectInterfaces(clazzes[i], acc, bundle);
+        }
+    }
+
+    /**
+     * Collect interfaces for the given class.
+     * This method explores super class to.
+     * @param clazz : class object.
+     * @param acc : set of implemented interface (accumulator)
+     * @param bundle : bundle.
+     * @throws ClassNotFoundException : occurs if an interface cannot be load.
+     */
+    private void collectInterfacesFromClass(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+        Class[] clazzes = clazz.getInterfaces();
+        for (int i = 0; i < clazzes.length; i++) {
+            acc.add(clazzes[i].getName());
+            collectInterfaces(clazzes[i], acc, bundle);
+        }
+        // Iterate on parent classes
+        Class sup = clazz.getSuperclass();
+        if (sup != null) {
+            collectInterfacesFromClass(sup, acc, bundle);
+        }
+    }
+
+    /**
+     * Collect parent classes for the given class.
+     * @param clazz : class object.
+     * @param acc : set of extended classes (accumulator)
+     * @param bundle : bundle.
+     * @throws ClassNotFoundException : occurs if an interface cannot be load.
+     */
+    private void collectParentClassesFromClass(Class clazz, Set acc, Bundle bundle) throws ClassNotFoundException {
+        Class parent = clazz.getSuperclass();
+        if (parent != null) {
+            acc.add(parent.getName());
+            collectParentClassesFromClass(parent, acc, bundle);
+        }
+    }
+
+    /**
+     * Check the provided service given in argument in the sense that the metadata are consistent.
+     * @param svc : the provided service to check.
+     * @return true if the provided service is correct
+     * @throws ConfigurationException : the checked provided service is not correct.
+     */
+    private boolean checkProvidedService(ProvidedService svc) throws ConfigurationException {
+        for (int i = 0; i < svc.getServiceSpecifications().length; i++) {
+            String specName = svc.getServiceSpecifications()[i];
+
+            // Check service level dependencies
+            try {
+                Class spec = getInstanceManager().getFactory().loadClass(specName);
+                Field specField = spec.getField("specification");
+                Object specif = specField.get(null);
+                if (specif instanceof String) {
+                    Element specification = ManifestMetadataParser.parse((String) specif);
+                    Element[] deps = specification.getElements("requires");
+                    for (int j = 0; deps != null && j < deps.length; j++) {
+                        Dependency dep = getAttachedDependency(deps[j]);
+                        if (dep != null) {
+                            // Fix service-level dependency flag
+                            dep.setServiceLevelDependency();
+                        }
+                        isDependencyCorrect(dep, deps[j]);
+                    }
+                } else {
+                    throw new ConfigurationException("Service Providing: The specification field of the service specification " + svc.getServiceSpecifications()[i] + " needs to be a String");
+                }
+            } catch (NoSuchFieldException e) {
+                return true; // No specification field
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("Service Providing: The service specification " + svc.getServiceSpecifications()[i] + " cannot be load");
+            } catch (IllegalArgumentException e) {
+                throw new ConfigurationException("Service Providing: The field 'specification' of the service specification " + svc.getServiceSpecifications()[i] + " is not accessible : " + e.getMessage());
+            } catch (IllegalAccessException e) {
+                throw new ConfigurationException("Service Providing: The field 'specification' of the service specification " + svc.getServiceSpecifications()[i] + " is not accessible : " + e.getMessage());
+            } catch (ParseException e) {
+                throw new ConfigurationException("Service Providing: The field 'specification' of the service specification " + svc.getServiceSpecifications()[i] + " does not contain a valid String : " + e.getMessage());
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Look for the implementation (i.e. component) dependency for the given service-level requirement metadata.
+     * @param element : the service-level requirement metadata
+     * @return the Dependency object, null if not found or if the DependencyHandler is not plugged to the instance
+     */
+    private Dependency getAttachedDependency(Element element) {
+        DependencyHandler handler = (DependencyHandler) getHandler(HandlerFactory.IPOJO_NAMESPACE + ":requires");
+        if (handler == null) { return null; }
+
+        String identity = element.getAttribute("id");
+        if (identity != null) {
+            // Look for dependency Id
+            for (int i = 0; i < handler.getDependencies().length; i++) {
+                if (handler.getDependencies()[i].getId().equals(identity)) { return handler.getDependencies()[i]; }
+            }
+        }
+        // If not found or no id, look for a dependency with the same specification
+        String requirement = element.getAttribute("specification");
+        for (int i = 0; i < handler.getDependencies().length; i++) {
+            if ((handler.getDependencies()[i].getSpecification().getName()).equals(requirement)) { return handler.getDependencies()[i]; }
+        }
+
+        return null;
+    }
+
+    /**
+     * Check the correctness of the implementation dependency against the service level dependency.
+     * @param dep : dependency to check
+     * @param elem : service-level dependency metadata
+     * @throws ConfigurationException  : the service level dependency and the implementation dependency does not match.
+     */
+    private void isDependencyCorrect(Dependency dep, Element elem) throws ConfigurationException {
+        String optional = elem.getAttribute("optional");
+        boolean opt = optional != null && optional.equalsIgnoreCase("true");
+
+        String aggregate = elem.getAttribute("aggregate");
+        boolean agg = aggregate != null && aggregate.equalsIgnoreCase("true");
+
+        if (dep == null && !opt) {
+            throw new ConfigurationException("Service Providing: The requirement " + elem.getAttribute("specification") + " is not present in the implementation and is declared as a mandatory service-level requirement");
+        }
+
+        if (dep != null && dep.isAggregate() && !agg) {
+            throw new ConfigurationException("Service Providing: The requirement " + elem.getAttribute("specification") + " is aggregate in the implementation and is declared as a simple service-level requirement");
+        }
+
+        String filter = elem.getAttribute("filter");
+        if (dep != null && filter != null) {
+            String filter2 = dep.getFilter();
+            if (filter2 == null || !filter2.equalsIgnoreCase(filter)) {
+                throw new ConfigurationException("Service Providing: The specification requirement " + elem.getAttribute("specification") + " has not the same filter as declared in the service-level requirement");
+            }
+        }
+    }
+
+    /**
+     * Stop the provided service handler.
+     *
+     * @see org.apache.felix.ipojo.Handler#stop()
+     */
+    public void stop() {
+        //Nothing to do.
+    }
+
+    /**
+     * Start the provided service handler.
+     *
+     * @see org.apache.felix.ipojo.Handler#start()
+     */
+    public void start() {
+        // Nothing to do.
+    }
+
+    /**
+     * Setter Callback Method.
+     * Check if the modified field is a property to update the value.
+     * @param pojo : the pojo object on which the field is accessed
+     * @param fieldName : field name
+     * @param value : new value
+     * @see org.apache.felix.ipojo.Handler#onSet(Object,
+     * java.lang.String, java.lang.Object)
+     */
+    public void onSet(Object pojo, String fieldName, Object value) {
+        // Verify that the field name correspond to a dependency
+        for (int i = 0; i < m_providedServices.length; i++) {
+            ProvidedService svc = m_providedServices[i];
+            boolean update = false;
+            for (int j = 0; j < svc.getProperties().length; j++) {
+                Property prop = svc.getProperties()[j];
+                if (fieldName.equals(prop.getField()) && ! prop.getValue().equals(value)) {
+                    // it is the associated property
+                    prop.setValue(value);
+                    update = true;
+                }
+            }
+            if (update) {
+                svc.update();
+            }
+            ServiceController ctrl = svc.getController(fieldName);
+            if (ctrl != null) {
+                if (value instanceof Boolean) {
+                    ctrl.setValue((Boolean) value);
+                } else {
+                    warn("Boolean value expected for the service controler " + fieldName);
+                }
+            }
+        }
+        // Else do nothing
+    }
+
+    /**
+     * Getter Callback Method.
+     * Check if the field is a property to push the stored value.
+     * @param pojo : the pojo object on which the field is accessed
+     * @param fieldName : field name
+     * @param value : value pushed by the previous handler
+     * @return the stored value or the previous value.
+     * @see org.apache.felix.ipojo.Handler#onGet(Object,
+     * java.lang.String, java.lang.Object)
+     */
+    public Object onGet(Object pojo, String fieldName, Object value) {
+        for (int i = 0; i < m_providedServices.length; i++) {
+            ProvidedService svc = m_providedServices[i];
+            for (int j = 0; j < svc.getProperties().length; j++) {
+                Property prop = svc.getProperties()[j];
+                if (fieldName.equals(prop.getField())) {
+                    // Manage the No Value case.
+                    return prop.onGet(pojo, fieldName, value);
+                }
+            }
+            ServiceController ctrl = svc.getController(fieldName);
+            if (ctrl != null) {
+                return new Boolean(ctrl.getValue());
+            }
+        }
+        // Else it is not a property
+        return value;
+    }
+
+    /**
+     * Register the services if the new state is VALID. Unregister the services
+     * if the new state is UNRESOLVED.
+     *
+     * @param state : the new instance state.
+     * @see org.apache.felix.ipojo.Handler#stateChanged(int)
+     */
+    public void stateChanged(int state) {
+        // If the new state is INVALID => unregister all the services
+        if (state == InstanceManager.INVALID) {
+            for (int i = 0; i < m_providedServices.length; i++) {
+                m_providedServices[i].unregisterService();
+            }
+            return;
+        }
+
+        // If the new state is VALID => register all the services
+        if (state == InstanceManager.VALID) {
+            for (int i = 0; i < m_providedServices.length; i++) {
+                m_providedServices[i].registerService();
+            }
+            return;
+        }
+    }
+
+    /**
+     * Adds properties to all provided services.
+     * @param dict : dictionary of properties to add
+     */
+    public void addProperties(Dictionary dict) {
+        for (int i = 0; i < m_providedServices.length; i++) {
+            System.out.println("adding properties " + dict);
+            m_providedServices[i].addProperties(dict);
+            m_providedServices[i].update();
+        }
+    }
+
+    /**
+     * Remove properties form all provided services.
+     *
+     * @param dict : dictionary of properties to delete.
+     */
+    public void removeProperties(Dictionary dict) {
+        for (int i = 0; i < m_providedServices.length; i++) {
+            m_providedServices[i].deleteProperties(dict);
+            m_providedServices[i].update();
+        }
+    }
+
+    /**
+     * Build the provided service description.
+     * @return the handler description.
+     * @see org.apache.felix.ipojo.Handler#getDescription()
+     */
+    public HandlerDescription getDescription() {
+        return m_description;
+    }
+
+    /**
+     * Reconfigure provided service.
+     * @param dict : the new instance configuration.
+     * @see org.apache.felix.ipojo.Handler#reconfigure(java.util.Dictionary)
+     */
+    public void reconfigure(Dictionary dict) {
+        for (int j = 0; j < getProvidedServices().length; j++) {
+            ProvidedService svc = getProvidedServices()[j];
+            Property[] props = svc.getProperties();
+            boolean update = false;
+            for (int k = 0; k < props.length; k++) {
+                if (dict.get(props[k].getName()) != null) {
+                    update = true;
+                    props[k].setValue(dict.get(props[k].getName()));
+                }
+            }
+            if (update) {
+                svc.update();
+            }
+        }
+    }
+
+    /**
+     * Initialize the component type.
+     * @param desc : component type description to populate.
+     * @param metadata : component type metadata.
+     * @throws ConfigurationException : occurs when the POJO does not implement any interfaces.
+     * @see org.apache.felix.ipojo.Handler#initializeComponentFactory(org.apache.felix.ipojo.architecture.ComponentTypeDescription, org.apache.felix.ipojo.metadata.Element)
+     */
+    public void initializeComponentFactory(ComponentTypeDescription desc, Element metadata) throws ConfigurationException {
+        // Change ComponentInfo
+        Element[] provides = metadata.getElements("provides");
+        PojoMetadata manipulation = getFactory().getPojoMetadata();
+
+        for (int i = 0; i < provides.length; i++) {
+            // First : create the serviceSpecification list
+            String[] serviceSpecification = manipulation.getInterfaces();
+            String parent = manipulation.getSuperClass();
+            Set interfaces = new HashSet();
+            Set parentClasses = new HashSet();
+            try {
+                computeInterfacesAndSuperClasses(serviceSpecification, parent, desc.getBundleContext().getBundle(), interfaces, parentClasses);
+                getLogger().log(Logger.INFO, "Collected interfaces from " + metadata.getAttribute("classname") + " : " + interfaces);
+                getLogger().log(Logger.INFO, "Collected super classes from " + metadata.getAttribute("classname") + " : " + parentClasses);
+            } catch (ClassNotFoundException e) {
+                throw new ConfigurationException("An interface or parent class cannot be loaded : " + e.getMessage());
+            }
+
+            String serviceSpecificationStr = provides[i].getAttribute("specifications");
+            if (serviceSpecificationStr == null) {
+                serviceSpecificationStr = provides[i].getAttribute("interface");
+                if (serviceSpecificationStr != null) {
+                    warn("The 'interface' attribute is deprecated, use the 'specifications' attribute instead of 'interface'");
+                }
+            }
+
+            if (serviceSpecificationStr != null) {
+                List itfs = ParseUtils.parseArraysAsList(serviceSpecificationStr);
+                for (int j = 0; j < itfs.size(); j++) {
+                    if (! interfaces.contains(itfs.get(j))
+                            && ! parentClasses.contains(itfs.get(j))
+                            && ! desc.getFactory().getClassName().equals(itfs.get(j))) {
+                            desc.getFactory().getLogger().log(Logger.ERROR, "The specification " + itfs.get(j) + " is not implemented by " + metadata.getAttribute("classname"));
+                    }
+                }
+                interfaces = new HashSet(itfs);
+            }
+
+            if (interfaces.isEmpty()) {
+                warn("No service interface found in the class hierarchy, use the implementation class");
+                interfaces.add(desc.getFactory().getClassName());
+            }
+
+            StringBuffer specs = null;
+            Set set = new HashSet(interfaces);
+            set.remove(Pojo.class.getName()); // Remove POJO.
+            Iterator iterator = set.iterator();
+            while (iterator.hasNext()) {
+                String spec = (String) iterator.next();
+                desc.addProvidedServiceSpecification(spec);
+                if (specs == null) {
+                    specs = new StringBuffer("{");
+                    specs.append(spec);
+                } else {
+                    specs.append(',');
+                    specs.append(spec);
+                }
+            }
+
+            specs.append('}');
+            provides[i].addAttribute(new Attribute("specifications", specs.toString())); // Add interface attribute to avoid checking in the configure method
+
+            Element[] props = provides[i].getElements("property");
+            for (int j = 0; props != null && j < props.length; j++) {
+                String name = props[j].getAttribute("name");
+                String value = props[j].getAttribute("value");
+                String type = props[j].getAttribute("type");
+                String field = props[j].getAttribute("field");
+
+
+                // Get property name :
+                if (field != null && name == null) {
+                    name = field;
+                }
+
+                // Check type if not already set
+                if (type == null) {
+                    if (field == null) {
+                        throw new ConfigurationException("The property " + name + " has neither type nor field.");
+                    }
+                    FieldMetadata fieldMeta = manipulation.getField(field);
+                    if (fieldMeta == null) {
+                        throw new ConfigurationException("A declared property was not found in the implementation class : " + field);
+                    }
+                    type = fieldMeta.getFieldType();
+                    props[j].addAttribute(new Attribute("type", type));
+                }
+
+                // Is the property set to immutable
+                boolean immutable = false;
+                String imm = props[j].getAttribute("immutable");
+                if (imm != null && imm.equalsIgnoreCase("true")) {
+                    immutable = true;
+                }
+
+                PropertyDescription pd = new PropertyDescription(name, type, value, immutable);
+                desc.addProperty(pd);
+
+                String man = props[j].getAttribute("mandatory");
+                if (man != null && man.equalsIgnoreCase("true")) {
+                    pd.setMandatory();
+                }
+            }
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
new file mode 100644
index 0000000..fa080f9
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerDescription.java
@@ -0,0 +1,119 @@
+/* 
+ * 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.handlers.providedservice;
+
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.architecture.HandlerDescription;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.Constants;
+
+/**
+ * Provided Service Handler Description.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ProvidedServiceHandlerDescription extends HandlerDescription {
+
+    /**
+     * Provided Service Description list.
+     */
+    private ProvidedServiceDescription[] m_providedServices = new ProvidedServiceDescription[0];
+   
+    /**
+     * Constructor.
+     * @param handler the handler.
+     * @param pss the list of provided service
+     */
+    public ProvidedServiceHandlerDescription(ProvidedServiceHandler handler, ProvidedService[] pss) {
+        super(handler);
+        m_providedServices = new ProvidedServiceDescription[pss.length];
+        for (int i = 0; i < pss.length; i++) {
+            m_providedServices[i] = new ProvidedServiceDescription(pss[i]);
+        }
+    }
+
+    /**
+     * Get the provided service descriptions.
+     * @return the provided service description list.
+     */
+    public ProvidedServiceDescription[] getProvidedServices() {
+        return m_providedServices;
+    }
+
+    /**
+     * Build the provided service handler description.
+     * @return the handler description.
+     * @see org.apache.felix.ipojo.architecture.HandlerDescription#getHandlerInfo()
+     */
+    public Element getHandlerInfo() {
+        Element services = super.getHandlerInfo();
+        for (int i = 0; i < m_providedServices.length; i++) {
+            Element service = new Element("provides", null);
+            StringBuffer spec = new StringBuffer("[");
+            for (int j = 0; j < m_providedServices[i].getServiceSpecifications().length; j++) {
+                if (j == 0) {
+                    spec.append(m_providedServices[i].getServiceSpecifications()[j]);
+                } else {
+                    spec.append(',');
+                    spec.append(m_providedServices[i].getServiceSpecifications()[j]);
+                }
+            }
+            spec.append(']');
+            service.addAttribute(new Attribute("specifications", spec.toString()));
+
+            if (m_providedServices[i].getState() == ProvidedService.REGISTERED) {
+                service.addAttribute(new Attribute("state", "registered"));
+                service.addAttribute(new Attribute("service.id", m_providedServices[i].getServiceReference()
+                        .getProperty(Constants.SERVICE_ID).toString()));
+            } else {
+                service.addAttribute(new Attribute("state", "unregistered"));
+            }
+            
+            // Service Properties.
+            Properties props = m_providedServices[i].getProperties();
+            Iterator iterator = props.keySet().iterator();
+            while (iterator.hasNext()) {
+                Element prop = new Element("property", null);
+                String name = (String) iterator.next();
+                prop.addAttribute(new Attribute("name", name));
+                Object obj = props.get(name);
+                if (obj != null) {
+                    prop.addAttribute(new Attribute("value", obj.toString()));
+                } else {
+                    prop.addAttribute(new Attribute("value", "null"));
+                }
+                service.addElement(prop);
+            }
+            
+            // Service Controller.
+            if (m_providedServices[i].getController() != null) {
+                Element controller = new Element("controller", null);
+                controller.addAttribute(new Attribute("value", m_providedServices[i].getController()));
+                service.addElement(controller);
+            }
+            
+            services.addElement(service);
+        }
+        return services;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ConfigurableCreationStrategy.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ConfigurableCreationStrategy.java
new file mode 100644
index 0000000..5c5ed35
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ConfigurableCreationStrategy.java
@@ -0,0 +1,142 @@
+/* 
+ * 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.handlers.providedservice.strategy;
+
+import java.lang.reflect.Proxy;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.IPOJOServiceFactory;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.handlers.providedservice.CreationStrategy;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * This {@link CreationStrategy} is here to ease customization of the strategy
+ * by hiding all the reflection stuff.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class ConfigurableCreationStrategy extends CreationStrategy {
+
+    /**
+     * The instance manager passed to the iPOJO ServiceFactory to manage
+     * instances.
+     */
+    private InstanceManager m_manager;
+
+    /**
+     * The lists of interfaces provided by this service.
+     */
+    private String[] m_specs;
+
+    /**
+     * The iPOJO ServiceFactory.
+     */
+    private IPOJOServiceFactory m_factory;
+
+    /**
+     * Method called when the underlying iPOJO Service factory
+     * is published.
+     * @param manager the instance manager
+     * @param specifications the provided specifications
+     * @param props the service properties
+     * @see org.apache.felix.ipojo.handlers.providedservice.CreationStrategy#onPublication(org.apache.felix.ipojo.InstanceManager, java.lang.String[], java.util.Properties)
+     */
+    public void onPublication(final InstanceManager manager,
+            final String[] specifications, final Properties props) {
+        // Store specifications (aka interfaces)
+        this.m_specs = specifications;
+        this.m_manager = manager;
+    }
+
+    /**
+     * Method called when the underlying iPOJO Service factory is
+     * un-published.
+     * @see org.apache.felix.ipojo.handlers.providedservice.CreationStrategy#onUnpublication()
+     */
+    public void onUnpublication() {
+        // Try to close the factory
+        if (m_factory instanceof ServiceObjectFactory) {
+            ((ServiceObjectFactory) m_factory).close();
+        }
+    }
+
+    /**
+     * Method called when a bundle want to access a service. This method is called once per
+     * asking bundle. To turn around this limitation, a proxy is registered.
+     * @param bundle the asking bundle
+     * @param registration the service registration
+     * @return the service object
+     * @see org.osgi.framework.ServiceFactory#getService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration)
+     */
+    public Object getService(final Bundle bundle,
+            final ServiceRegistration registration) {
+        // Init the factory if needed
+        if (m_factory == null) {
+            m_factory = getServiceFactory(m_manager);
+        }
+        // Return a proxy wrapping the real iPOJO ServiceFactory
+        return Proxy.newProxyInstance(m_manager.getClazz().getClassLoader(),
+                getModifiedSpecifications(m_manager.getContext()),
+                new ErrorPrintingServiceFactoryProxy(m_factory));
+    }
+
+    /**
+     * Method called when a bundle release a service.
+     * @param bundle the bundle
+     * @param registration the service registration
+     * @param service the service object
+     * @see org.osgi.framework.ServiceFactory#ungetService(org.osgi.framework.Bundle, org.osgi.framework.ServiceRegistration, java.lang.Object)
+     */
+    public void ungetService(final Bundle bundle,
+            final ServiceRegistration registration, final Object service) {
+        // Nothing to do
+    }
+
+    /**
+     * Utility method that transform the specifications names into a Class
+     * array, appending the IPOJOServiceFactory interface to it.
+     * @param context used for class loading
+     * @return a array of Class
+     */
+    private Class[] getModifiedSpecifications(final BundleContext context) {
+        Class[] classes = new Class[m_specs.length + 1];
+        int i = 0;
+        for (i = 0; i < m_specs.length; i++) {
+            try {
+                classes[i] = context.getBundle().loadClass(m_specs[i]);
+            } catch (ClassNotFoundException e) {
+                // Should not happen.
+            }
+        }
+        classes[i] = IPOJOServiceFactory.class;
+        return classes;
+    }
+
+    /**
+     * User provided {@link CreationStrategy} MUST implement this method to
+     * provide the real iPOJO ServiceFactory instance.
+     * @param manager {@link InstanceManager} that the factory could use
+     * @return an instance of {@link IPOJOServiceFactory}
+     */
+    protected abstract IPOJOServiceFactory getServiceFactory(
+            final InstanceManager manager);
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ErrorPrintingServiceFactoryProxy.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ErrorPrintingServiceFactoryProxy.java
new file mode 100644
index 0000000..ec51005
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ErrorPrintingServiceFactoryProxy.java
@@ -0,0 +1,104 @@
+/* 
+ * 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.handlers.providedservice.strategy;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.IPOJOServiceFactory;
+
+/**
+ * This proxy class is here to wrap an iPOJO ServiceFactory.
+ * If the consumer of this service do not call the getService or ungetService
+ * methods, it will get an Exception with an explicit error message telling
+ * him that this service is only usable through iPOJO.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ErrorPrintingServiceFactoryProxy implements InvocationHandler {
+
+    /**
+     * getService(ComponentInstance) method.
+     */
+    private static Method GET_METHOD;
+
+    /**
+     * ungetService(ComponentInstance, Object) method.
+     */
+    private static Method UNGET_METHOD;
+
+    /**
+     * Wrapped factory.
+     */
+    private final IPOJOServiceFactory m_factory;
+
+    static {
+        // Static initialization of theses constants.
+        try {
+            GET_METHOD = IPOJOServiceFactory.class.getMethod("getService",
+                                                             new Class[]{ComponentInstance.class});
+            UNGET_METHOD = IPOJOServiceFactory.class.getMethod("ungetService",
+                                                               new Class[]{ComponentInstance.class, Object.class});
+        } catch (Exception e) {
+            // Should never happen
+        }
+    }
+
+    /**
+     * Wraps a ServiceFactory in an InvocationHandler that will delegate only
+     * get/ungetService methods to the factory. All other methods will be
+     * rejected with a meaningful error message.
+     *
+     * @param factory delegating iPOJO ServiceFactory
+     */
+    public ErrorPrintingServiceFactoryProxy(final IPOJOServiceFactory factory) {
+        this.m_factory = factory;
+    }
+
+    /**
+     * 'Invoke' methods called when a method is called on the proxy.
+     * @param proxy the proxy
+     * @param method the method
+     * @param args the arguments
+     * @return the result
+     * @throws Exception if something wrong happens
+     * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+     */
+    public Object invoke(final Object proxy,
+                         final Method method,
+                         final Object[] args) throws Exception {
+
+        // Handle get/unget operations
+        if (GET_METHOD.equals(method)) {
+            return m_factory.getService((ComponentInstance) args[0]);
+        }
+        if (UNGET_METHOD.equals(method)) {
+            m_factory.ungetService((ComponentInstance) args[0], args[1]);
+            return null;
+        }
+
+        // All other methods are rejected
+        throw new UnsupportedOperationException("This service requires an advanced creation policy. "
+                        + "Before calling the service, call the IPOJOServiceFactory.getService(ComponentInstance) "
+                        + "method to get the service object. ");
+
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ServiceObjectFactory.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ServiceObjectFactory.java
new file mode 100644
index 0000000..26c4fc7
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/handlers/providedservice/strategy/ServiceObjectFactory.java
@@ -0,0 +1,36 @@
+/* 
+ * 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.handlers.providedservice.strategy;
+
+import org.apache.felix.ipojo.IPOJOServiceFactory;
+
+/**
+ * Extended iPOJOServiceFactory that supports a close() operation.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface ServiceObjectFactory extends IPOJOServiceFactory {
+
+    /**
+     * Called when the supporting CreationStrategy is unpublished
+     * from the service registry. This allows to do an explicit 
+     * cleanup.
+     */
+    void close();
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java
new file mode 100644
index 0000000..db8bc98
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/FieldMetadata.java
@@ -0,0 +1,159 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.parser;
+
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * A Field Metadata represents a field of the implementation class.
+ * This class avoids using reflection to get the type and the name of a field.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class FieldMetadata {
+    
+    /**
+     * The name of the field.
+     */
+    private String m_name;
+    
+    /**
+     * The yype of the field. 
+     */
+    private String m_type;
+    
+    /**
+     * Creates a field metadata.
+     * This constructor is used when creating the {@link PojoMetadata}
+     * object.
+     * @param metadata the field manipulation element from Manipulation
+     * Metadata.
+     */
+    FieldMetadata(Element metadata) {
+        m_name = metadata.getAttribute("name");
+        m_type = metadata.getAttribute("type");
+    }
+    
+    /**
+     * Creates a field metadata.
+     * This constructor can be used to avoid using {@link PojoMetadata}.
+     * Be care that creating such {@link FieldMetadata} does not assert its 
+     * presence in the implementation class.
+     * @param field the field name.
+     * @param type the type of the field.
+     */
+    public FieldMetadata(String field, String type) {
+        m_name = field;
+        m_type = type;
+    }
+    
+    public String getFieldName() { return m_name; }
+    
+    public String getFieldType() { return m_type; }
+    
+    /**
+     * Gets the 'reflective' type of the given type.
+     * The reflective type is the type used by the Java Reflection API.
+     * More precisely this method handles the array cases 
+     * @param type the type to analyze to find the Java reflective type.
+     * @return the reflective type corresponding to this field.
+     */
+    public static String getReflectionType(String type) {
+        // Primitive Array 
+        if (type.endsWith("[]") && type.indexOf('.') == -1) {
+            int index = type.indexOf('[');
+            return '[' + getInternalPrimitiveType(type.substring(0, index));
+        }
+        // Non-Primitive Array 
+        if (type.endsWith("[]") && type.indexOf('.') != -1) {
+            int index = type.indexOf('[');
+            return "[L" + type.substring(0, index) + ";";
+        }
+        // The type is not an array.
+        return type;
+    }
+    
+    /**
+     * Gets the internal notation for primitive type.
+     * @param string the String form of the type
+     * @return the internal notation or <code>null</code> if not found
+     */
+    public static String getInternalPrimitiveType(String string) {
+        if (string.equalsIgnoreCase("boolean")) {
+            return "Z";
+        }
+        if (string.equalsIgnoreCase("char")) {
+            return "C";
+        }
+        if (string.equalsIgnoreCase("byte")) {
+            return "B";
+        }
+        if (string.equalsIgnoreCase("short")) {
+            return "S";
+        }
+        if (string.equalsIgnoreCase("int")) {
+            return "I";
+        }
+        if (string.equalsIgnoreCase("float")) {
+            return "F";
+        }
+        if (string.equalsIgnoreCase("long")) {
+            return "J";
+        }
+        if (string.equalsIgnoreCase("double")) {
+            return "D";
+        }
+        return null;
+    }
+    
+    /**
+     * Gets the iPOJO primitive type from the given primitive class.
+     * @param clazz the class of the primitive type
+     * @return the iPOJO primitive type name or <code>null</code> if
+     * not found.
+     */
+    public static String getPrimitiveTypeByClass(Class clazz) {
+        if (clazz.equals(Boolean.TYPE)) {
+            return "boolean";
+        }
+        if (clazz.equals(Character.TYPE)) {
+            return "char";
+        }
+        if (clazz.equals(Byte.TYPE)) {
+            return "byte";
+        }
+        if (clazz.equals(Short.TYPE)) {
+            return "short";
+        }
+        if (clazz.equals(Integer.TYPE)) {
+            return "int";
+        }
+        if (clazz.equals(Float.TYPE)) {
+            return "float";
+        }
+        if (clazz.equals(Long.TYPE)) {
+            return "long";
+        }
+        if (clazz.equals(Double.TYPE)) {
+            return "double";
+        }
+        return null;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
new file mode 100644
index 0000000..1acbfe1
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/ManifestMetadataParser.java
@@ -0,0 +1,560 @@
+/*
+ * 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.parser;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * The Manifest Metadata parser reads a manifest file and builds
+ * the iPOJO metadata ({@link Element} / {@link Attribute} ) structure.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ManifestMetadataParser {
+
+    /**
+     * The element list.
+     * Contains the element found in the parsed header.
+     */
+    private Element[] m_elements = new Element[0];
+
+    /**
+     * Gets the array of component type metadata.
+     * @return the component metadata (composite & component).
+     * An empty array is returned if no component type declaration.
+     * @throws ParseException if a parsing error occurs
+     */
+    public Element[] getComponentsMetadata() throws ParseException {
+        Element[] elems = m_elements[0].getElements();
+        List list = new ArrayList();
+        for (int i = 0; i < elems.length; i++) {
+            if (!"instance".equals(elems[i].getName())) {
+                list.add(elems[i]);
+            }
+        }
+        return (Element[]) list.toArray(new Element[list.size()]);
+    }
+
+    /**
+     * Gets the array of instance configuration described in the metadata.
+     * @return the instances list or <code>null</code> if no instance configuration.
+     * @throws ParseException if the metadata cannot be parsed successfully
+     */
+    public Dictionary[] getInstances() throws ParseException {
+        Element[] configs = m_elements[0].getElements("instance");
+        if (configs == null) {
+            return null;
+        }
+        Dictionary[] dicts = new Dictionary[configs.length];
+        for (int i = 0; i < configs.length; i++) {
+            dicts[i] = parseInstance(configs[i]);
+        }
+        return dicts;
+    }
+
+    /**
+     * Parses an Element to create an instance configuration dictionary.
+     * The 'name' attribute of the instance declaration is mapped
+     * to the 'instance.name' property.
+     * @param instance the Element describing an instance.
+     * @return the resulting dictionary
+     * @throws ParseException if a configuration cannot be parse correctly.
+     */
+    private Dictionary parseInstance(Element instance) throws ParseException {
+        Dictionary dict = new Properties();
+        String name = instance.getAttribute("name");
+        String comp = instance.getAttribute("component");
+        String version = instance.getAttribute("version");
+
+        if (name != null) {
+            dict.put("instance.name", instance.getAttribute("name"));
+        }
+
+        if (comp == null) {
+            throw new ParseException("An instance does not have the 'component' attribute");
+        }
+
+        dict.put("component", comp);
+
+        if (version != null) {
+            dict.put("factory.version", version);
+        }
+
+        Element[] props = instance.getElements("property");
+
+        for (int i = 0; props != null && i < props.length; i++) {
+            parseProperty(props[i], dict);
+        }
+
+        return dict;
+    }
+
+    /**
+     * Parses an instance property.
+     * This method is recursive to handle complex properties.
+     * @param prop the current element to parse
+     * @param dict the dictionary to populate (the future instance configuration)
+     * @throws ParseException if the property cannot be parsed correctly
+     */
+    private void parseProperty(Element prop, Dictionary dict) throws ParseException {
+        // Check that the property has a name
+        String name = prop.getAttribute("name");
+        String value = prop.getAttribute("value");
+        if (name == null) {
+            throw new ParseException("A property does not have the 'name' attribute: " + prop);
+        }
+
+        //case : the property element has no 'value' attribute
+        if (value == null) {
+            // Recursive case
+            // Get the type of the structure to create
+            String type = prop.getAttribute("type");
+            if (type == null || type.equalsIgnoreCase("dictionary")) {
+                dict.put(name, parseDictionary(prop));
+            } else if (type.equalsIgnoreCase("map")) {
+                dict.put(name, parseMap(prop));
+            } else if (type.equalsIgnoreCase("list")) {
+                dict.put(name, parseList(prop));
+            } else if (type.equalsIgnoreCase("array")) {
+                List list = parseList(prop);
+                boolean isString = true;
+                for (int i = 0; isString && i < list.size(); i++) {
+                    isString = list.get(i) instanceof String;
+                }
+                Object[] obj = null;
+                if (isString) {
+                    obj = new String[list.size()];
+                } else {
+                    obj = new Object[list.size()];
+                }
+                // Transform the list to array
+                dict.put(name, list.toArray(obj));
+            }
+        } else {
+            dict.put(prop.getAttribute("name"), prop.getAttribute("value"));
+        }
+    }
+
+    /**
+     * Parses a complex property.
+     * This property will be built as a {@link Dictionary}.
+     * @param prop the Element to parse.
+     * @return the resulting dictionary
+     * @throws ParseException if an internal property is incorrect.
+     */
+    private Dictionary parseDictionary(Element prop) throws ParseException {
+     // Check if there is 'property' elements
+        Element[] subProps = prop.getElements("property");
+        if (subProps != null) {
+            Dictionary dict2 = new Properties();
+            for (int i = 0; i < subProps.length; i++) {
+                parseProperty(subProps[i], dict2);
+            }
+            return dict2;
+        } else {
+            // If the no sub-properties, inject an empty dictionary.
+            return new Properties();
+        }
+    }
+
+    /**
+     * Parses a complex property.
+     * This property will be built as a {@link Map}.
+     * The used {@link Map} implementation is {@link HashMap}.
+     * @param prop the property to parse
+     * @return the resulting Map
+     * @throws ParseException if an internal property is incorrect.
+     */
+    private Map parseMap(Element prop) throws ParseException {
+        // Check if there is 'property' elements
+        Element[] subProps = prop.getElements("property");
+        if (subProps != null) {
+            Map map = new HashMap(); // Create an hashmap to store elements.
+            for (int i = 0; i < subProps.length; i++) {
+                parseProperty(subProps[i], map);
+            }
+            return map;
+        } else { // if not inject an empty map
+            return new HashMap(0);
+        }
+    }
+
+    /**
+     * Parses a complex property. This property will be built as a {@link List}.
+     * The used {@link List} implementation is {@link ArrayList}.
+     * The order of elements is kept.
+     * @param prop the property to parse
+     * @return the resulting List
+     * @throws ParseException if an internal property is incorrect.
+     */
+    private List parseList(Element prop) throws ParseException {
+        Element[] subProps = prop.getElements("property");
+        if (subProps != null) {
+            List list = new ArrayList(subProps.length); // Create a list to store elements.
+            for (int i = 0; i < subProps.length; i++) {
+                parseAnonymousProperty(subProps[i], list); // Anonymous properties.
+            }
+            return list;
+        } else {
+            // If no sub-properties, inject an empty list.
+            return new ArrayList(0);
+        }
+    }
+
+    /**
+     * Parse a property.
+     * This methods handles complex properties.
+     * @param prop the current element to parse
+     * @param map the map to populate
+     * @throws ParseException if the property cannot be parsed correctly
+     */
+    private void parseProperty(Element prop, Map map) throws ParseException {
+        // Check that the property has a name
+        String name = prop.getAttribute("name");
+        String value = prop.getAttribute("value");
+        if (name == null) {
+            throw new ParseException(
+                    "A property does not have the 'name' attribute");
+        }
+        // case : the property element has no 'value' attribute
+        if (value == null) {
+            // Recursive case
+            // Get the type of the structure to create
+            String type = prop.getAttribute("type");
+            if (type == null || type.equalsIgnoreCase("dictionary")) {
+                map.put(name, parseDictionary(prop));
+            } else if (type.equalsIgnoreCase("map")) {
+                map.put(name, parseMap(prop));
+            } else if (type.equalsIgnoreCase("list")) {
+                map.put(name, parseList(prop));
+            } else if (type.equalsIgnoreCase("array")) {
+                List list = parseList(prop);
+                boolean isString = true;
+                for (int i = 0; isString && i < list.size(); i++) {
+                    isString = list.get(i) instanceof String;
+                }
+                Object[] obj = null;
+                if (isString) {
+                    obj = new String[list.size()];
+                } else {
+                    obj = new Object[list.size()];
+                }
+                map.put(name, list.toArray(obj)); // Transform the list to array
+            }
+        } else {
+            map.put(prop.getAttribute("name"), prop.getAttribute("value"));
+        }
+    }
+
+    /**
+     * Parse an anonymous property.
+     * An anonymous property is a property with no name.
+     * An anonymous property can be simple (just a value) or complex (i.e. a map, a dictionary
+     * a list or an array).
+     * @param prop the property to parse
+     * @param list the list to populate with the resulting property
+     * @throws ParseException if an internal property cannot be parse correctly
+     */
+    private void parseAnonymousProperty(Element prop, List list) throws ParseException {
+        // Check that the property has a name
+        String name = prop.getAttribute("name");
+        String value = prop.getAttribute("value");
+        if (name != null) {
+            throw new ParseException("Anonymous property expected in a list or an array");
+        }
+        //case : the property element has no 'value' attribute
+        if (value == null) {
+            // Recursive case
+
+            // Get the type of the structure to create
+            String type = prop.getAttribute("type");
+            if (type == null || type.equalsIgnoreCase("dictionary")) {
+                // Check if there is 'property' elements
+                Element[] subProps = prop.getElements("property");
+                if (subProps != null) {
+                    Dictionary dict2 = new Properties();
+                    for (int i = 0; i < subProps.length; i++) {
+                        parseProperty(subProps[i], dict2);
+                    }
+                    list.add(dict2);
+                } else {
+                    // If the no sub-properties, inject an empty dictionary.
+                    list.add(new Properties());
+                }
+            } else if (type.equalsIgnoreCase("map")) {
+                // Check if there is 'property' elements
+                Element[] subProps = prop.getElements("property");
+                if (subProps != null) {
+                    Map map2 = new HashMap(); // Create an hashmap to store elements.
+                    for (int i = 0; i < subProps.length; i++) {
+                        parseProperty(subProps[i], map2);
+                    }
+                    list.add(map2);
+                } else { // if not inject an empty map
+                    list.add(new HashMap(0));
+                }
+            }  else if (type.equalsIgnoreCase("list")) {
+                Element[] subProps = prop.getElements("property");
+                if (subProps != null) {
+                    // Create a list to store elements.
+                    List list2 = new ArrayList(subProps.length);
+                    for (int i = 0; i < subProps.length; i++) {
+                        parseAnonymousProperty(subProps[i], list2); // Anonymous properties
+                    }
+                    list.add(list2);
+                } else {
+                    // If no sub-properties, inject an empty list.
+                    list.add(new ArrayList(0));
+                }
+            } else if (type.equalsIgnoreCase("array")) {
+                // Check sub-props.
+                Element[] subProps = prop.getElements("property");
+                if (subProps != null) {
+                    List list2 = new ArrayList(subProps.length); // Use list as
+                                                                 // pivot type
+                    for (int i = 0; i < subProps.length; i++) {
+                        parseAnonymousProperty(subProps[i], list2);
+                    }
+                    list.add(list.toArray(new Object[list.size()])); // Transform
+                                                                     // the list
+                                                                     // to array
+                } else {
+                    list.add(new Element[0]); // Insert an empty Element array.
+                }
+            }
+        } else {
+            list.add(prop.getAttribute("value"));
+        }
+
+    }
+
+    /**
+     * Adds an element to the {@link ManifestMetadataParser#m_elements} list.
+     * @param elem the the element to add
+     */
+    private void addElement(Element elem) {
+        if (m_elements == null) {
+            m_elements = new Element[] { elem };
+        } else {
+            Element[] newElementsList = new Element[m_elements.length + 1];
+            System.arraycopy(m_elements, 0, newElementsList, 0, m_elements.length);
+            newElementsList[m_elements.length] = elem;
+            m_elements = newElementsList;
+        }
+    }
+
+    /**
+     * Removes an element from the {@link ManifestMetadataParser#m_elements} list.
+     * @return an element to remove
+     */
+    private Element removeLastElement() {
+        int idx = -1;
+        idx = m_elements.length - 1;
+        Element last = m_elements[idx];
+        if (idx >= 0) {
+            if ((m_elements.length - 1) == 0) {
+                // It is the last element of the list;
+                m_elements = new Element[0];
+            } else {
+                // Remove the last element of the list :
+                Element[] newElementsList = new Element[m_elements.length - 1];
+                System.arraycopy(m_elements, 0, newElementsList, 0, idx);
+                m_elements = newElementsList;
+            }
+        }
+        return last;
+    }
+
+    /**
+     * Looks for the <code>iPOJO-Components</code> header
+     * in the given dictionary. Then, initializes the
+     * {@link ManifestMetadataParser#m_elements} list (adds the
+     * <code>iPOJO</code> root element) and parses the contained
+     * component type declarations and instance configurations.
+     * @param dict the given headers of the manifest file
+     * @throws ParseException if any error occurs
+     */
+    public void parse(Dictionary dict) throws ParseException {
+        String componentClassesStr = (String) dict.get("iPOJO-Components");
+        // Add the ipojo element inside the element list
+        addElement(new Element("iPOJO", ""));
+        parseElements(componentClassesStr.trim());
+    }
+
+    /**
+     * Parses the given header, initialized the
+     * {@link ManifestMetadataParser#m_elements} list
+     * (adds the <code>iPOJO</code> element) and parses
+     * contained component type declarations and instance configurations.
+     * @param header the given header of the manifest file
+     * @throws ParseException if any error occurs
+     */
+    public void parseHeader(String header) throws ParseException {
+        // Add the ipojo element inside the element list
+        addElement(new Element("iPOJO", ""));
+        parseElements(header.trim());
+    }
+
+    /**
+     * Parses the metadata from the string given in argument.
+     * This methods creates a new {@link ManifestMetadataParser} object
+     * and calls the {@link ManifestMetadataParser#parseElements(String)}
+     * method. The parsing must result as a tree (only one root element).
+     * @param metadata the metadata to parse
+     * @return Element the root element resulting of the parsing
+     * @throws ParseException if any error occurs
+     */
+    public static Element parse(String metadata) throws ParseException {
+        ManifestMetadataParser parser = new ManifestMetadataParser();
+        parser.parseElements(metadata);
+        if (parser.m_elements.length != 1) {
+            throw new ParseException("Error in parsing, root element not found : " + metadata);
+        }
+        return parser.m_elements[0];
+    }
+
+    /**
+     * Parses the metadata from the given header string.
+     * This method creates a new {@link ManifestMetadataParser} object and then
+     * creates the <code>iPOJO</code> root element, parses content elements
+     * (component types and instances declarations), and returns the resulting
+     * {@link Element} / {@link Attribute} structure. The parsed string
+     * must be a tree (only one root element).
+     * @param header the header to parse
+     * @return Element the root element resulting of the parsing
+     * @throws ParseException if any error occurs
+     */
+    public static Element parseHeaderMetadata(String header) throws ParseException {
+        ManifestMetadataParser parser = new ManifestMetadataParser();
+        parser.addElement(new Element("iPOJO", ""));
+        parser.parseElements(header);
+        if (parser.m_elements.length != 1) {
+            throw new ParseException("Error in parsing, root element not found : " + header);
+        }
+        return parser.m_elements[0];
+    }
+
+    /**
+     * Parses the given string.
+     * This methods populates the {@link ManifestMetadataParser#m_elements}
+     * list.
+     * @param elems the string to parse
+     */
+    private void parseElements(String elems) {
+        char[] string = elems.toCharArray();
+
+        for (int i = 0; i < string.length; i++) {
+            char current = string[i];
+            switch (current) { //NOPMD
+                // Beginning of an attribute.
+                case '$':
+                    StringBuffer attName = new StringBuffer();
+                    StringBuffer attValue = new StringBuffer();
+                    StringBuffer attNs = null;
+                    i++;
+                    current = string[i]; // Increment and get the new current char.
+                    while (current != '=') {
+                        if (current == ':') {
+                            attNs = attName;
+                            attName = new StringBuffer();
+                        } else {
+                            attName.append(current);
+                        }
+                        i++;
+                        current = string[i];
+                    }
+                    i = i + 2; // skip ="
+                    current = string[i];
+                    while (current != '"') {
+                        attValue.append(current);
+                        i++;
+                        current = string[i]; // Increment and get the new current char.
+                    }
+                    i++; // skip "
+                    current = string[i];
+
+                    Attribute att = null;
+                    if (attNs == null) {
+                        att = new Attribute(attName.toString(), attValue.toString());
+                    } else {
+                        att = new Attribute(attName.toString(), attNs.toString(), attValue.toString());
+                    }
+                    m_elements[m_elements.length - 1].addAttribute(att);
+                    break;
+
+                // End of an element
+                case '}':
+                    Element lastElement = removeLastElement();
+                    if (m_elements.length == 0) {
+                        addElement(lastElement);
+                    } else {
+                        Element newQueue = m_elements[m_elements.length - 1];
+                        newQueue.addElement(lastElement);
+                    }
+                    break;
+
+                // Space
+                case ' ':
+                    break; // do nothing;
+
+                // Default case
+                default:
+                    StringBuffer qname = new StringBuffer();
+                    current = string[i];
+                    while (current != ' ') {
+                        qname.append(current);
+                        i++;
+                        current = string[i]; // Increment and get the new current char.
+                    }
+                    // Skip spaces
+                    while (string[i] == ' ') {
+                        i = i + 1;
+                    }
+                    i = i + 1; // skip {
+
+                    Element elem = null;
+                    // Parse the qname
+                    String n = qname.toString();
+                    if (n.indexOf(':') == -1) {
+                    	// No namespace
+                    	elem = new Element(n, null);
+                    } else {
+                    	// The namespace ends on the first ':'
+                    	int last = n.lastIndexOf(':');
+                    	String ns = n.substring(0, last);
+                    	String name = n.substring(last + 1);
+                    	elem = new Element(name.toString(), ns.toString());
+                    }
+
+                    addElement(elem);
+
+                    break;
+            }
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
new file mode 100644
index 0000000..1de846a
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/MethodMetadata.java
@@ -0,0 +1,176 @@
+/*
+ * 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.parser;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * A Method Metadata represents a method from the implementation class.
+ * This class allows getting information about a method : name, arguments, return type...
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class MethodMetadata {
+
+    /**
+     * Empty Constructor Method Id.
+     */
+    public static final String EMPTY_CONSTRUCTOR_ID = "$init";
+
+    /**
+     * Bundle Context Constructor Method Id.
+     */
+    public static final String BC_CONSTRUCTOR_ID = "$init$org_osgi_framework_BundleContext";
+
+    /**
+     * Constructor Prefix.
+     */
+    public static final String CONSTRUCTOR_PREFIX = "$init";
+
+    /**
+     * The name of the method.
+     */
+    private String m_name;
+
+    /**
+     * The argument type array.
+     */
+    private String[] m_arguments = new String[0];
+
+    /**
+     * The returned type.
+     */
+    private String m_return = "void";
+
+    /**
+     * Creates a Method Metadata.
+     * @param metadata the method manipulation element.
+     */
+    MethodMetadata(Element metadata) {
+        m_name = metadata.getAttribute("name");
+        String arg = metadata.getAttribute("arguments");
+        String result = metadata.getAttribute("return");
+        if (arg != null) {
+            m_arguments = ParseUtils.parseArrays(arg);
+        }
+        if (result != null) {
+            m_return = result;
+        }
+    }
+
+    public String getMethodName() {
+        return m_name;
+    }
+
+    public String[] getMethodArguments() {
+        return m_arguments;
+    }
+
+    public String getMethodReturn() {
+        return m_return;
+    }
+
+    /**
+     * Gets the method unique identifier. For internal usage only.
+     * A method identifier is a unique string that can be a java field
+     * that identify the method.
+     * @return the method identifier.
+     */
+    public String getMethodIdentifier() {
+        StringBuffer identifier = new StringBuffer(m_name);
+        for (int i = 0; i < m_arguments.length; i++) {
+            String arg = m_arguments[i];
+            identifier.append('$');
+            if (arg.endsWith("[]")) {
+                arg = arg.substring(0, arg.length() - 2);
+                identifier.append(arg.replace('.', '_'));
+                identifier.append("__"); // Replace [] by __
+            } else {
+                identifier.append(arg.replace('.', '_'));
+            }
+        }
+        return identifier.toString();
+    }
+
+    /**
+     * Computes the method id for the given Method object.
+     * @param method the Method object.
+     * @return the method id.
+     */
+    public static String computeMethodId(Method method) {
+        StringBuffer identifier = new StringBuffer(method.getName());
+        Class[] args = method.getParameterTypes();
+        for (int i = 0; i < args.length; i++) {
+            identifier.append('$'); // Argument separator.
+            if (args[i].isArray()) {
+                if (args[i].getComponentType().isPrimitive()) {
+                    // Primitive array
+                    identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i].getComponentType()));
+                } else {
+                    // Object array
+                    identifier.append(args[i].getComponentType().getName().replace('.', '_')); // Replace '.' by '_'
+                }
+                identifier.append("__"); // Add __ (array)
+            } else {
+                if (args[i].isPrimitive()) {
+                    // Primitive type
+                    identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i]));
+                } else {
+                    // Object type
+                    identifier.append(args[i].getName().replace('.', '_')); // Replace '.' by '_'
+                }
+            }
+        }
+        return identifier.toString();
+    }
+
+    /**
+     * Computes the method id for the given Constructor object.
+     * @param method the Method object.
+     * @return the method id.
+     */
+    public static String computeMethodId(Constructor method) {
+        StringBuffer identifier = new StringBuffer("$init");
+        Class[] args = method.getParameterTypes();
+        for (int i = 0; i < args.length; i++) {
+            identifier.append('$'); // Argument separator.
+            if (args[i].isArray()) {
+                if (args[i].getComponentType().isPrimitive()) {
+                    // Primitive array
+                    identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i].getComponentType()));
+                } else {
+                    // Object array
+                    identifier.append(args[i].getComponentType().getName().replace('.', '_')); // Replace '.' by '_'
+                }
+                identifier.append("__"); // Add __ (array)
+            } else {
+                if (args[i].isPrimitive()) {
+                    // Primitive type
+                    identifier.append(FieldMetadata.getPrimitiveTypeByClass(args[i]));
+                } else {
+                    // Object type
+                    identifier.append(args[i].getName().replace('.', '_')); // Replace '.' by '_'
+                }
+            }
+        }
+        return identifier.toString();
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/ParseException.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/ParseException.java
new file mode 100644
index 0000000..1a1db2d
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/ParseException.java
@@ -0,0 +1,40 @@
+/* 
+ * 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.parser;
+
+/**
+ * Exception thrown by parsers.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ParseException extends Exception {
+
+    /**
+     * serialVersionUID.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Parsing error.
+     * @param msg : the error emssage.
+     */
+    public ParseException(String msg) {
+        super(msg);
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.java
new file mode 100644
index 0000000..a2227e5
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/ParseUtils.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.felix.ipojo.parser;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * Parser Utility Methods.
+ * This class contains helper method to parse iPOJO metadata.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public final class ParseUtils {
+
+    /**
+     * Parses the iPOJO string form of an array as {a, b, c}
+     * or [a, b, c].
+     * @param str the string form
+     * @return the resulting string array
+     */
+    public static String[] parseArrays(String str) {
+        if (str.length() == 0) {
+            return new String[0];
+        }
+        
+        // Remove { and } or [ and ]
+        if ((str.charAt(0) == '{' && str.charAt(str.length() - 1) == '}') 
+                || (str.charAt(0) == '[' && str.charAt(str.length() - 1) == ']')) {
+            String internal = (str.substring(1, str.length() - 1)).trim();
+            // Check empty array
+            if (internal.length() == 0) {
+                return new String[0];
+            }
+            return split(internal, ",");
+        } else {
+            return new String[] { str };
+        }
+    }
+    
+    /**
+     * Parses the string form of an array as {a, b, c}
+     * or [a, b, c] as a list.
+     * @param str the string form
+     * @return the resulting list
+     */
+    public static List parseArraysAsList(String str) {
+        return Arrays.asList(parseArrays(str));
+    }
+    
+    /**
+     * Split method. 
+     * This method is equivalent of the String.split in java 1.4
+     * The result array contains 'trimmed' String
+     * @param toSplit the String to split
+     * @param separator the separator
+     * @return the split array 
+     */
+    public static String[] split(String toSplit, String separator) {
+        StringTokenizer tokenizer = new StringTokenizer(toSplit, separator);
+        String[] result = new String[tokenizer.countTokens()];
+        int index = 0;
+        while (tokenizer.hasMoreElements()) {
+            result[index] = tokenizer.nextToken().trim();
+            index++;
+        }
+        return result;
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java
new file mode 100644
index 0000000..8b06832
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/parser/PojoMetadata.java
@@ -0,0 +1,267 @@
+/*
+ * 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.parser;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Manipulation Metadata allows getting information about the implementation class
+ * without using reflection such as implemented interfaces, super class,
+ * methods and fields.
+ * This method allows getting object to register {@link org.apache.felix.ipojo.FieldInterceptor} and
+ * {@link org.apache.felix.ipojo.MethodInterceptor}.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class PojoMetadata {
+
+    /**
+     * The list of implemented interfaces.
+     */
+    private String[] m_interfaces = new String[0];
+
+    /**
+     * The list of fields.
+     */
+    private FieldMetadata[] m_fields = new FieldMetadata[0];
+
+    /**
+     * The list of methods.
+     */
+    private MethodMetadata[] m_methods = new MethodMetadata[0];
+
+    /**
+     * The Super class (if <code>null</code> for {@link Object}).
+     */
+    private String m_super;
+
+
+    /**
+     * Creates Pojo metadata.
+     * Manipulation Metadata object are created from component type metadata by
+     * parsing manipulation metadata.
+     * @param metadata the component type metadata
+     * @throws ConfigurationException if the manipulation metadata cannot be found
+     */
+    public PojoMetadata(Element metadata) throws ConfigurationException {
+        Element[] elems = metadata.getElements("manipulation", "");
+        if (elems == null) {
+            throw new ConfigurationException("The component " + metadata.getAttribute("classname") + " has no manipulation metadata");
+        }
+        Element manip = elems[0];
+        m_super = manip.getAttribute("super");
+        Element[] fields = manip.getElements("field");
+        for (int i = 0; fields != null && i < fields.length; i++) {
+            FieldMetadata field = new FieldMetadata(fields[i]);
+            addField(field);
+        }
+        Element[] methods = manip.getElements("method");
+        for (int i = 0; methods != null && i < methods.length; i++) {
+            MethodMetadata method = new MethodMetadata(methods[i]);
+            addMethod(method);
+        }
+        Element[] itfs = manip.getElements("interface");
+        for (int i = 0; itfs != null && i < itfs.length; i++) {
+            addInterface(itfs[i].getAttribute("name"));
+        }
+    }
+
+    public MethodMetadata[] getMethods() { return m_methods; }
+
+    public FieldMetadata[] getFields() { return m_fields; }
+
+    public String[] getInterfaces() { return m_interfaces; }
+
+    /**
+     * Gets the field metadata for the given name.
+     * @param name : the name of the field
+     * @return the corresponding field metadata or <code>null</code> if not found
+     */
+    public FieldMetadata getField(String name) {
+        for (int i = 0; i < m_fields.length; i++) {
+            if (m_fields[i].getFieldName().equalsIgnoreCase(name)) { return m_fields[i]; }
+        }
+        return null;
+    }
+
+    /**
+     * Gets the field metadata for the given name and type.
+     * @param name : the name of the field
+     * @param type : the type of the field
+     * @return the corresponding field metadata or <code>null</code> if not found
+     */
+    public FieldMetadata getField(String name, String type) {
+        for (int i = 0; i < m_fields.length; i++) {
+            if (m_fields[i].getFieldName().equalsIgnoreCase(name) && m_fields[i].getFieldType().equalsIgnoreCase(type)) { return m_fields[i]; }
+        }
+        return null;
+    }
+
+    /**
+     * Checks if the given interface name is implemented.
+     * This methods checks on interface directly implemented
+     * by the implementation class.
+     * @param itf the interface to check.
+     * @return <code>true</code> if the implementation class implements
+     * the given interface.
+     */
+    public boolean isInterfaceImplemented(String itf) {
+        for (int i = 0; i < m_interfaces.length; i++) {
+            if (m_interfaces[i].equals(itf)) { return true; }
+        }
+        return false;
+    }
+
+    /**
+     * Gets the MethodMetadata corresponding to the method
+     * (contained in the implementation class) with
+     * the given name.
+     * If several methods match, the first one is returned.
+     * @param name the name of the method to find.
+     * @return the method metadata object or <code>null</code> if not found
+     */
+    public MethodMetadata getMethod(String name) {
+        for (int i = 0; i < m_methods.length; i++) {
+            if (m_methods[i].getMethodName().equalsIgnoreCase(name)) { return m_methods[i]; }
+        }
+        return null;
+    }
+
+    /**
+     * Gets the MethodMetadata list corresponding to the method
+     * (contained in the implementation class) to given name.
+     * All methods contained in the implementation class matching
+     * with the name are in the returned list.
+     * @param name the name of the method to look for.
+     * @return the Method Metadata array or an empty array if not found
+     */
+    public MethodMetadata[] getMethods(String name) {
+        MethodMetadata[] mms = new MethodMetadata[0];
+        for (int i = 0; i < m_methods.length; i++) {
+            if (m_methods[i].getMethodName().equalsIgnoreCase(name)) {
+                if (mms.length > 0) {
+                    MethodMetadata[] newInstances = new MethodMetadata[mms.length + 1];
+                    System.arraycopy(mms, 0, newInstances, 0, mms.length);
+                    newInstances[mms.length] = m_methods[i];
+                    mms = newInstances;
+                } else {
+                    mms = new MethodMetadata[] { m_methods[i] };
+                }
+            }
+        }
+        return mms;
+    }
+
+    /**
+     * Gets the MethodMetadata list corresponding to the constructors
+     * (contained in the implementation class).
+     * @return the Method Metadata array or an empty array if not found
+     */
+    public MethodMetadata[] getConstructors() {
+        return getMethods("$init");
+    }
+
+    /**
+     * Gets the MethodMetadata corresponding to the method
+     * (contained in the implementation class) to given name
+     * and argument types.
+     * @param name the name of the method to look for.
+     * @param types the array of the argument types of the method
+     * @return the Method Metadata or <code>null</code> if not found
+     */
+    public MethodMetadata getMethod(String name, String[] types) {
+        for (int i = 0; i < m_methods.length; i++) {
+            if (m_methods[i].getMethodName().equalsIgnoreCase(name) && m_methods[i].getMethodArguments().length == types.length) {
+                int argIndex = 0;
+                for (; argIndex < types.length; argIndex++) {
+                    if (! types[argIndex].equals(m_methods[i].getMethodArguments()[argIndex])) {
+                        break;
+                    }
+                }
+                if (argIndex == types.length) { return m_methods[i]; } // No mismatch detected.
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets the constructor corresponding to the given argument types.
+     * @param types the argument types
+     * @return the matching constructor or <code>null</code> if not found.
+     */
+    public MethodMetadata getConstructor(String[] types) {
+    	return getMethod("$init", types); // Constructors are named $init in the manipulation metadata
+    }
+
+     /**
+     * Adds a method to the list.
+     * This method is used during the creation of the {@link PojoMetadata}
+     * object.
+     * @param method the Method Metadata to add.
+     */
+    private void addMethod(MethodMetadata method) {
+        if (m_methods.length > 0) {
+            MethodMetadata[] newInstances = new MethodMetadata[m_methods.length + 1];
+            System.arraycopy(m_methods, 0, newInstances, 0, m_methods.length);
+            newInstances[m_methods.length] = method;
+            m_methods = newInstances;
+        } else {
+            m_methods = new MethodMetadata[] { method };
+        }
+    }
+
+     /**
+     * Adds a field to the list.
+     * This method is used during the creation of the {@link PojoMetadata}
+     * object.
+     * @param field the Field Metadata to add.
+     */
+    private void addField(FieldMetadata field) {
+        if (m_fields.length > 0) {
+            FieldMetadata[] newInstances = new FieldMetadata[m_fields.length + 1];
+            System.arraycopy(m_fields, 0, newInstances, 0, m_fields.length);
+            newInstances[m_fields.length] = field;
+            m_fields = newInstances;
+        } else {
+            m_fields = new FieldMetadata[] { field };
+        }
+    }
+
+    /**
+     * Adds the interface to the list.
+     * This method is used during the creation of the {@link PojoMetadata}
+     * object.
+     * @param itf the interface name to add.
+     */
+    private void addInterface(String itf) {
+        if (m_interfaces.length > 0) {
+            String[] newInstances = new String[m_interfaces.length + 1];
+            System.arraycopy(m_interfaces, 0, newInstances, 0, m_interfaces.length);
+            newInstances[m_interfaces.length] = itf;
+            m_interfaces = newInstances;
+        } else {
+            m_interfaces = new String[] { itf };
+        }
+    }
+
+    public String getSuperClass() {
+        return m_super;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Callback.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
new file mode 100644
index 0000000..fe32379
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Callback.java
@@ -0,0 +1,278 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.parser.FieldMetadata;
+import org.apache.felix.ipojo.parser.MethodMetadata;
+
+/**
+ * A callback allows invoking a method on a POJO.
+ * This class supports both public, protected and private methods of the
+ * implementation class. This class also supports public method from super class.
+ * The {@link Method} object is computed once and this computation is delayed
+ * to the first invocation.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Callback {
+
+    /**
+     * The method object.
+     * Computed at the first call.
+     */
+    protected Method m_methodObj;
+
+    /**
+     * The name of the method to call.
+     */
+    private String m_method;
+
+    /**
+     * Is the method a static method ?
+     * This implies calling the method on <code>null</code>
+     */
+    private boolean m_isStatic;
+
+    /**
+     * The reference on the instance manager.
+     * Used to get POJO objects.
+     */
+    private InstanceManager m_manager;
+
+    /**
+     * The argument classes.
+     * This array contains the list of argument class names.
+     */
+    private String[] m_args;
+
+    /**
+     * Creates a Callback.
+     * If the argument array is not null the reflection type are computed.
+     * @see {@link Callback#computeArguments(String[])}
+     * @param method the name of the method to call
+     * @param args the argument type name, or <code>null</code> if no arguments
+     * @param isStatic is the method a static method
+     * @param manager the instance manager of the component containing the method
+     */
+    public Callback(String method, String[] args, boolean isStatic, InstanceManager manager) {
+        m_method = method;
+        m_isStatic = isStatic;
+        m_manager = manager;
+        if (args != null) {
+            computeArguments(args);
+        } else {
+        	m_args = new String[0];
+        }
+    }
+
+    /**
+     * Creates a Callback.
+     * @param method the the name of the method to call
+     * @param args the argument classes
+     * @param isStatic the is the method a static method
+     * @param manager the the instance manager of the component containing the method
+     */
+    public Callback(String method, Class[] args, boolean isStatic, InstanceManager manager) {
+        m_method = method;
+        m_isStatic = isStatic;
+        m_manager = manager;
+        m_args = new String[args.length];
+        for (int i = 0; i < args.length; i++) {
+            m_args[i] = args[i].getName();
+        }
+    }
+
+    /**
+     * Creates a Callback.
+     * @param method the {@link MethodMetadata} obtained from manipulation
+     * metadata ({@link PojoMetadata}).
+     * @param manager the instance manager.
+     */
+    public Callback(MethodMetadata method, InstanceManager manager) {
+        m_isStatic = false;
+        m_method = method.getMethodName();
+        m_manager = manager;
+        computeArguments(method.getMethodArguments());
+    }
+
+    /**
+     * Computes arguments of the method.
+     * This method computes "reflection type" from given argument.
+     * @see FieldMetadata#getReflectionType(String)
+     * @param args the arguments of the method.
+     */
+    private void computeArguments(String[] args) {
+        m_args = new String[args.length];
+        for (int i = 0; i < args.length; i++) {
+            m_args[i] = FieldMetadata.getReflectionType(args[i]);
+        }
+    }
+
+    /**
+     * Searches the {@link Method} in the given method arrays.
+     * @param methods the method array in which the method should be found
+     * @return the method object or <code>null</code> if not found
+     */
+    private Method searchMethodInMethodArray(Method[] methods) {
+        for (int i = 0; i < methods.length; i++) {
+            // First check the method name
+            if (methods[i].getName().equals(m_method)) {
+                // Check arguments
+                Class[] clazzes = methods[i].getParameterTypes();
+                if (clazzes.length == m_args.length) { // Test size to avoid useless loop
+                    int argIndex = 0;
+                    for (; argIndex < m_args.length; argIndex++) {
+                        if (!m_args[argIndex].equals(clazzes[argIndex].getName())) {
+                            break;
+                        }
+                    }
+                    if (argIndex == m_args.length) { // No mismatch detected.
+                        return methods[i]; // It is the looked method.
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Searches the {@link Method} object in the POJO by analyzing implementation
+     * class methods. The name of the method and the argument type are checked.
+     * @throws NoSuchMethodException if the method cannot be found either in the
+     * implementation class or in parent classes.
+     */
+    protected void searchMethod() throws NoSuchMethodException {
+        Method[] methods = m_manager.getClazz().getDeclaredMethods();
+        m_methodObj = searchMethodInMethodArray(methods);
+
+        if (m_methodObj == null) { // look at parent classes
+            methods = m_manager.getClazz().getMethods();
+            m_methodObj = searchMethodInMethodArray(methods);
+        }
+
+        if (m_methodObj == null) {
+            throw new NoSuchMethodException(m_method);
+        } else {
+            if (! m_methodObj.isAccessible()) {
+                // If not accessible, try to set the accessibility.
+                m_methodObj.setAccessible(true);
+            }
+        }
+    }
+
+    /**
+     * Invokes the method without arguments.
+     * If several the instance contains several objects, the method is invoked
+     * on every objects.
+     * @return the result of the invocation, <code>null</code> for <code>void</code>
+     * method, the last result for multi-object instance
+     * @throws NoSuchMethodException if Method is not found in the class
+     * @throws InvocationTargetException if the method throws an exception
+     * @throws IllegalAccessException if the method can not be invoked
+     */
+    public Object call() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        return call(new Object[0]);
+    }
+
+    /**
+     * Invokes the method without arguments.
+     * The method is invokes on the specified object.
+     * @param instance the instance on which call the callback
+     * @return the result of the invocation, <code>null</code> for
+     * <code>void</code> method
+     * @throws NoSuchMethodException if the method was not found
+     * @throws IllegalAccessException if the method cannot be called
+     * @throws InvocationTargetException if an error happens in the method
+     */
+    public Object call(Object instance) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        return call(instance, new Object[0]);
+    }
+
+    /**
+     * Invokes the method on every created objects with the specified
+     * arguments.
+     * @param arg the method arguments
+     * @return the result of the invocation, <code>null</code> for
+     * <code>void</code> method, the last result for instance containing
+     * several objects.
+     * @throws NoSuchMethodException if the callback method is not found
+     * @throws IllegalAccessException if the callback method cannot be called
+     * @throws InvocationTargetException if an error is thrown by the called method
+     */
+    public Object call(Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        if (m_methodObj == null) {
+            searchMethod();
+        }
+
+        if (m_isStatic) {
+            return m_methodObj.invoke(null, arg);
+        } else {
+            // Two cases :
+            // - if instances already exists : call on each instances
+            // - if no instance exists : create an instance
+            if (m_manager.getPojoObjects() == null) {
+                return  m_methodObj.invoke(m_manager.getPojoObject(), arg);
+            } else {
+                Object newObject = null;
+                for (int i = 0; i < m_manager.getPojoObjects().length; i++) {
+                    newObject = m_methodObj.invoke(m_manager.getPojoObjects()[i], arg);
+                }
+                return newObject;
+            }
+        }
+    }
+
+    /**
+     * Invokes the method on the given object with the specified
+     * arguments.
+     * @param instance the instance on which call the method
+     * @param arg the argument array
+     * @return the result of the invocation, <code>null</code> for
+     * <code>void</code> method
+     * @throws NoSuchMethodException if the callback method is not found
+     * @throws IllegalAccessException if the callback method cannot be called
+     * @throws InvocationTargetException if an error is thrown by the called method
+     */
+    public Object call(Object instance, Object[] arg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        if (m_methodObj == null) {
+            searchMethod();
+        }
+
+        return m_methodObj.invoke(instance, arg);
+    }
+
+    /**
+     * Gets the method name.
+     * @return the method name
+     */
+    public String getMethod() {
+        return m_method;
+    }
+
+    /**
+     * Gets the method arguments.
+     * @return the arguments.
+     */
+    public String[] getArguments() {
+    	return m_args;
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
new file mode 100644
index 0000000..52c11c2
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyModel.java
@@ -0,0 +1,1007 @@
+/*
+ * 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.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.IPOJOServiceFactory;
+import org.apache.felix.ipojo.context.ServiceReferenceImpl;
+import org.apache.felix.ipojo.metadata.Element;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Abstract dependency model.
+ * This class is the parent class of every service dependency. It manages the most
+ * part of dependency management. This class creates an interface between the service
+ * tracker and the concrete dependency.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public abstract class DependencyModel implements TrackerCustomizer {
+
+    /**
+     * Dependency state : BROKEN.
+     * A broken dependency cannot be fulfilled anymore. The dependency becomes
+     * broken when a used service disappears in the static binding policy.
+     */
+    public static final int BROKEN = -1;
+
+    /**
+     * Dependency state : UNRESOLVED.
+     * A dependency is unresolved if the dependency is not valid and no service
+     * providers are available.
+     */
+    public static final int UNRESOLVED = 0;
+
+    /**
+     * Dependency state : RESOLVED.
+     * A dependency is resolved if the dependency is optional or at least one
+     * provider is available.
+     */
+    public static final int RESOLVED = 1;
+
+    /**
+     * Binding policy : Dynamic.
+     * In this policy, services can appears and departs without special treatment.
+     */
+    public static final int DYNAMIC_BINDING_POLICY = 0;
+
+    /**
+     * Binding policy : Static.
+     * Once a service is used, if this service disappears the dependency becomes
+     * {@link DependencyModel#BROKEN}. The instance needs to be recreated.
+     */
+    public static final int STATIC_BINDING_POLICY = 1;
+
+    /**
+     * Binding policy : Dynamic-Priority.
+     * In this policy, services can appears and departs. However, once a service
+     * with a highest ranking (according to the used comparator) appears, this
+     * new service is re-injected.
+     */
+    public static final int DYNAMIC_PRIORITY_BINDING_POLICY = 2;
+
+    /**
+     * Does the dependency bind several providers ?
+     */
+    private boolean m_aggregate;
+
+    /**
+     * Is the dependency optional ?
+     */
+    private boolean m_optional;
+
+    /**
+     * The required specification.
+     * Cannot change once set.
+     */
+    private Class m_specification;
+
+    /**
+     * The comparator to sort service references.
+     */
+    private Comparator m_comparator;
+
+    /**
+     * The LDAP filter object selecting service references
+     * from the set of providers providing the required specification.
+     */
+    private Filter m_filter;
+
+    /**
+     * Bundle context used by the dependency.
+     * (may be a {@link ServiceContext}).
+     */
+    private BundleContext m_context;
+
+    /**
+     * Listener object on which invoking the {@link DependencyStateListener#validate(DependencyModel)}
+     * and {@link DependencyStateListener#invalidate(DependencyModel)} methods.
+     */
+    private final DependencyStateListener m_listener;
+
+    /**
+     * The actual state of the dependency.
+     * {@link DependencyModel#UNRESOLVED} at the beginning.
+     */
+    private int m_state;
+
+    /**
+     * The Binding policy of the dependency.
+     */
+    private int m_policy = DYNAMIC_BINDING_POLICY;
+
+    /**
+     * The tracker used by this dependency to track providers.
+     */
+    private Tracker m_tracker;
+
+    /**
+     * The list of matching service references. This list is a
+     * subset of tracked references. This set is computed according
+     * to the filter and the {@link DependencyModel#match(ServiceReference)} method.
+     */
+    private final List m_matchingRefs = new ArrayList();
+
+    /**
+     * The instance requiring the service.
+     */
+    private final ComponentInstance m_instance;
+
+    /**
+     * Map {@link ServiceReference} -> Service Object.
+     * This map stores service object, and so is able to handle
+     * iPOJO custom policies.
+     */
+    private Map/*<ServiceReference, Object>*/ m_serviceObjects = new HashMap();
+
+    /**
+     * Creates a DependencyModel.
+     * If the dependency has no comparator and follows the
+     * {@link DependencyModel#DYNAMIC_PRIORITY_BINDING_POLICY} policy
+     * the OSGi Service Reference Comparator is used.
+     * @param specification the required specification
+     * @param aggregate is the dependency aggregate ?
+     * @param optional is the dependency optional ?
+     * @param filter the LDAP filter
+     * @param comparator the comparator object to sort references
+     * @param policy the binding policy
+     * @param context the bundle context (or service context)
+     * @param listener the dependency lifecycle listener to notify from dependency
+     * @param ci instance managing the dependency
+     * state changes.
+     */
+    public DependencyModel(Class specification, boolean aggregate, boolean optional, Filter filter, Comparator comparator, int policy,
+            BundleContext context, DependencyStateListener listener, ComponentInstance ci) {
+        m_specification = specification;
+        m_aggregate = aggregate;
+        m_optional = optional;
+        m_filter = filter;
+        m_comparator = comparator;
+        m_context = context;
+        m_policy = policy;
+        // If the dynamic priority policy is chosen, and we have no comparator, fix it to OSGi standard service reference comparator.
+        if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY && m_comparator == null) {
+            m_comparator = new ServiceReferenceRankingComparator();
+        }
+        m_state = UNRESOLVED;
+        m_listener = listener;
+        m_instance = ci;
+    }
+
+    /**
+     * Opens the tracking.
+     * This method computes the dependency state
+     * @see DependencyModel#computeDependencyState()
+     */
+    public void start() {
+        m_state = UNRESOLVED;
+        m_tracker = new Tracker(m_context, m_specification.getName(), this);
+        m_tracker.open();
+        computeDependencyState();
+    }
+
+    /**
+     * Closes the tracking.
+     * The dependency becomes {@link DependencyModel#UNRESOLVED}
+     * at the end of this method.
+     */
+    public void stop() {
+        if (m_tracker != null) {
+            m_tracker.close();
+            m_tracker = null;
+        }
+        m_matchingRefs.clear();
+        ungetAllServices();
+        m_state = UNRESOLVED;
+    }
+
+    /**
+     * Ungets all 'get' service references.
+     * This also clears the service object map.
+     */
+    private void ungetAllServices() {
+        Set entries = m_serviceObjects.entrySet();
+        Iterator it = entries.iterator();
+        while (it.hasNext()) {
+            Map.Entry entry = (Map.Entry) it.next();
+            ServiceReference ref = (ServiceReference) entry.getKey();
+            Object svc = entry.getValue();
+            if (m_tracker != null) {
+                m_tracker.ungetService(ref);
+            }
+            if (svc instanceof IPOJOServiceFactory) {
+                ((IPOJOServiceFactory) svc).ungetService(m_instance, svc);
+            }
+        }
+        m_serviceObjects.clear();
+    }
+
+    /**
+     * Is the reference set frozen (cannot change anymore)?
+     * This method must be override by concrete dependency to support
+     * the static binding policy. In fact, this method allows optimizing
+     * the static dependencies to become frozen only when needed.
+     * This method returns <code>false</code> by default.
+     * The method must always return <code>false</code> for non-static dependencies.
+     * @return <code>true</code> if the reference set is frozen.
+     */
+    public boolean isFrozen() {
+        return false;
+    }
+
+
+    /**
+     * Unfreezes the dependency.
+     * This method must be overide by concrete dependency to support
+     * the static binding policy. This method is called after tracking restarting.
+     */
+    public void unfreeze() {
+        // nothing to do
+    }
+
+    /**
+     * Does the service reference match ? This method must be override by
+     * concrete dependencies if they need advanced testing on service reference
+     * (that cannot be expressed in the LDAP filter). By default this method
+     * returns <code>true</code>.
+     * @param ref the tested reference.
+     * @return <code>true</code> if the service reference matches.
+     */
+    public boolean match(ServiceReference ref) {
+        return true;
+    }
+
+    /**
+     * Computes the actual dependency state.
+     * This methods invokes the {@link DependencyStateListener}.
+     */
+    private void computeDependencyState() {
+        if (m_state == BROKEN) { return; } // The dependency is broken ...
+
+        boolean mustCallValidate = false;
+        boolean mustCallInvalidate = false;
+        synchronized (this) {
+            if (m_optional || !m_matchingRefs.isEmpty()) {
+                // The dependency is valid
+                if (m_state == UNRESOLVED) {
+                    m_state = RESOLVED;
+                    mustCallValidate = true;
+                }
+            } else {
+                // The dependency is invalid
+                if (m_state == RESOLVED) {
+                    m_state = UNRESOLVED;
+                    mustCallInvalidate = true;
+                }
+            }
+        }
+
+        // Invoke callback in a non-synchronized region
+        if (mustCallInvalidate) {
+            invalidate();
+        } else if (mustCallValidate) {
+            validate();
+        }
+
+    }
+
+    /**
+     * Service tracker adding service callback.
+     * It accepts the service only if the dependency isn't broken or frozen.
+     * @param ref the arriving service reference.
+     * @return <code>true</code> if the reference must be tracked.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
+     */
+    public boolean addingService(ServiceReference ref) {
+        return !((m_state == BROKEN) || isFrozen());
+    }
+
+    /**
+     * Service Tracker added service callback.
+     * If the service matches (against the filter and the {@link DependencyModel#match(ServiceReference)},
+     * manages the provider arrival.
+     * @param ref : new references.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public void addedService(ServiceReference ref) {
+        if (matchAgainstFilter(ref) && match(ref)) {
+            manageArrival(ref);
+        }
+        // Do not store the service if it doesn't match.
+    }
+
+    /**
+     * Checks if the given service reference match the current filter.
+     * This method aims to avoid calling {@link Filter#match(ServiceReference)}
+     * method when manipulating a composite reference. In fact, this method thrown
+     * a {@link ClassCastException} on Equinox.
+     * @param ref the service reference to check.
+     * @return <code>true</code> if the service reference matches.
+     */
+    private boolean matchAgainstFilter(ServiceReference ref) {
+        boolean match = true;
+        if (m_filter != null) {
+            if (ref instanceof ServiceReferenceImpl) {
+                // Can't use the match(ref) as it throw a class cast exception on Equinox.
+                match = m_filter.match(((ServiceReferenceImpl) ref).getProperties());
+            } else { // Non composite reference.
+                match = m_filter.match(ref);
+            }
+        }
+        return match;
+    }
+
+    /**
+     * Manages the arrival of a new service reference.
+     * The reference is valid and matches the filter and the {@link DependencyModel#match(ServiceReference)}
+     * method. This method has different behavior according to the binding policy.
+     * @param ref the new reference
+     */
+    private void manageArrival(ServiceReference ref) {
+        // Create a local copy of the state and of the list size.
+        int state = m_state;
+        int size;
+
+        synchronized (this) {
+            m_matchingRefs.add(ref);
+
+            // Sort the collection if needed, if not sort, services are append to the list.
+            if (m_comparator != null) {
+                // The collection must be sort only if:
+                // The policy is dynamic-priority
+                // No services are already used
+                // If so, sorting can imply a re-binding, and so don't follow the Dynamic Binding policy
+                if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY
+                       || m_tracker.getUsedServiceReferences() == null
+                       || m_tracker.getUsedServiceReferences().isEmpty()) {
+                    Collections.sort(m_matchingRefs, m_comparator);
+                }
+            }
+
+            size = m_matchingRefs.size();
+        }
+
+        if (m_aggregate) {
+            onServiceArrival(ref); // Always notify the arrival for aggregate dependencies.
+            if (state == UNRESOLVED) { // If we was unresolved, try to validate the dependency.
+                computeDependencyState();
+            }
+        } else { // We are not aggregate.
+            if (size == 1) {
+                onServiceArrival(ref); // It is the first service, so notify.
+                computeDependencyState();
+            } else {
+                // In the case of a dynamic priority binding, we have to test if we have to update the bound reference
+                if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY && m_matchingRefs.get(0) == ref) {
+                    // We are sure that we have at least two references, so if the highest ranked references (first one) is the new received
+                    // references,
+                    // we have to unbind the used one and to bind the the new one.
+                    onServiceDeparture((ServiceReference) m_matchingRefs.get(1));
+                    onServiceArrival(ref);
+                }
+            }
+        }
+        // Ignore others cases
+    }
+
+    /**
+     * Service tracker removed service callback.
+     * A service provider goes away. The depart needs to be managed only if the
+     * reference was used.
+     * @param ref the leaving service reference
+     * @param arg1 the service object if the service was already get
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void removedService(ServiceReference ref, Object arg1) {
+        if (m_matchingRefs.contains(ref)) {
+            manageDeparture(ref, arg1);
+        }
+    }
+
+    /**
+     * Manages the departure of a used service.
+     * @param ref the leaving service reference
+     * @param obj the service object if the service was get
+     */
+    private void manageDeparture(ServiceReference ref, Object obj) {
+        // Unget the service reference
+        ungetService(ref);
+
+        // If we already get this service and the binding policy is static, the dependency becomes broken
+        if (isFrozen() && obj != null) {
+            if (m_state != BROKEN) {
+                m_state = BROKEN;
+                invalidate();  // This will invalidate the instance.
+                // Reinitialize the dependency tracking
+                ComponentInstance instance = null;
+                synchronized (this) {
+                    instance = m_instance;
+                }
+                instance.stop(); // Stop the instance
+                unfreeze();
+                instance.start();
+            }
+        } else {
+            synchronized (this) {
+                m_matchingRefs.remove(ref);
+            }
+            if (obj == null) {
+                computeDependencyState(); // check if the dependency stills valid.
+            } else {
+                // A used service disappears, we have to sort the available providers to choose the best one.
+                // However, the sort has to be done only for scalar dependencies following the dynamic binding
+                // policy. Static dependencies will be broken, DP dependencies are always sorted.
+                // Aggregate dependencies does not need to be sort, as it will change the array
+                // order.
+                if (m_comparator != null && m_policy == DYNAMIC_BINDING_POLICY && ! m_aggregate) {
+                    Collections.sort(m_matchingRefs, m_comparator);
+                }
+                onServiceDeparture(ref);
+                ServiceReference newRef = getServiceReference();
+                if (newRef == null) { // Check if there is another provider.
+                    computeDependencyState(); // no more references.
+                } else {
+                    if (!m_aggregate) {
+                        onServiceArrival(newRef); // Injecting the new service reference for non aggregate dependencies.
+                    }
+                }
+            }
+        }
+
+    }
+
+    /**
+     * Service tracker modified service callback.
+     * This method must handle if the modified service should be considered as
+     * a depart or an arrival.
+     * According to the dependency filter, a service can now match or can no match
+     * anymore.
+     * @param ref the modified reference
+     * @param arg1 the service object if already get.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
+     */
+    public void modifiedService(ServiceReference ref, Object arg1) {
+        if (m_matchingRefs.contains(ref)) {
+            // It's a used service. Check if the service always match.
+            if (!matchAgainstFilter(ref) && match(ref)) {
+                // The service does not match anymore. Call removedService.
+                manageDeparture(ref, arg1);
+            } else {
+                manageModification(ref);
+            }
+        } else {
+            // The service was not used. Check if it matches.
+            if (matchAgainstFilter(ref) && match(ref)) {
+                manageArrival(ref);
+            }
+            // Else, the service does not match.
+        }
+    }
+
+    /**
+     * Gets the next matching service reference.
+     * @return <code>null</code> if no more provider is available,
+     * else returns the first reference from the matching set.
+     */
+    public ServiceReference getServiceReference() {
+        synchronized (this) {
+            if (m_matchingRefs.isEmpty()) {
+                return null;
+            } else {
+                return (ServiceReference) m_matchingRefs.get(0);
+            }
+        }
+    }
+
+    /**
+     * Gets matching service references.
+     * @return the sorted (if a comparator is used) array of matching service
+     * references, <code>null</code> if no references are available.
+     */
+    public ServiceReference[] getServiceReferences() {
+        synchronized (this) {
+            if (m_matchingRefs.isEmpty()) { return null; }
+            // TODO Consider sorting the array (on a copy of matching ref) if dynamic priority used.
+            return (ServiceReference[]) m_matchingRefs.toArray(new ServiceReference[m_matchingRefs.size()]);
+        }
+    }
+
+    /**
+     * Gets the list of currently used service references.
+     * If no service references, returns <code>null</code>
+     * @return the list of used reference (according to the service tracker).
+     */
+    public List getUsedServiceReferences() {
+        synchronized (this) {
+            // The list must confront actual matching services with already get services from the tracker.
+
+            int size = m_matchingRefs.size();
+            List usedByTracker = null;
+            if (m_tracker != null) {
+                usedByTracker = m_tracker.getUsedServiceReferences();
+            }
+            if (size == 0 || usedByTracker == null) { return null; }
+
+            List list = new ArrayList(1);
+            for (int i = 0; i < size; i++) {
+                if (usedByTracker.contains(m_matchingRefs.get(i))) {
+                    list.add(m_matchingRefs.get(i)); // Add the service in the list.
+                    if (!isAggregate()) { // IF we are not multiple, return the list when the first element is found.
+                        return list;
+                    }
+                }
+            }
+
+            return list;
+        }
+    }
+
+    /**
+     * Gets the number of actual matching references.
+     * @return the number of matching references
+     */
+    public int getSize() {
+        return m_matchingRefs.size();
+    }
+
+    /**
+     * Concrete dependency callback.
+     * This method is called when a new service needs to be
+     * re-injected in the underlying concrete dependency.
+     * @param ref the service reference to inject.
+     */
+    public abstract void onServiceArrival(ServiceReference ref);
+
+    /**
+     * Concrete dependency callback.
+     * This method is called when a used service (already injected) is leaving.
+     * @param ref the leaving service reference.
+     */
+    public abstract void onServiceDeparture(ServiceReference ref);
+
+    /**
+     * Concrete dependency callback.
+     * This method is called when a used service (already injected) is modified.
+     * @param ref the modified service reference.
+     */
+    public abstract void onServiceModification(ServiceReference ref);
+
+    /**
+     * This method can be override by the concrete dependency to be notified
+     * of service modification.
+     * This modification is not an arrival or a departure.
+     * @param ref the modified service reference.
+     */
+    public void manageModification(ServiceReference ref) {
+        if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY) {
+            // Check that the order has changed or not.
+            int indexBefore = m_matchingRefs.indexOf(ref);
+            Collections.sort(m_matchingRefs, m_comparator);
+            if (indexBefore != m_matchingRefs.indexOf(ref) && ! m_aggregate) {
+                // The order has changed during the sort.
+                onServiceDeparture((ServiceReference) m_matchingRefs.get(1));
+                onServiceArrival(ref);
+            }
+
+        } else {
+            // It's a modification...
+            onServiceModification(ref);
+        }
+    }
+
+    /**
+     * Concrete dependency callback.
+     * This method is called when the dependency is reconfigured and when this
+     * reconfiguration implies changes on the matching service set ( and by the
+     * way on the injected service).
+     * @param departs the service leaving the matching set.
+     * @param arrivals the service arriving in the matching set.
+     */
+    public abstract void onDependencyReconfiguration(ServiceReference[] departs, ServiceReference[] arrivals);
+
+    /**
+     * Calls the listener callback to notify the new state of the current
+     * dependency.
+     */
+    private void invalidate() {
+        m_listener.invalidate(this);
+    }
+
+    /**
+     * Calls the listener callback to notify the new state of the current
+     * dependency.
+     */
+    private void validate() {
+        m_listener.validate(this);
+    }
+
+    /**
+     * Gets the actual state of the dependency.
+     * @return the state of the dependency.
+     */
+    public int getState() {
+        return m_state;
+    }
+
+    /**
+     * Gets the tracked specification.
+     * @return the Class object tracked by the dependency.
+     */
+    public Class getSpecification() {
+        return m_specification;
+    }
+
+    /**
+     * Sets the required specification of this service dependency.
+     * This operation is not supported if the dependency tracking has already begun.
+     * @param specification the required specification.
+     */
+    public void setSpecification(Class specification) {
+        if (m_tracker == null) {
+            m_specification = specification;
+        } else {
+            throw new UnsupportedOperationException("Dynamic specification change is not yet supported");
+        }
+    }
+
+    /**
+     * Sets the filter of the dependency. This method recomputes the
+     * matching set and call the onDependencyReconfiguration callback.
+     * @param filter the new LDAP filter.
+     */
+    public void setFilter(Filter filter) { //NOPMD
+        m_filter = filter;
+        if (m_tracker != null) { // Tracking started ...
+            List toRemove = new ArrayList();
+            List toAdd = new ArrayList();
+            ServiceReference usedRef = null;
+            synchronized (this) {
+
+                // Store the used service references.
+                if (!m_aggregate && !m_matchingRefs.isEmpty()) {
+                    usedRef = (ServiceReference) m_matchingRefs.get(0);
+                }
+
+                // Get actually all tracked references.
+                ServiceReference[] refs = m_tracker.getServiceReferences();
+
+                if (refs == null) {
+                    for (int j = 0; j < m_matchingRefs.size(); j++) {
+                        // All references need to be removed.
+                        toRemove.add(m_matchingRefs.get(j));
+                    }
+                    // No more matching dependency. Clear the matching reference set.
+                    m_matchingRefs.clear();
+                } else {
+                    // Compute matching services.
+                    List matching = new ArrayList();
+                    for (int i = 0; i < refs.length; i++) {
+                        if (matchAgainstFilter(refs[i]) && match(refs[i])) {
+                            matching.add(refs[i]);
+                        }
+                    }
+                    // Now compare with used services.
+                    for (int j = 0; j < m_matchingRefs.size(); j++) {
+                        ServiceReference ref = (ServiceReference) m_matchingRefs.get(j);
+                        // Check if the reference is inside the matching list:
+                        if (!matching.contains(ref)) {
+                            // The reference should be removed
+                            toRemove.add(ref);
+                        }
+                    }
+
+                    // Then remove services which do no more match.
+                    m_matchingRefs.removeAll(toRemove);
+
+                    // Then, add new matching services.
+
+                    for (int k = 0; k < matching.size(); k++) {
+                        if (!m_matchingRefs.contains(matching.get(k))) {
+                            m_matchingRefs.add(matching.get(k));
+                            toAdd.add(matching.get(k));
+                        }
+                    }
+
+                    // Sort the collections if needed.
+                    if (m_comparator != null) {
+                        Collections.sort(m_matchingRefs, m_comparator);
+                        Collections.sort(toAdd, m_comparator);
+                        Collections.sort(toRemove, m_comparator);
+                    }
+
+                }
+            }
+
+            // Call the callback outside the sync bloc.
+            if (m_aggregate) {
+                ServiceReference[] rem = null;
+                ServiceReference[] add = null;
+                if (!toAdd.isEmpty()) {
+                    add = (ServiceReference[]) toAdd.toArray(new ServiceReference[toAdd.size()]);
+                }
+                if (!toRemove.isEmpty()) {
+                    rem = (ServiceReference[]) toRemove.toArray(new ServiceReference[toRemove.size()]);
+                }
+                if (rem != null || add != null) { // Notify the change only when a change is made on the matching reference list.
+                    onDependencyReconfiguration(rem, add);
+                }
+            } else {
+                // Create a local copy to avoid un-sync reference list access.
+                int size;
+                ServiceReference newRef = null;
+                synchronized (m_matchingRefs) {
+                    size = m_matchingRefs.size();
+                    if (size > 0) {
+                        newRef = (ServiceReference) m_matchingRefs.get(0);
+                    }
+                }
+                // Non aggregate case.
+                // If the used reference was not null
+                if (usedRef == null) {
+                    // The used ref was null,
+                    if (size > 0) {
+                        onDependencyReconfiguration(null, new ServiceReference[] { newRef });
+                    } // Don't notify the change, if the set is not touched by the reconfiguration.
+                } else {
+                    // If the used ref disappears, inject a new service if available, else reinject null.
+                    if (toRemove.contains(usedRef)) {
+                        // We have to replace the service.
+                        if (size > 0) {
+                            onDependencyReconfiguration(new ServiceReference[] { usedRef }, new ServiceReference[] { newRef });
+                        } else {
+                            onDependencyReconfiguration(new ServiceReference[] { usedRef }, null);
+                        }
+                    } else if (m_policy == DYNAMIC_PRIORITY_BINDING_POLICY && newRef != usedRef) { //NOPMD
+                        // In the case of dynamic-priority, check if the used ref is no more the highest reference
+                        onDependencyReconfiguration(new ServiceReference[] { usedRef }, new ServiceReference[] { newRef });
+                    }
+                }
+            }
+            // Now, compute the new dependency state.
+            computeDependencyState();
+        }
+    }
+
+    /**
+     * Returns the dependency filter (String form).
+     * @return the String form of the LDAP filter used by this dependency,
+     * <code>null</code> if not set.
+     */
+    public String getFilter() {
+        if (m_filter == null) {
+            return null;
+        } else {
+            return m_filter.toString();
+        }
+    }
+
+    /**
+     * Sets the aggregate attribute of the current dependency.
+     * If the tracking is opened, it will call arrival and departure callbacks.
+     * @param isAggregate the new aggregate attribute value.
+     */
+    public synchronized void setAggregate(boolean isAggregate) {
+        if (m_tracker == null) { // Not started ...
+            m_aggregate = isAggregate;
+        } else {
+            // We become aggregate.
+            if (!m_aggregate && isAggregate) {
+                m_aggregate = true;
+                // Call the callback on all non already injected service.
+                if (m_state == RESOLVED) {
+
+                    for (int i = 1; i < m_matchingRefs.size(); i++) { // The loop begin at 1, as the 0 is already injected.
+                        onServiceArrival((ServiceReference) m_matchingRefs.get(i));
+                    }
+                }
+            } else if (m_aggregate && !isAggregate) {
+                m_aggregate = false;
+                // We become non-aggregate.
+                if (m_state == RESOLVED) {
+                    for (int i = 1; i < m_matchingRefs.size(); i++) { // The loop begin at 1, as the 0 stills injected.
+                        onServiceDeparture((ServiceReference) m_matchingRefs.get(i));
+                    }
+                }
+            }
+            // Else, do nothing.
+        }
+    }
+
+    public synchronized boolean isAggregate() {
+        return m_aggregate;
+    }
+
+    /**
+     * Sets the optionality attribute of the current dependency.
+     * @param isOptional the new optional attribute value.
+     */
+    public void setOptionality(boolean isOptional) {
+        if (m_tracker == null) { // Not started ...
+            m_optional = isOptional;
+        } else {
+            computeDependencyState();
+        }
+    }
+
+    public boolean isOptional() {
+        return m_optional;
+    }
+
+    /**
+     * Gets the used binding policy.
+     * @return the current binding policy.
+     */
+    public int getBindingPolicy() {
+        return m_policy;
+    }
+
+    /**
+     * Sets the binding policy.
+     * Not yet supported.
+     */
+    public void setBindingPolicy() {
+        throw new UnsupportedOperationException("Binding Policy change is not yet supported");
+        // TODO supporting dynamic policy change.
+    }
+
+    public void setComparator(Comparator cmp) {
+        m_comparator = cmp;
+        // NOTE: the array will be sorted at the next get.
+    }
+
+    /**
+     * Gets the used comparator name.
+     * <code>Null</code> if no comparator (i.e. the OSGi one is used).
+     * @return the comparator class name or <code>null</code> if the dependency doesn't use a comparator.
+     */
+    public synchronized String getComparator() {
+        if (m_comparator != null) {
+            return m_comparator.getClass().getName();
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Sets the bundle context used by this dependency.
+     * This operation is not supported if the tracker is already opened.
+     * @param context the bundle context or service context to use
+     */
+    public void setBundleContext(BundleContext context) {
+        if (m_tracker == null) { // Not started ...
+            m_context = context;
+        } else {
+            throw new UnsupportedOperationException("Dynamic bundle (i.e. service) context change is not supported");
+        }
+    }
+
+    /**
+     * Gets a service object for the given reference.
+     * @param ref the wanted service reference
+     * @return the service object attached to the given reference
+     */
+    public Object getService(ServiceReference ref) {
+        Object svc =  m_tracker.getService(ref);
+        if (svc instanceof IPOJOServiceFactory) {
+            Object obj =  ((IPOJOServiceFactory) svc).getService(m_instance);
+            m_serviceObjects.put(ref, svc); // We store the factory !
+            return obj;
+        } else {
+            m_serviceObjects.put(ref, svc);
+            return svc;
+        }
+    }
+
+    /**
+     * Ungets a used service reference.
+     * @param ref the reference to unget.
+     */
+    public void ungetService(ServiceReference ref) {
+        m_tracker.ungetService(ref);
+        Object obj = m_serviceObjects.remove(ref);  // Remove the service object
+        if (obj != null  && obj instanceof IPOJOServiceFactory) {
+            ((IPOJOServiceFactory) obj).ungetService(m_instance, obj);
+        }
+    }
+
+    /**
+     * Helper method parsing the comparator attribute and returning the
+     * comparator object. If the 'comparator' attribute is not set, this method
+     * returns null. If the 'comparator' attribute is set to 'osgi', this method
+     * returns the normal OSGi comparator. In other case, it tries to create
+     * an instance of the declared comparator class.
+     * @param dep the Element describing the dependency
+     * @param context the bundle context (to load the comparator class)
+     * @return the comparator object, <code>null</code> if not set.
+     * @throws ConfigurationException the comparator class cannot be load or the
+     * comparator cannot be instantiated correctly.
+     */
+    public static Comparator getComparator(Element dep, BundleContext context) throws ConfigurationException {
+        Comparator cmp = null;
+        String comp = dep.getAttribute("comparator");
+        if (comp != null) {
+            if (comp.equalsIgnoreCase("osgi")) {
+                cmp = new ServiceReferenceRankingComparator();
+            } else {
+                try {
+                    Class cla = context.getBundle().loadClass(comp);
+                    cmp = (Comparator) cla.newInstance();
+                } catch (ClassNotFoundException e) {
+                    throw new ConfigurationException("Cannot load a customized comparator : " + e.getMessage());
+                } catch (IllegalAccessException e) {
+                    throw new ConfigurationException("Cannot create a customized comparator : " + e.getMessage());
+                } catch (InstantiationException e) {
+                    throw new ConfigurationException("Cannot create a customized comparator : " + e.getMessage());
+                }
+            }
+        }
+        return cmp;
+    }
+
+    /**
+     * Loads the given specification class.
+     * @param specification the specification class name to load
+     * @param context the bundle context
+     * @return the class object for the given specification
+     * @throws ConfigurationException if the class cannot be loaded correctly.
+     */
+    public static Class loadSpecification(String specification, BundleContext context) throws ConfigurationException {
+        Class spec = null;
+        try {
+            spec = context.getBundle().loadClass(specification);
+        } catch (ClassNotFoundException e) {
+            throw new ConfigurationException("A required specification cannot be loaded : " + specification);
+        }
+        return spec;
+    }
+
+    /**
+     * Helper method parsing the binding policy.
+     * If the 'policy' attribute is not set in the dependency, the method returns
+     * the 'DYNAMIC BINDING POLICY'. Accepted policy values are : dynamic,
+     * dynamic-priority and static.
+     * @param dep the Element describing the dependency
+     * @return the policy attached to this dependency
+     * @throws ConfigurationException if an unknown binding policy was described.
+     */
+    public static int getPolicy(Element dep) throws ConfigurationException {
+        String policy = dep.getAttribute("policy");
+        if (policy == null || policy.equalsIgnoreCase("dynamic")) {
+            return DYNAMIC_BINDING_POLICY;
+        } else if (policy.equalsIgnoreCase("dynamic-priority")) {
+            return DYNAMIC_PRIORITY_BINDING_POLICY;
+        } else if (policy.equalsIgnoreCase("static")) {
+            return STATIC_BINDING_POLICY;
+        } else {
+            throw new ConfigurationException("Binding policy unknown : " + policy);
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyStateListener.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyStateListener.java
new file mode 100644
index 0000000..a72409b
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/DependencyStateListener.java
@@ -0,0 +1,39 @@
+/* 
+ * 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.util;
+
+
+/**
+ * This interface allows a class to be notified of service dependency state changes.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface DependencyStateListener {
+
+    /**
+     * The given dependency becomes valid.
+     * @param dependency the dependency becoming valid.
+     */
+    void validate(DependencyModel dependency);
+    
+    /**
+     * The given dependency becomes invalid.
+     * @param dependency the dependency becoming invalid.
+     */
+    void invalidate(DependencyModel dependency);
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Logger.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Logger.java
new file mode 100644
index 0000000..e28009b
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Logger.java
@@ -0,0 +1,383 @@
+/*
+ * 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.util;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ErrorHandler;
+import org.apache.felix.ipojo.Extender;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogService;
+
+/**
+ * iPOJO Logger.
+ * This class is an helper class implementing a simple log system.
+ * This logger sends log messages to a log service if available.
+ *
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Logger {
+
+    /**
+     * The iPOJO default log level property.
+     */
+    public static final String IPOJO_LOG_LEVEL_PROP = "ipojo.log.level";
+
+    /**
+     * iPOJO log level manifest header.
+     * The uppercase 'I' is important as BND removes all headers that do not
+     * start with an uppercase are not added to the bundle.
+     * Use an upper case to support bnd.
+     */
+    public static final String IPOJO_LOG_LEVEL_HEADER = "Ipojo-log-level";
+
+    /**
+     * The Log Level ERROR.
+     */
+    public static final int ERROR = 1;
+
+    /**
+     * The Log Level WARNING.
+     */
+    public static final int WARNING = 2;
+
+    /**
+     * The Log Level INFO.
+     */
+    public static final int INFO = 3;
+
+    /**
+     * The Log Level DEBUG.
+     */
+    public static final int DEBUG = 4;
+
+    /**
+     * The Bundle Context used to get the
+     * log service.
+     */
+    private BundleContext m_context;
+
+    /**
+     * The name of the logger.
+     */
+    private String m_name;
+
+    /**
+     * The instance associated to the logger if any.
+     */
+    private ComponentInstance m_instance;
+
+    /**
+     * The trace level of this logger.
+     */
+    private int m_level;
+
+    /**
+     * Creates a logger.
+     * @param context the bundle context
+     * @param name the name of the logger
+     * @param level the trace level
+     */
+    public Logger(BundleContext context, String name, int level) {
+        m_name = name;
+        m_level = level;
+        m_context = context;
+    }
+
+    /**
+     * Creates a logger.
+     * @param context the bundle context
+     * @param instance the instance
+     * @param level the trace level
+     */
+    public Logger(BundleContext context, ComponentInstance instance, int level) {
+        m_instance = instance;
+        m_name = m_instance.getInstanceName();
+        m_level = level;
+        m_context = context;
+    }
+
+    /**
+     * Create a logger.
+     * Uses the default logger level.
+     * @param context the bundle context
+     * @param name the name of the logger
+     */
+    public Logger(BundleContext context, String name) {
+        this(context, name, getDefaultLevel(context));
+    }
+
+    /**
+     * Create a logger.
+     * Uses the default logger level.
+     * @param context the bundle context
+     * @param instance the instance
+     */
+    public Logger(BundleContext context, ComponentInstance instance) {
+        this(context, instance, getDefaultLevel(context));
+    }
+
+    /**
+     * Logs a message.
+     * @param level the level of the message
+     * @param msg the the message to log
+     */
+    public void log(int level, String msg) {
+        if (m_level >= level) {
+            dispatch(level, msg);
+        }
+        invokeErrorHandler(level, msg, null);
+    }
+
+    /**
+     * Logs a message with an exception.
+     * @param level the level of the message
+     * @param msg the message to log
+     * @param exception the exception attached to the message
+     */
+    public void log(int level, String msg, Throwable exception) {
+        if (m_level >= level) {
+            dispatch(level, msg, exception);
+        }
+        invokeErrorHandler(level, msg, exception);
+    }
+
+    /**
+     * Internal log method.
+     * @param level the level of the message.
+     * @param msg the message to log
+     */
+    private void dispatch(int level, String msg) {
+        LogService log = null;
+        ServiceReference ref = null;
+        try {
+            // Security Check
+            if (SecurityHelper.hasPermissionToGetService(LogService.class.getName(), m_context)) {
+                ref = m_context.getServiceReference(LogService.class.getName());
+            } else {
+                Extender.getIPOJOBundleContext().getServiceReference(LogService.class.getName());
+            }
+
+            if (ref != null) {
+                log = (LogService) m_context.getService(ref);
+            }
+        } catch (IllegalStateException e) {
+            // Handle the case where the iPOJO bundle is stopping
+        }
+
+        String message = null;
+        String name = m_name;
+        if (name == null) {
+            name = "";
+        }
+
+        switch (level) {
+            case DEBUG:
+                message = "[DEBUG] " + name + " : " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_DEBUG, message);
+                } else {
+                    System.err.println(message);
+                }
+                break;
+            case ERROR:
+                message = "[ERROR] " + name + " : " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_ERROR, message);
+                } else {
+                    System.err.println(message);
+                }
+                break;
+            case INFO:
+                message = "[INFO] " + name + " : " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_INFO, message);
+                } else {
+                    System.err.println(message);
+                }
+                break;
+            case WARNING:
+                message = "[WARNING] " + name + " : " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_WARNING, message);
+                } else {
+                    System.err.println(message);
+                }
+                break;
+            default:
+                message = "[UNKNOWN] " + name + " : " + msg;
+                System.err.println(message);
+                break;
+        }
+
+        if (log != null) {
+            m_context.ungetService(ref);
+        }
+    }
+
+    /**
+     * Internal log method.
+     * @param level the level of the message.
+     * @param msg the message to log
+     * @param exception the exception attached to the message
+     */
+    private void dispatch(int level, String msg, Throwable exception) {
+        LogService log = null;
+        ServiceReference ref = null;
+        try {
+            // Security Check
+            if (SecurityHelper.hasPermissionToGetService(LogService.class.getName(), m_context)) {
+                ref = m_context.getServiceReference(LogService.class.getName());
+            } else {
+                Extender.getIPOJOBundleContext().getServiceReference(LogService.class.getName());
+            }
+
+            if (ref != null) {
+                log = (LogService) m_context.getService(ref);
+            }
+        } catch (IllegalStateException e) {
+            // Handle the case where the iPOJO bundle is stopping
+        }
+
+        String message = null;
+        String name = m_name;
+        if (name == null) {
+            name = "";
+        }
+
+        switch (level) {
+            case DEBUG:
+                message = "[DEBUG] " + name + " : " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_DEBUG, message, exception);
+                } else {
+                    System.err.println(message);
+                    exception.printStackTrace();
+                }
+                break;
+            case ERROR:
+                message = "[ERROR] " + name + " : " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_ERROR, message, exception);
+                } else {
+                    System.err.println(message);
+                    exception.printStackTrace();
+                }
+                break;
+            case INFO:
+                message = "[INFO] " + name + " : " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_INFO, message, exception);
+                } else {
+                    System.err.println(message);
+                    exception.printStackTrace();
+                }
+                break;
+            case WARNING:
+                message = "[WARNING] " + name + " : " + msg;
+                if (log != null) {
+                    log.log(LogService.LOG_WARNING, message, exception);
+                } else {
+                    System.err.println(message);
+                    exception.printStackTrace();
+                }
+                break;
+            default:
+                message = "[UNKNOWN] " + name + " : " + msg;
+                System.err.println(message);
+                exception.printStackTrace();
+                break;
+        }
+
+        if (log != null) {
+            m_context.ungetService(ref);
+        }
+    }
+
+    /**
+     * Invokes the error handler service is present.
+     * @param level the log level
+     * @param msg the message
+     * @param error the error
+     */
+    private void invokeErrorHandler(int level, String msg, Throwable error) {
+        // First check the level
+        if (level > WARNING) {
+            return; // Others levels are not supported.
+        }
+        // Try to get the error handler service
+        try {
+            ServiceReference ref = m_context.getServiceReference(ErrorHandler.class.getName());
+            if (ref != null) {
+                ErrorHandler handler = (ErrorHandler) m_context.getService(ref);
+                if (level == ERROR) {
+                    handler.onError(m_instance, msg, error);
+                } else if (level == WARNING) {
+                    handler.onWarning(m_instance, msg, error);
+                } // The others case are not supported
+                m_context.ungetService(ref);
+                return;
+            } // Else do nothing...
+        } catch (IllegalStateException e) {
+            // Ignore
+            // The iPOJO bundle is stopping.
+        }
+    }
+
+    /**
+     * Gets the default logger level.
+     * The property is searched inside the framework properties,
+     * the system properties, and in the manifest from the given
+     * bundle context. By default, set the level to {@link Logger#WARNING}.
+     * @param context the bundle context.
+     * @return the default log level.
+     */
+    private static int getDefaultLevel(BundleContext context) {
+        // First check in the framework and in the system properties
+        String level = context.getProperty(IPOJO_LOG_LEVEL_PROP);
+
+        // If null, look in the bundle manifest
+        if (level == null) {
+            String key = IPOJO_LOG_LEVEL_PROP.replace('.', '-');
+            level = (String) context.getBundle().getHeaders().get(key);
+        }
+
+        // if still null try the second header
+        if (level == null) {
+            level = (String) context.getBundle().getHeaders().get(IPOJO_LOG_LEVEL_HEADER);
+        }
+
+        if (level != null) {
+            if (level.equalsIgnoreCase("info")) {
+                return INFO;
+            } else if (level.equalsIgnoreCase("debug")) {
+                return DEBUG;
+            } else if (level.equalsIgnoreCase("warning")) {
+                return WARNING;
+            } else if (level.equalsIgnoreCase("error")) {
+                return ERROR;
+            }
+        }
+
+        // Either l is null, either the specified log level was unknown
+        // Set the default to WARNING
+        return WARNING;
+
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Property.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Property.java
new file mode 100644
index 0000000..13e2282
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Property.java
@@ -0,0 +1,683 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.ConstructorInjector;
+import org.apache.felix.ipojo.FieldInterceptor;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.parser.ParseUtils;
+import org.osgi.framework.BundleContext;
+
+/**
+ * Property class managing a managed value.
+ * This class managed the method invocation, field injection
+ * and constructor injection.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Property implements FieldInterceptor, ConstructorInjector {
+
+    /**
+     * Object used for an unvalued property.
+     */
+    public static final Object NO_VALUE = new Object();
+
+    /**
+     * The name of the property (field name if not set).
+     * Cannot change once set.
+     */
+    private final String m_name;
+
+    /**
+     * The field of the property.
+     * Cannot change once set.
+     */
+    private final String m_field;
+
+    /**
+     * The setter method of the property.
+     * Cannot change once set.
+     */
+    private final Callback m_method;
+
+    /**
+     * The index of the parameter in case of
+     * constructor injection.
+     */
+    private int m_index = -1;
+
+    /**
+     * The value of the property.
+     */
+    private Object m_value = NO_VALUE;
+
+    /**
+     * The default value of the property.
+     */
+    private Object m_defaultValue = NO_VALUE;
+
+    /**
+     * Flag tracking is the method was
+     * already called for the current value.
+     */
+    private boolean m_invoked;
+
+    /**
+     * The type of the property.
+     */
+    private final Class m_type;
+
+    /**
+     * The handler object to get the logger.
+     */
+    private final Handler m_handler;
+
+    /**
+     * The instance manager.
+     */
+    private final InstanceManager m_manager;
+
+    /**
+     * Creates a property.
+     * At least the method or the field need
+     * to be specified.
+     * @param name the name of the property (optional)
+     * @param field the name of the field
+     * @param method the method name
+     * @param value the initial value of the property (optional)
+     * @param type the the type of the property
+     * @param manager the instance manager
+     * @param handler the handler object which manage this property.
+     * @throws ConfigurationException if the property value cannot be set.
+     */
+    public Property(String name, String field, String method, String value, String type, InstanceManager manager, Handler handler) throws ConfigurationException {
+        m_handler = handler;
+        m_manager = manager;
+        m_field = field;
+
+        if (name == null) {
+            if (m_field == null) {
+                m_name = method;
+            } else {
+                m_name = field;
+            }
+        } else {
+            m_name = name;
+        }
+
+        m_type = computeType(type, manager.getGlobalContext());
+        if (value != null) {
+            m_value = create(m_type, value);
+            m_defaultValue = m_value;
+        }
+
+        if (method != null) {
+            m_method = new Callback(method, new String[] { m_type.getName() }, false, manager);
+        } else {
+            m_method = null;
+        }
+    }
+
+    /**
+     * Creates a property.
+     * At least the method or the field need
+     * to be specified.
+     * @param name the name of the property (optional)
+     * @param field the name of the field
+     * @param method the method name
+     * @param value the initial value of the property (optional)
+     * @param manager the instance manager
+     * @param handler the handler object which manage this property.
+     * @throws ConfigurationException if the property value cannot be set.
+     */
+    public Property(String name, String field, String method, Object value, InstanceManager manager, Handler handler) throws ConfigurationException {
+        m_handler = handler;
+        m_manager = manager;
+        m_field = field;
+
+        if (value == null) {
+            throw new ConfigurationException("Cannot create properties without a value");
+        }
+
+        if (name == null) {
+            if (m_field == null) {
+                m_name = method;
+            } else {
+                m_name = field;
+            }
+        } else {
+            m_name = name;
+        }
+
+        m_type = value.getClass();
+        m_value = value;
+        m_defaultValue = m_value;
+
+        if (method != null) {
+            m_method = new Callback(method, new String[] { m_type.getName() }, false, manager);
+        } else {
+            m_method = null;
+        }
+    }
+
+    public Property(String name, String field, String method, int index,
+            String value, String type, InstanceManager manager, Handler handler) throws ConfigurationException {
+        this(name, field, method, value, type, manager, handler);
+        m_index = index;
+    }
+
+    /**
+     * Computes and returns the property type according to the given type name.
+     * @param type the the type name
+     * @param context the bundle context (used to load classes)
+     * @return the class of the given type
+     * @throws ConfigurationException if an error occurs when loading the type class for non-primitive types.
+     */
+    public static Class computeType(String type, BundleContext context) throws ConfigurationException {
+        // Array :
+        if (type.endsWith("[]")) {
+            return computeArrayType(type, context);
+        } else {
+            // Syntactic sugar to avoid writing java.lang.String
+            if ("string".equals(type) || "String".equals(type)) {
+                return java.lang.String.class;
+            } else if ("boolean".equals(type)) {
+                return Boolean.TYPE;
+            } else if ("byte".equals(type)) {
+                return Byte.TYPE;
+            } else if ("short".equals(type)) {
+                return  Short.TYPE;
+            } else if ("int".equals(type)) {
+                return Integer.TYPE;
+            } else if ("long".equals(type)) {
+                return Long.TYPE;
+            } else if ("float".equals(type)) {
+                return Float.TYPE;
+            } else if ("double".equals(type)) {
+                return Double.TYPE;
+            } else if ("char".equals(type)) {
+                return Character.TYPE;
+            } else {
+                // Non array, complex type.
+                try {
+                    return context.getBundle().loadClass(type);
+                } catch (ClassNotFoundException e) {
+                    throw new ConfigurationException("Class not found exception in setValue on " + type + " : " + e.getMessage());
+                } catch (SecurityException e) {
+                    throw new ConfigurationException("Security execption in setValue on " + type + " : " + e.getMessage());
+                } catch (IllegalArgumentException e) {
+                    throw new ConfigurationException("Argument issue when calling the constructor of the type " + type);
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the Class object of a type array.
+     * @param type the string descriptor of the type (must end by [] )
+     * @param context the bundle context (used to load classes)
+     * @return the Class object of the given type array.
+     * @throws ConfigurationException if the class cannot be loaded
+     */
+    private static Class computeArrayType(String type, BundleContext context) throws ConfigurationException {
+        // Note: Harmony does't support the type[].class notation.
+        // An empty array has to be created to get the class object.
+        String internalType = type.substring(0, type.length() - 2);
+        if ("string".equals(internalType) || "String".equals(internalType)) {
+            return new String[0].getClass();
+        }
+        if ("boolean".equals(internalType)) {
+            return new boolean[0].getClass();
+        }
+        if ("byte".equals(internalType)) {
+            return new byte[0].getClass();
+        }
+        if ("short".equals(internalType)) {
+            return new short[0].getClass();
+        }
+        if ("int".equals(internalType)) {
+            return new int[0].getClass();
+        }
+        if ("long".equals(internalType)) {
+            return new long[0].getClass();
+        }
+        if ("float".equals(internalType)) {
+            return new float[0].getClass();
+        }
+        if ("double".equals(internalType)) {
+            return new double[0].getClass();
+        }
+        if ("char".equals(internalType)) {
+            return new char[0].getClass();
+        }
+
+        // Complex array type.
+        try {
+            Class clazz = context.getBundle().loadClass(internalType);
+            Object[] object = (Object[]) Array.newInstance(clazz, 0);
+            return object.getClass();
+        } catch (ClassNotFoundException e) {
+            throw new ConfigurationException("Class not found exception in setValue on " + internalType);
+        } catch (SecurityException e) {
+            throw new ConfigurationException("Security Exception in setValue on " + internalType);
+        } catch (IllegalArgumentException e) {
+            throw new ConfigurationException("Argument issue when calling the constructor of the type " + internalType);
+        }
+    }
+
+    public String getName() {
+        return m_name;
+    }
+
+    public String getField() {
+        return m_field;
+    }
+
+    public String getType() {
+        return m_type.getName();
+    }
+
+    /**
+     * Gets the method name,
+     * <code>null</code> if no method.
+     * @return the method name.
+     */
+    public String getMethod() {
+        if (m_method == null) { return null; }
+        return m_method.getMethod();
+    }
+
+    /**
+     * Checks if the property has a method callback.
+     * @return <code>true</code> if the property has a method.
+     */
+    public boolean hasMethod() {
+        return m_method != null;
+    }
+
+    /**
+     * Gets the parameter index.
+     * @return the parameter index or <code>-1</code>
+     * if this property is not injected using constructor
+     * parameter.
+     */
+    public int getParameterIndex() {
+        return m_index;
+    }
+
+    /**
+     * Checks if the property has a field.
+     * @return <code>true</code> if the property has a field.
+     */
+    public boolean hasField() {
+        return m_field != null;
+    }
+
+    public synchronized Object getValue() {
+        return m_value;
+    }
+
+    /**
+     * Gets the initial value of the property.
+     * @return the default value.
+     */
+    public Object getDefaultValue() {
+        return m_defaultValue;
+    }
+
+    /**
+     * Gets the NO VALUE Object.
+     * This method returns the object to inject when the property
+     * was not assigned to a value.
+     * @param type the type of the value.
+     * @return the object to inject when the property has no value.
+     */
+    private static Object getNoValue(Class type) {
+        if (Boolean.TYPE.equals(type)) { return Boolean.FALSE; }
+        if (Byte.TYPE.equals(type)) { return new Byte((byte) 0); }
+        if (Short.TYPE.equals(type)) { return new Short((short) 0); }
+        if (Integer.TYPE.equals(type)) { return new Integer(0); }
+        if (Long.TYPE.equals(type)) { return new Long(0); }
+        if (Float.TYPE.equals(type)) { return new Float(0); }
+        if (Double.TYPE.equals(type)) { return new Double(0); }
+        if (Character.TYPE.equals(type)) { return new Character((char) 0); }
+        // If all other case, return null.
+        return null;
+    }
+
+    /**
+     * Sets the value of the property.
+     * @param value the new value.
+     */
+    public void setValue(Object value) {
+        synchronized (this) {
+            // Is the object is directly assignable to the property, affect it.
+            if (isAssignable(m_type, value)) {
+                m_value = value;
+            } else {
+                // If the object is a String, we must recreate the object from the String form
+                if (value instanceof String) {
+                    try {
+                        m_value = create(m_type, (String) value);
+                    } catch (ConfigurationException e) {
+                        throw new ClassCastException("Incompatible type for the property " + m_name + " : " + e.getMessage());
+                    }
+                } else {
+                    // Error, the given property cannot be injected.
+                    throw new ClassCastException("Incompatible type for the property " + m_name + " " + m_type.getName() + " expected, "
+                                                 + value.getClass() + " found");
+                }
+            }
+            m_invoked = false;
+        }
+    }
+
+    /**
+     * Checks if the given value is assignable to the given type.
+     * @param type the class of the type
+     * @param value the object to check
+     * @return <code>true</code> if the object is assignable in the property of type 'type'.
+     */
+    public static boolean isAssignable(Class type, Object value) {
+        if (value == null || type.isInstance(value) || value == Property.NO_VALUE) { // When the value is null, the assign works necessary.
+            return true;
+        } else if (type.isPrimitive()) {
+            // Manage all boxing types.
+            if (value instanceof Boolean && Boolean.TYPE.equals(type)) { return true; }
+            if (value instanceof Byte && Byte.TYPE.equals(type)) { return true; }
+            if (value instanceof Short && Short.TYPE.equals(type)) { return true; }
+            if (value instanceof Integer && Integer.TYPE.equals(type)) { return true; }
+            if (value instanceof Long && Long.TYPE.equals(type)) { return true; }
+            if (value instanceof Float && Float.TYPE.equals(type)) { return true; }
+            if (value instanceof Double && Double.TYPE.equals(type)) { return true; }
+            if (value instanceof Character && Character.TYPE.equals(type)) { return true; }
+            return false;
+        } else {
+            // Else return false.
+            return false;
+        }
+    }
+
+    /**
+     * Creates an object of the given type with the given String value.
+     * @param type the type of the returned object
+     * @param strValue the String value.
+     * @return the object of type 'type' created from the String 'value'
+     * @throws ConfigurationException if the object cannot be created.
+     */
+    public static Object create(Class type, String strValue) throws ConfigurationException {
+        if (Boolean.TYPE.equals(type)) {
+            return Boolean.valueOf(strValue);
+        }
+        if (Byte.TYPE.equals(type)) { return new Byte(strValue); }
+        if (Short.TYPE.equals(type)) { return new Short(strValue); }
+        if (Integer.TYPE.equals(type)) { return new Integer(strValue); }
+        if (Long.TYPE.equals(type)) { return new Long(strValue); }
+        if (Float.TYPE.equals(type)) { return new Float(strValue); }
+        if (Double.TYPE.equals(type)) { return new Double(strValue); }
+        if (Character.TYPE.equals(type)) { return new Character(strValue.charAt(0)); }
+
+        // Array :
+        if (type.isArray()) {
+            return createArrayObject(type.getComponentType(), ParseUtils.parseArrays(strValue));
+        }
+
+        // Enum :
+        if (type.getSuperclass() != null  && type.getSuperclass().getName().equals("java.lang.Enum")) {
+            try {
+                Method valueOf = type.getMethod("valueOf", new Class[] {String.class});
+                if (! valueOf.isAccessible()) {
+                    valueOf.setAccessible(true);
+                }
+                 // Invoke the static method
+                return valueOf.invoke(null, new String[] {strValue});
+            } catch (InvocationTargetException e) {
+                throw new ConfigurationException("Cannot create an enumerated value for " + type
+                        + " with " + strValue + " : " + e.getTargetException());
+            } catch (Exception e) {
+                throw new ConfigurationException("Cannot create an enumerated value for " + type
+                        + " with " + strValue + " : " + e.getMessage());
+            }
+        }
+
+        // Else it is a neither a primitive type neither a String -> create
+        // the object by calling a constructor with a string in argument.
+        try {
+            Constructor cst = type.getConstructor(new Class[] { String.class });
+            return cst.newInstance(new Object[] { strValue });
+        } catch (SecurityException e) {
+            throw new ConfigurationException("Security exception during the creation of " + type + " : " + e.getMessage());
+        } catch (NoSuchMethodException e) {
+            throw new ConfigurationException("Constructor not found exception during the creation of " + type + " : " + e.getMessage());
+        } catch (IllegalArgumentException e) {
+            throw new ConfigurationException("Argument issue when calling the constructor of the type " + type);
+        } catch (InstantiationException e) {
+            throw new ConfigurationException("Instantiation problem  " + type);
+        } catch (IllegalAccessException e) {
+            throw new ConfigurationException("Illegal Access " + type);
+        } catch (InvocationTargetException e) {
+            throw new ConfigurationException("Invocation problem during the creation of " + type + " : " + e.getTargetException().getMessage());
+        }
+
+    }
+
+    /**
+     * Creates an array object containing the type component type from
+     * the String array 'values'.
+     * @param interntype the internal type of the array.
+     * @param values the String array
+     * @return the array containing objects created from the 'values' array
+     * @throws ConfigurationException if the array cannot be created correctly
+     */
+    public static Object createArrayObject(Class interntype, String[] values) throws ConfigurationException {
+        if (Boolean.TYPE.equals(interntype)) {
+            boolean[] bool = new boolean[values.length];
+            for (int i = 0; i < values.length; i++) {
+                bool[i] = Boolean.valueOf(values[i]).booleanValue();
+            }
+            return bool;
+        }
+        if (Byte.TYPE.equals(interntype)) {
+            byte[] byt = new byte[values.length];
+            for (int i = 0; i < values.length; i++) {
+                byt[i] = new Byte(values[i]).byteValue();
+            }
+            return byt;
+        }
+        if (Short.TYPE.equals(interntype)) {
+            short[] shor = new short[values.length];
+            for (int i = 0; i < values.length; i++) {
+                shor[i] = new Short(values[i]).shortValue();
+            }
+            return shor;
+        }
+        if (Integer.TYPE.equals(interntype)) {
+            int[] ints = new int[values.length];
+            for (int i = 0; i < values.length; i++) {
+                ints[i] = new Integer(values[i]).intValue();
+            }
+            return ints;
+        }
+        if (Long.TYPE.equals(interntype)) {
+            long[] longs = new long[values.length];
+            for (int i = 0; i < values.length; i++) {
+                longs[i] = new Long(values[i]).longValue();
+            }
+            return longs;
+        }
+        if (Float.TYPE.equals(interntype)) {
+            float[] floats = new float[values.length];
+            for (int i = 0; i < values.length; i++) {
+                floats[i] = new Float(values[i]).floatValue();
+            }
+            return floats;
+        }
+        if (Double.TYPE.equals(interntype)) {
+            double[] doubles = new double[values.length];
+            for (int i = 0; i < values.length; i++) {
+                doubles[i] = new Double(values[i]).doubleValue();
+            }
+            return doubles;
+        }
+        if (Character.TYPE.equals(interntype)) {
+            char[] chars = new char[values.length];
+            for (int i = 0; i < values.length; i++) {
+                chars[i] = values[i].toCharArray()[0];
+            }
+            return chars;
+        }
+
+        // Else it is a neither a primitive type -> create the
+        // object by calling a constructor with a string in argument.
+        try {
+            Constructor cst = interntype.getConstructor(new Class[] { String.class });
+            Object[] object = (Object[]) Array.newInstance(interntype, values.length);
+            for (int i = 0; i < values.length; i++) {
+                object[i] = cst.newInstance(new Object[] { values[i].trim() });
+            }
+            return object;
+        } catch (NoSuchMethodException e) {
+            throw new ConfigurationException("Constructor not found exception in setValue on " + interntype.getName());
+        } catch (IllegalArgumentException e) {
+            throw new ConfigurationException("Argument issue when calling the constructor of the type " + interntype.getName());
+        } catch (InstantiationException e) {
+            throw new ConfigurationException("Instantiation problem  " + interntype.getName());
+        } catch (IllegalAccessException e) {
+            throw new ConfigurationException("Illegal Access Exception in  " + interntype.getName());
+        } catch (InvocationTargetException e) {
+            throw new ConfigurationException("Invocation problem " + interntype.getName() + " : " + e.getTargetException().getMessage());
+        }
+    }
+
+    /**
+     * Clears the invoked flag.
+     * Then, despite the setter was already called,
+     * it will be invoked another times.
+     */
+    public synchronized void reset() {
+        m_invoked = false;
+    }
+
+    /**
+     * Invokes the setter method on the given pojo object.
+     * If no specified pojo object, it calls on each created pojo object.
+     * @param instance the created object (could be <code>null</code>)
+     */
+    public synchronized void invoke(Object instance) {
+        if (m_invoked) {
+            return; // Already called.
+        }
+
+        if (m_value == NO_VALUE) {
+            // Don't call method if no value
+            return;
+        }
+
+        try {
+            if (instance == null) {
+                m_method.call(new Object[] { m_value });
+            } else {
+                m_method.call(instance, new Object[] { m_value });
+            }
+            m_invoked = true;
+        } catch (NoSuchMethodException e) {
+            m_handler.error("The method " + m_method + " does not exist in the implementation class " + m_manager.getClassName(), e);
+            m_manager.stop();
+        } catch (IllegalAccessException e) {
+            m_handler.error("The method " + m_method + " is not accessible in the implementation class " + m_manager.getClassName(), e);
+            m_manager.stop();
+        } catch (InvocationTargetException e) {
+            m_handler.error("The method " + m_method + " in the implementation class " + m_manager.getClassName() + "throws an exception : " + e.getTargetException().getMessage(), e.getTargetException());
+            m_manager.setState(ComponentInstance.INVALID);
+        }
+    }
+
+    /**
+     * A field value is required by the object 'pojo'.
+     * @param pojo the POJO object
+     * @param fieldName the field
+     * @param value the last value
+     * @return the value if the handler want to inject this value.
+     * @see org.apache.felix.ipojo.FieldInterceptor#onGet(java.lang.Object, java.lang.String, java.lang.Object)
+     */
+    public synchronized Object onGet(Object pojo, String fieldName, Object value) {
+        if (m_value  == NO_VALUE) {
+            return getNoValue(m_type);
+        }
+        return m_value;
+    }
+
+    /**
+     * The field 'field' receives a new value.
+     * @param pojo the pojo
+     * @param fieldName the field name
+     * @param value the new value
+     * @see org.apache.felix.ipojo.FieldInterceptor#onSet(java.lang.Object, java.lang.String, java.lang.Object)
+     */
+    public synchronized void onSet(Object pojo, String fieldName, Object value) {
+        if (m_value == null || ! m_value.equals(value)) {
+            setValue(value);
+        }
+    }
+
+    /**
+     * Gets the object to inject as constructor parameter.
+     * @param index the constructor parameter index
+     * @return the object to inject, so the property value.
+     * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameter(int)
+     */
+    public Object getConstructorParameter(int index) {
+        if (m_index != index) {
+            return null;
+        }
+
+        if (m_value  == NO_VALUE) {
+           return getNoValue(m_type);
+        }
+        return m_value;
+    }
+
+    /**
+     * Gets the type of the constructor parameter to inject.
+     * @param index the parameter index
+     * @return the Class of the property.
+     * @see org.apache.felix.ipojo.ConstructorInjector#getConstructorParameterType(int)
+     */
+    public Class getConstructorParameterType(int index) {
+        if (m_index != index) {
+            return null;
+        }
+        return m_type;
+    }
+
+    /**
+     * Gets the handler managing the property.
+     * @return the configuration handler.
+     */
+    public Handler getHandler() {
+        return m_handler;
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/SecurityHelper.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/SecurityHelper.java
new file mode 100644
index 0000000..04d576f
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/SecurityHelper.java
@@ -0,0 +1,186 @@
+/* 
+ * 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.util;
+
+import java.security.Permission;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServicePermission;
+
+
+/**
+ * Methods checking security permissions.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class SecurityHelper {
+    
+    
+    /**
+     * Gets a bundle context to register the given services.
+     * This method can be used only if iPOJO is able to
+     * registers the services (so for ManagedServiceFactory,
+     * Factory and Architecture)
+     * @param itfs the service interfaces
+     * @param comp the component bundle context
+     * @param ipojo the ipojo bundle context
+     * @return <code>comp</code> if the bundle has enough permission
+     * to register the service, <code>ipojo</code> otherwise.
+     */
+    public static BundleContext selectContextToRegisterServices(String[] itfs,
+            BundleContext comp, BundleContext ipojo) {
+        if (System.getSecurityManager() != null) {
+            for (int i = 0; i < itfs.length; i++) {
+                final Permission perm = new ServicePermission(itfs[i],
+                        ServicePermission.REGISTER);
+                if (!comp.getBundle().hasPermission(perm)) {
+                    return ipojo;
+                }
+            }
+            
+        }
+        return comp;
+    }
+    
+    /**
+     * Gets a bundle context to register the given service.
+     * This method can be used only if iPOJO is able to
+     * registers the service (so for ManagedServiceFactory,
+     * Factory and Architecture)
+     * @param itf the service interface
+     * @param comp the component bundle context
+     * @param ipojo the ipojo bundle context
+     * @return <code>comp</code> if the bundle has enough permission
+     * to register the service, <code>ipojo</code> otherwise.
+     */
+    public static BundleContext selectContextToRegisterService(String itf,
+            BundleContext comp, BundleContext ipojo) {
+        if (System.getSecurityManager() != null) {
+            final Permission perm = new ServicePermission(itf,
+                    ServicePermission.REGISTER);
+            if (!comp.getBundle().hasPermission(perm)) {
+                return ipojo;
+            }
+        }
+        return comp;
+    }
+    
+    /**
+     * Gets a bundle context to get the given service.
+     * This method can be used only if iPOJO is able to
+     * get the service (so for ManagedServiceFactory,
+     * Factory, Architecture and LogService)
+     * @param itf the service interface
+     * @param comp the component bundle context
+     * @param ipojo the ipojo bundle context
+     * @return <code>comp</code> if the bundle has enough permission
+     * to get the service, <code>ipojo</code> otherwise.
+     */
+    public static BundleContext selectContextToGetService(String itf,
+            BundleContext comp, BundleContext ipojo) {
+        if (System.getSecurityManager() != null) {
+            final Permission perm = new ServicePermission(itf,
+                    ServicePermission.GET);
+            if (!comp.getBundle().hasPermission(perm)) {
+                return ipojo;
+            }
+        }
+        return comp;
+    }
+    
+    /**
+     * Checks if the component bundle context has enough permission
+     * to get the given service.
+     * @param itf the service interface
+     * @param comp the component bundle context
+     * @return <code>true</code> if the bundle has enough permission
+     * to get the service, <code>false</code> otherwise.
+     */
+    public static boolean hasPermissionToGetService(String itf,
+            BundleContext comp) {
+        if (System.getSecurityManager() != null) {
+            final Permission perm = new ServicePermission(itf,
+                    ServicePermission.GET);
+            return comp.getBundle().hasPermission(perm);
+        }
+        return true;
+    } 
+    
+    /**
+     * Checks if the component bundle context has enough permission
+     * to get the given services.
+     * @param itfs the service interfaces
+     * @param comp the component bundle context
+     * @return <code>true</code> if the bundle has enough permission
+     * to get the services, <code>false</code> otherwise.
+     */
+    public static boolean hasPermissionToGetServices(String[] itfs,
+            BundleContext comp) {
+        if (System.getSecurityManager() != null) {
+            for (int i = 0; i < itfs.length; i++) {
+                final Permission perm = new ServicePermission(itfs[i],
+                        ServicePermission.GET);
+                if (!comp.getBundle().hasPermission(perm)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    } 
+    
+    /**
+     * Checks if the component bundle context has enough permission
+     * to register the given service.
+     * @param itf the service interface
+     * @param comp the component bundle context
+     * @return <code>true</code> if the bundle has enough permission
+     * to register the service, <code>false</code> otherwise.
+     */
+    public static boolean hasPermissionToRegisterService(String itf,
+            BundleContext comp) {
+        if (System.getSecurityManager() != null) {
+            final Permission perm = new ServicePermission(itf,
+                    ServicePermission.REGISTER);
+            return comp.getBundle().hasPermission(perm);
+        }
+        return true;
+    }
+    
+    /**
+     * Checks if the component bundle context has enough permission
+     * to register the given services.
+     * @param itfs the service interfaces
+     * @param comp the component bundle context
+     * @return <code>true</code> if the bundle has enough permission
+     * to register the services, <code>false</code> otherwise.
+     */
+    public static boolean hasPermissionToRegisterServices(String[] itfs,
+            BundleContext comp) {
+        if (System.getSecurityManager() != null) {
+            for (int i = 0; i < itfs.length; i++) {
+                final Permission perm = new ServicePermission(itfs[i],
+                        ServicePermission.REGISTER);
+                if (!comp.getBundle().hasPermission(perm)) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/ServiceReferenceRankingComparator.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/ServiceReferenceRankingComparator.java
new file mode 100644
index 0000000..649116c
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/ServiceReferenceRankingComparator.java
@@ -0,0 +1,90 @@
+/* 
+ * 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.util;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Service Reference Comparator.
+ * This comparator follows OSGi Ranking policy.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class ServiceReferenceRankingComparator implements Comparator, Serializable {
+
+    /**
+     * Id.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Compares two service reference.
+     * @param ref1 the reference 1
+     * @param ref2 the reference 2
+     * @return <code>-1</code> if the reference 1 
+     * is 'higher' than the reference 2, <code>1</code> otherwise. 
+     * (higher is term of ranking means a lower index)
+     * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+     */
+    public int compare(Object ref1, Object ref2) {
+        if (ref1.equals(ref2)) { return 0; }
+
+        if (ref1 instanceof ServiceReference && ref2 instanceof ServiceReference) {
+            Object property1 = ((ServiceReference) ref1).getProperty(Constants.SERVICE_RANKING);
+            Object property2 = ((ServiceReference) ref2).getProperty(Constants.SERVICE_RANKING);
+
+            int rank1 = 0;
+            int rank2 = 0;
+            if (property1 instanceof Integer) {
+                rank1 = ((Integer) property1).intValue();
+            }
+            if (property2 instanceof Integer) {
+                rank2 = ((Integer) property2).intValue();
+            }
+
+            if (rank1 == rank2) {
+                // Check service.id
+                Object sid1 = ((ServiceReference) ref1).getProperty(Constants.SERVICE_ID);
+                Object sid2 = ((ServiceReference) ref2).getProperty(Constants.SERVICE_ID);
+
+                long rankId1 = ((Long) sid1).longValue();
+                long rankId2 = ((Long) sid2).longValue();
+
+                if (rankId1 == rankId2) {
+                    return 0;
+                } else if (rankId1 < rankId2) {
+                    return -1;
+                } else {
+                    return 1;
+                }
+
+            } else if (rank1 > rank2) {
+                return -1;
+            } else {
+                return 1;
+            }
+
+        } else {
+            return 0;
+        }
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
new file mode 100644
index 0000000..9f02c42
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/Tracker.java
@@ -0,0 +1,767 @@
+/*
+ * 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.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.felix.ipojo.context.ServiceReferenceImpl;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Utility class close to the OSGi Service Tracker.
+ * This class is used when tracking dynamic services is required.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class Tracker implements TrackerCustomizer {
+
+    /**
+     * The bundle context against which this Tracker object is tracking.
+     */
+    protected BundleContext m_context;
+
+    /**
+     * the filter specifying search criteria for the services to track.
+     */
+    protected Filter m_filter;
+
+    /**
+     * The TrackerCustomizer object for this tracker.
+     */
+    protected TrackerCustomizer m_customizer;
+
+    /**
+     * The filter string for use when adding the ServiceListener.
+     * If this field is set, then certain optimizations can be taken since we don't have a user supplied filter.
+     */
+    protected String m_listenerFilter;
+
+    /**
+     * The class name to be tracked. If this field is set, then we are
+     * tracking by class name.
+     */
+    private String m_trackClass;
+
+    /**
+     * The reference to be tracked. If this field is set, then we are
+     * tracking a single ServiceReference.
+     */
+    private ServiceReference m_trackReference;
+
+    /**
+     * The tracked services: ServiceReference object -> customized.
+     *Object and ServiceListener object
+     */
+    private Tracked m_tracked;
+
+    /**
+     * The cached ServiceReference for getServiceReference.
+     * This field is volatile since it is accessed by multiple threads.
+     */
+    private volatile ServiceReference m_cachedReference;
+
+    /**
+     * The cached service object for getService. This field is volatile
+     * since it is accessed by multiple threads.
+     */
+    private volatile Object m_cachedService;
+
+    /**
+     * Creates a Tracker object on the specified ServiceReference object.
+     * The service referenced by the specified ServiceReference object will be tracked by this Tracker.
+     * @param context The BundleContext object against which the tracking is done.
+     * @param reference The ServiceReference object for the service to be tracked.
+     * @param customizer The customizer object to call when services are added, modified, or removed in this Tracker object. If customizer is null, then this Tracker object will be used as
+     *            the TrackerCustomizer object and the Tracker object will call the TrackerCustomizer methods on itself.
+     */
+    public Tracker(BundleContext context, ServiceReference reference, TrackerCustomizer customizer) {
+        m_context = context;
+        m_trackReference = reference;
+        m_trackClass = null;
+        if (customizer == null) {
+            m_customizer = this;
+        } else {
+            m_customizer = customizer;
+        }
+        m_listenerFilter = "(" + Constants.SERVICE_ID + "=" + reference.getProperty(Constants.SERVICE_ID).toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        try {
+            this.m_filter = context.createFilter(m_listenerFilter);
+        } catch (InvalidSyntaxException e) { // we could only get this exception if the ServiceReference was invalid
+            throw new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Creates a Tracker object on the specified class name.
+     * Services registered under the specified class name will be tracked by this Tracker object.
+     * @param context the BundleContext object against which the tracking is done.
+     * @param clazz the Class name of the services to be tracked.
+     * @param customizer the customizer object to call when services are added, modified, or removed in this Tracker object. If customizer is null, then this Tracker object will be used as
+     *            the TrackerCustomizer object and the Tracker object will call the TrackerCustomizer methods on itself.
+     */
+    public Tracker(BundleContext context, String clazz, TrackerCustomizer customizer) {
+        // Security Check
+        if (! SecurityHelper.hasPermissionToGetService(clazz, context)) {
+            throw new SecurityException("The bundle " + context.getBundle().getBundleId()
+                    + " does not have the permission to get the service " + clazz);
+        }
+
+        this.m_context = context;
+        this.m_trackReference = null;
+        this.m_trackClass = clazz;
+        if (customizer == null) {
+            m_customizer = this;
+        } else {
+            m_customizer = customizer;
+        }
+        this.m_listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz + ")";
+        try {
+            this.m_filter = context.createFilter(m_listenerFilter);
+        } catch (InvalidSyntaxException e) { // we could only get this exception
+            // if the clazz argument was
+            // malformed
+            throw new IllegalArgumentException("unexpected InvalidSyntaxException: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Creates a Tracker object on the specified Filter object.
+     * <p>
+     * Services which match the specified Filter object will be tracked by this Tracker object.
+     * @param context the BundleContext object against which the tracking is done.
+     * @param filter the Filter object to select the services to be tracked.
+     * @param customizer The customizer object to call when services are added, modified, or removed in this Tracker object. If customizer is null, then this Tracker object will be used as the
+     *            TrackerCustomizer object and the Tracker object will call the TrackerCustomizer methods on itself.
+     */
+    public Tracker(BundleContext context, Filter filter, TrackerCustomizer customizer) {
+        this.m_context = context;
+        this.m_trackReference = null;
+        this.m_trackClass = null;
+        this.m_listenerFilter = null;
+        this.m_filter = filter;
+        if (customizer == null) {
+            m_customizer = this;
+        } else {
+            m_customizer = customizer;
+        }
+        if ((context == null) || (filter == null)) { // we throw a NPE here to be consistent with the other constructors
+            throw new NullPointerException(); // NOPMD by clement on 29/02/08 14:12
+        }
+    }
+
+    /**
+     * Opens this Tracker object and begin tracking services.
+     * <p>
+     * Services which match the search criteria specified when this Tracker object was created are now tracked by this Tracker object.
+     */
+    public synchronized void open() {
+        if (m_tracked != null) { return; }
+
+        m_tracked = new Tracked();
+        synchronized (m_tracked) {
+            try {
+                m_context.addServiceListener(m_tracked, m_listenerFilter);
+                ServiceReference[] references;
+                if (m_listenerFilter == null) { // user supplied filter
+                    references = getInitialReferences(null, m_filter.toString());
+                } else { // constructor supplied filter
+                    if (m_trackClass == null) {
+                        references = new ServiceReference[] { m_trackReference };
+                    } else {
+                        references = getInitialReferences(m_trackClass, null);
+                    }
+                }
+
+                m_tracked.setInitialServices(references); // set tracked with
+                // the initial
+                // references
+            } catch (InvalidSyntaxException e) {
+                throw new IllegalStateException("unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+            }
+        }
+        /* Call tracked outside of synchronized region */
+        m_tracked.trackInitialServices(); // process the initial references
+    }
+
+    /**
+     * Returns the list of initial ServiceReference objects that will be tracked by this Tracker object.
+     * @param trackClass the class name with which the service was registered, or null for all services.
+     * @param filterString the filter criteria or null for all services.
+     * @return the list of initial ServiceReference objects.
+     * @throws InvalidSyntaxException if the filter uses an invalid syntax.
+     */
+    private ServiceReference[] getInitialReferences(String trackClass, String filterString) throws InvalidSyntaxException {
+        return m_context.getServiceReferences(trackClass, filterString);
+    }
+
+    /**
+     * Closes this Tracker object.
+     * <p>
+     * This method should be called when this Tracker object should end the tracking of services.
+     */
+    public synchronized void close() {
+        if (m_tracked == null) { return; }
+
+        m_tracked.close();
+        ServiceReference[] references = getServiceReferences();
+        Tracked outgoing = m_tracked;
+
+        try {
+            m_context.removeServiceListener(outgoing);
+        } catch (IllegalStateException e) { //NOPMD
+            /* In case the context was stopped. */
+        }
+        if (references != null) {
+            for (int i = 0; i < references.length; i++) {
+                outgoing.untrack(references[i]);
+            }
+        }
+        m_tracked = null;
+
+    }
+
+    /**
+     * Default implementation of the TrackerCustomizer.addingService method.
+     * <p>
+     * This method is only called when this Tracker object has been constructed with a null TrackerCustomizer argument. The default implementation returns the result of calling getService,
+     * on the BundleContext object with which this Tracker object was created, passing the specified ServiceReference object.
+     * <p>
+     * This method can be overridden in a subclass to customize the service object to be tracked for the service being added. In that case, take care not to rely on the default implementation of removedService that will unget the service.
+     * @param reference the Reference to service being added to this Tracker object.
+     * @return The service object to be tracked for the service added to this Tracker object.
+     * @see TrackerCustomizer
+     */
+    public boolean addingService(ServiceReference reference) {
+        return true;
+    }
+
+    /**
+     * Default implementation of the TrackerCustomizer.addedService method.
+     * @param reference the added reference.
+     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
+     */
+    public void addedService(ServiceReference reference) {
+        // Nothing to do.
+    }
+
+    /**
+     * Default implementation of the TrackerCustomizer.modifiedService method.
+     * <p>
+     * This method is only called when this Tracker object has been constructed with a null TrackerCustomizer argument. The default implementation does nothing.
+     * @param reference the Reference to modified service.
+     * @param service The service object for the modified service.
+     * @see TrackerCustomizer
+     */
+    public void modifiedService(ServiceReference reference, Object service) {
+        // Nothing to do.
+    }
+
+    /**
+     * Default implementation of the TrackerCustomizer.removedService method.
+     * <p>
+     * This method is only called when this Tracker object has been constructed with a null TrackerCustomizer argument. The default implementation calls ungetService, on the
+     * BundleContext object with which this Tracker object was created, passing the specified ServiceReference object.
+     * <p>
+     * This method can be overridden in a subclass. If the default implementation of addingService method was used, this method must unget the service.
+     * @param reference the Reference to removed service.
+     * @param service The service object for the removed service.
+     * @see TrackerCustomizer
+     */
+    public void removedService(ServiceReference reference, Object service) {
+        m_context.ungetService(reference);
+    }
+
+    /**
+     * Waits for at least one service to be tracked by this Tracker object.
+     * <p>
+     * It is strongly recommended that waitForService is not used during the calling of the BundleActivator methods. BundleActivator methods are expected to complete in a short period of time.
+     * @param timeout the time interval in milliseconds to wait. If zero, the method will wait indefinately.
+     * @return Returns the result of getService().
+     * @throws InterruptedException If another thread has interrupted the current thread.
+     */
+    public Object waitForService(long timeout) throws InterruptedException {
+        if (timeout < 0) { throw new IllegalArgumentException("timeout value is negative"); }
+        Object object = getService();
+        while (object == null) {
+            Tracked tracked = this.m_tracked; // use local var since we are not synchronized
+            if (tracked == null) { /* if Tracker is not open */
+                return null;
+            }
+            synchronized (tracked) {
+                if (tracked.size() == 0) {
+                    tracked.wait(timeout);
+                }
+            }
+            object = getService();
+            if (timeout > 0) { return object; }
+        }
+        return object;
+    }
+
+    /**
+     * Returns an array of ServiceReference objects for all services being tracked by this Tracker object.
+     * @return Array of ServiceReference objects or <code>null</code> if no service are being tracked.
+     */
+    public ServiceReference[] getServiceReferences() {
+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized
+        if (tracked == null) { // if Tracker is not open
+            return null;
+        }
+        synchronized (tracked) {
+            int length = tracked.size();
+            if (length == 0) { return null; }
+            ServiceReference[] references = new ServiceReference[length];
+            Iterator keys = tracked.keySet().iterator();
+            for (int i = 0; i < length; i++) {
+                references[i] = (ServiceReference) keys.next();
+            }
+            return references;
+        }
+    }
+
+    /**
+     * Gets the list of stored service reference.
+     * @return the list containing used service reference
+     */
+    public List/*<ServiceReference>*/getServiceReferencesList() {
+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized
+        if (tracked == null) { // if Tracker is not open
+            return null;
+        }
+        synchronized (tracked) {
+            int length = tracked.size();
+            if (length == 0) { return null; }
+            List references = new ArrayList(length);
+            Iterator keys = tracked.keySet().iterator();
+            for (int i = 0; i < length; i++) {
+                references.add(keys.next());
+            }
+            // The resulting array is sorted by ranking.
+            return references;
+        }
+    }
+
+    /**
+     * Returns the list of references used by the tracker.
+     * A reference becomes used when the dependency has already
+     * called getService on this reference.
+     * @return the list of used references.
+     */
+    public List/*<ServiceReference>*/getUsedServiceReferences() {
+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized
+        if (tracked == null || tracked.size() == 0) { // if Tracker is not open or empty
+            return null;
+        }
+        synchronized (tracked) {
+            int length = tracked.size();
+            List references = new ArrayList();
+            Iterator keys = tracked.entrySet().iterator();
+            for (int i = 0; i < length; i++) {
+                Map.Entry entry = (Map.Entry) keys.next();
+                Object key = entry.getKey();
+                if (entry.getValue() != null) {
+                    references.add(key);
+                }
+            }
+            return references;
+        }
+    }
+
+    /**
+     * Returns a ServiceReference object for one of the services being tracked by this Tracker object.
+     * If multiple services are being tracked, the service with the highest ranking (as specified in its service.ranking property) is returned.
+     * If there is a tie in ranking, the service with the lowest service ID (as specified in its service.id property); that is, the service that was registered first is returned.
+     * This is the same algorithm used by BundleContext.getServiceReference.
+     * @return ServiceReference object or null if no service is being tracked.
+     * @since 1.1
+     */
+    public ServiceReference getServiceReference() {
+        ServiceReference reference = m_cachedReference;
+        if (reference != null) { return reference; }
+
+        ServiceReference[] references = getServiceReferences();
+        if (references == null) {
+            return null;
+        } else {
+            // As the map is sorted, return the first element.
+            return m_cachedReference = references[0];
+        }
+    }
+
+    /**
+     * Returns the service object for the specified ServiceReference object if the referenced service is being tracked by this Tracker object.
+     * @param reference the Reference to the desired service.
+     * @return the Service object. Try to get the service if not yet tracked.
+     */
+    public Object getService(ServiceReference reference) {
+        // Security Check
+        if (! SecurityHelper.hasPermissionToGetServices((String[]) reference.getProperty(Constants.OBJECTCLASS),
+                m_context)) {
+            throw new SecurityException("The bundle " + m_context.getBundle().getBundleId() + " does not have"
+                    + " the permission to get the services "
+                    + Arrays.asList((String[]) reference.getProperty(Constants.OBJECTCLASS)));
+        }
+
+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized
+        if (tracked == null) { /* if Tracker is not open */
+            return null;
+        }
+        Object object = null;
+        synchronized (tracked) {
+            object = tracked.get(reference);
+            if (object == null) {
+                if (tracked.containsKey(reference)) { // Not already get but already tracked.
+                    object = m_context.getService(reference);
+                    tracked.put(reference, object);
+                    return object;
+                }
+            } else { // The object was already get.
+                return object;
+            }
+
+            return  m_context.getService(reference);
+        }
+    }
+
+    /**
+     * Ungets the given service reference.
+     * @param reference the service reference to unget.
+     */
+    public void ungetService(ServiceReference reference) {
+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized
+        if (tracked == null) { /* if Tracker is not open */
+            return;
+        }
+        Object object = null;
+        synchronized (tracked) {
+            object = tracked.get(reference);
+        }
+        if (object != null) {
+            m_context.ungetService(reference);
+        }
+    }
+
+    /**
+     * Returns an array of service objects for all services being tracked by this Tracker object.
+     * @return Array of service objects or <code>null</code> if no service are being tracked.
+     */
+    public Object[] getServices() {
+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized
+        if (tracked == null) { /* if Tracker is not open */
+            return null;
+        }
+        synchronized (tracked) {
+            ServiceReference[] references = getServiceReferences();
+            int length = 0;
+            if (references == null) {
+                return null;
+            } else {
+                length = references.length;
+            }
+            Object[] objects = new Object[length];
+            for (int i = 0; i < length; i++) {
+                objects[i] = getService(references[i]);
+            }
+            return objects;
+        }
+    }
+
+    /**
+     * Returns a service object for one of the services being tracked by this Tracker object.
+     * <p>
+     * If any services are being tracked, this method returns the result of calling getService(getServiceReference()).
+     * @return Service object or <code>null</code> if no service is being tracked.
+     */
+    public Object getService() {
+        Object service = m_cachedService;
+        if (service != null) { return service; }
+        ServiceReference reference = getServiceReference();
+        if (reference == null) { return null; }
+        return m_cachedService = getService(reference);
+    }
+
+    /**
+     * Removes a service from this Tracker object. The specified service will be removed from this Tracker object. If the specified service was being tracked then the
+     * TrackerCustomizer.removedService method will be called for that service.
+     * @param reference the Reference to the service to be removed.
+     */
+    public void remove(ServiceReference reference) {
+        Tracked tracked = this.m_tracked; // use local var since we are not synchronized
+        if (tracked == null) { /* if Tracker is not open */
+            return;
+        }
+        tracked.untrack(reference);
+    }
+
+    /**
+     * Returns the number of services being tracked by this Tracker object.
+     * @return the Number of services being tracked.
+     */
+    public int size() {
+        Tracked tracked = this.m_tracked; //use local var since we are not synchronized
+        if (tracked == null) { /* if Tracker is not open */
+            return 0;
+        }
+        return tracked.size();
+    }
+
+    /**
+     * Inner class to track services. If a Tracker object is reused (closed then reopened), then a new Tracked object is used. This class is a hashtable mapping ServiceReference object -> customized Object. This
+     * class is the ServiceListener object for the tracker. This class is used to synchronize access to the tracked services. This is not a public class. It is only for use by the implementation of the Tracker
+     * class.
+     */
+    class Tracked extends HashMap implements ServiceListener {
+        /**
+         * UID.
+         */
+        static final long serialVersionUID = -7420065199791006079L;
+
+        /**
+         * The list of ServiceReferences in the process of being added. This is used to deal with nesting of ServiceEvents. Since ServiceEvents are synchronously delivered, ServiceEvents can be nested. For example, when processing the adding of a service
+         * and the customizer causes the service to be unregistered, notification to the nested call to untrack that the service was unregistered can be made to the track method. Since the ArrayList implementation is not synchronized, all access to
+         * this list must be protected by the same synchronized object for thread safety.
+         */
+        private List m_adding;
+
+        /**
+         * <code>true</code> if the tracked object is closed. This field is volatile because it is set by one thread and read by another.
+         */
+        private volatile boolean m_closed;
+
+        /**
+         * The Initial list of ServiceReferences for the tracker. This is used to correctly process the initial services which could become unregistered before they are tracked. This is necessary since the initial set of tracked services are not
+         * "announced" by ServiceEvents and therefore the ServiceEvent for unregistration could be delivered before we track the service. A service must not be in both the initial and adding lists at the same time. A service must be moved from the
+         * initial list to the adding list "atomically" before we begin tracking it. Since the LinkedList implementation is not synchronized, all access to this list must be protected by the same synchronized object for thread safety.
+         */
+        private List m_initial;
+
+        /**
+         * Tracked constructor.
+         */
+        protected Tracked() {
+            super();
+            m_closed = false;
+            m_adding = new ArrayList(6);
+            m_initial = new LinkedList();
+        }
+
+        /**
+         * Sets initial list of services into tracker before ServiceEvents begin to be received. This method must be called from Tracker.open while synchronized on this object in the same synchronized block as the addServiceListener call.
+         * @param references The initial list of services to be tracked.
+         */
+        protected void setInitialServices(ServiceReference[] references) {
+            if (references == null) { return; }
+            int size = references.length;
+            for (int i = 0; i < size; i++) {
+                m_initial.add(references[i]);
+            }
+        }
+
+        /**
+         * Tracks the initial list of services. This is called after ServiceEvents can begin to be received. This method must be called from Tracker.open while not synchronized on this object after the addServiceListener call.
+         */
+        protected void trackInitialServices() {
+            while (true) {
+                ServiceReference reference;
+                synchronized (this) {
+                    if (m_initial.isEmpty()) { //  if there are no more inital services
+                        return; // we are done
+                    }
+
+                    // move the first service from the initial list to the adding list within this synchronized block.
+                    reference = (ServiceReference) ((LinkedList) m_initial).removeFirst();
+                    if (this.containsKey(reference)) { //Check if the reference is already tracked.
+                        //if we are already tracking this service
+                        continue; /* skip this service */
+                    }
+                    if (m_adding.contains(reference)) {
+                        // if this service is already in the process of being added.
+                        continue; // skip this service
+                    }
+                    m_adding.add(reference);
+                }
+                trackAdding(reference); // Begin tracking it. We call trackAdding since we have already put the reference in the adding list.
+            }
+        }
+
+        /**
+         * Called by the owning Tracker object when it is closed.
+         */
+        protected void close() {
+            m_closed = true;
+        }
+
+        /**
+         * ServiceListener method for the Tracker class. This method must NOT be synchronized to avoid deadlock potential.
+         * @param event the ServiceEvent object from the framework.
+         */
+        public void serviceChanged(ServiceEvent event) {
+            //Check if we had a delayed call (which could happen when we close).
+            if (m_closed) { return; }
+            ServiceReference reference = event.getServiceReference();
+
+            switch (event.getType()) {
+                case ServiceEvent.REGISTERED:
+                case ServiceEvent.MODIFIED:
+                    if (m_listenerFilter == null) { // user supplied filter
+                        boolean match = true;
+                        if (reference instanceof ServiceReferenceImpl) {
+                            // Can't use the match(ref) as it throw a class cast exception on Equinox.
+                            match = m_filter.match(((ServiceReferenceImpl) reference).getProperties());
+                        } else { // Non compute reference.
+                            match = m_filter.match(reference);
+                        }
+                        if (match) {
+                            track(reference); // Arrival
+                        } else {
+                            untrack(reference); // Departure
+                        }
+                    } else { // constructor supplied filter
+                        track(reference);
+                    }
+                    break;
+                case ServiceEvent.UNREGISTERING:
+                    untrack(reference); // Departure
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        /**
+         * Begins to track the referenced service.
+         * @param reference the Reference to a service to be tracked.
+         */
+        protected void track(ServiceReference reference) {
+            Object object;
+            boolean alreadyTracked;
+            synchronized (this) {
+                alreadyTracked = this.containsKey(reference);
+                object = this.get(reference);
+            }
+            if (alreadyTracked) { // we are already tracking the service
+                if (object != null) { // If already get, invalidate the cache
+                    synchronized (this) {
+                        modified();
+                    }
+                }
+                // Call customizer outside of synchronized region
+                m_customizer.modifiedService(reference, object);
+                return;
+            }
+            synchronized (this) {
+                if (m_adding.contains(reference)) { // if this service is already in the process of being added.
+                    return;
+                }
+                m_adding.add(reference); // mark this service is being added
+            }
+
+            trackAdding(reference); // call trackAdding now that we have put the reference in the adding list
+        }
+
+        /**
+         * Common logic to add a service to the tracker used by track and trackInitialServices.
+         * The specified reference must have been placed in the adding list before calling this method.
+         * @param reference the Reference to a service to be tracked.
+         */
+        private void trackAdding(ServiceReference reference) {
+            boolean mustBeTracked = false;
+            boolean becameUntracked = false;
+            boolean mustCallAdded = false;
+            //Call customizer outside of synchronized region
+            try {
+                mustBeTracked = m_customizer.addingService(reference);
+            } finally {
+                synchronized (this) {
+                    if (m_adding.remove(reference)) { // if the service was not untracked during the customizer callback
+                        if (mustBeTracked) {
+                            this.put(reference, null);
+                            modified();
+                            mustCallAdded = true;
+                            notifyAll(); // notify any waiters in waitForService
+                        }
+                    } else {
+                        becameUntracked = true;
+                        // If already get during the customizer callback
+                        ungetService(reference);
+                        modified();
+                    }
+                }
+            }
+
+            // Call customizer outside of synchronized region
+            if (becameUntracked) {
+                // The service became untracked during the customizer callback.
+                m_customizer.removedService(reference, null);
+            } else {
+                if (mustCallAdded) {
+                    m_customizer.addedService(reference);
+                }
+            }
+        }
+
+        /**
+         * Discontinues tracking the referenced service.
+         * @param reference the Reference to the tracked service.
+         */
+        protected void untrack(ServiceReference reference) {
+            Object object;
+            synchronized (this) {
+                if (m_initial.remove(reference)) { // if this service is already in the list of initial references to process
+                    return; // we have removed it from the list and it will not be processed
+                }
+
+                if (m_adding.remove(reference)) { // if the service is in the process of being added
+                    return; // in case the service is untracked while in the process of adding
+                }
+
+                boolean isTraked = this.containsKey(reference); // Check if we was tracking the reference
+                object = this.remove(reference); // must remove from tracker before calling customizer callback
+
+                if (!isTraked) { return; }
+                modified();
+            }
+            // Call customizer outside of synchronized region and only if we are not closed
+            if (! m_closed) {
+            	m_customizer.removedService(reference, object);
+            }
+            // If the customizer throws an unchecked exception, it is safe to let it propagate
+        }
+
+        /**
+         * Called by the Tracked object whenever the set of tracked services is modified. Increments the tracking count and clears the cache.
+         * This method must not be synchronized since it is called by Tracked while Tracked is synchronized. We don't want synchronization interactions between the ServiceListener thread and the user thread.
+         */
+        void modified() {
+            m_cachedReference = null; /* clear cached value */
+            m_cachedService = null; /* clear cached value */
+        }
+    }
+}
diff --git a/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/TrackerCustomizer.java b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/TrackerCustomizer.java
new file mode 100644
index 0000000..69693cf
--- /dev/null
+++ b/ipojo/runtime/core/src/main/java/org/apache/felix/ipojo/util/TrackerCustomizer.java
@@ -0,0 +1,61 @@
+/* 
+ * 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.util;
+
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Tracker Customizer.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface TrackerCustomizer {
+
+    /**
+     * A service is being added to the Tracker object.
+     * This method is called before a service which matched the search parameters of the Tracker object is added to it. This method should return the service object to be tracked for this ServiceReference object.
+     * The returned service object is stored in the Tracker object and is available from the getService and getServices methods.
+     * @param reference the Reference to service being added to the Tracker object.
+     * @return The service object to be tracked for the ServiceReference object or null if the ServiceReference object should not be tracked.
+     */
+    boolean addingService(ServiceReference reference);
+    
+    /**
+     * A service tracked by the Tracker object has been added in the list.
+     * This method is called when a service has been added in the managed list (after addingService) and if the service has not disappeared before during the callback.
+     * @param reference the added reference.
+     */
+    void addedService(ServiceReference reference);
+
+    /**
+     * A service tracked by the Tracker object has been modified.
+     * This method is called when a service being tracked by the Tracker object has had it properties modified.
+     * @param reference the Reference to service that has been modified.
+     * @param service The service object for the modified service.
+     */
+    void modifiedService(ServiceReference reference, Object service);
+
+    /**
+     * A service tracked by the Tracker object has been removed.
+     * This method is called after a service is no longer being tracked by the Tracker object.
+     * @param reference the Reference to service that has been removed.
+     * @param service The service object for the removed service.
+     */
+    void removedService(ServiceReference reference, Object service);
+
+}
diff --git a/ipojo/runtime/core/src/main/resources/core.xsd b/ipojo/runtime/core/src/main/resources/core.xsd
new file mode 100644
index 0000000..6046c8d
--- /dev/null
+++ b/ipojo/runtime/core/src/main/resources/core.xsd
@@ -0,0 +1,602 @@
+<!--
+  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.
+-->
+<xs:schema elementFormDefault="qualified" targetNamespace="org.apache.felix.ipojo"
+  xmlns="org.apache.felix.ipojo" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <xs:annotation>
+    <xs:documentation>iPOJO Core XML-Schema. This grammars models iPOJO descriptor using core
+      features. It provides several extensibility mechanism in order to compose this schema with
+      external handlers and other component implementation type such as
+      compositions.</xs:documentation>
+  </xs:annotation>
+  <xs:element name="ipojo">
+    <xs:complexType>
+      <xs:annotation>
+        <xs:documentation>iPOJO top level element.</xs:documentation>
+      </xs:annotation>
+      <xs:choice minOccurs="0" maxOccurs="unbounded">
+        <xs:element ref="handler" minOccurs="0" maxOccurs="unbounded">
+          <xs:annotation>
+            <xs:documentation>The handler declarations.</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element ref="instance" minOccurs="0" maxOccurs="unbounded">
+          <xs:annotation>
+            <xs:documentation>The instance declarations.</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:element ref="component" minOccurs="0" maxOccurs="unbounded">
+          <xs:annotation>
+            <xs:documentation>The component type declarations.</xs:documentation>
+          </xs:annotation>
+        </xs:element>
+        <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"
+        > </xs:any>
+      </xs:choice>
+    </xs:complexType>
+  </xs:element>
+  <xs:complexType name="HandlerType">
+    <xs:annotation>
+      <xs:documentation>Description of the handler.</xs:documentation>
+    </xs:annotation>
+    <xs:complexContent>
+      <xs:extension base="RootElementType">
+        <xs:sequence maxOccurs="unbounded" minOccurs="0">
+          <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##any" processContents="skip"
+          > </xs:any>
+        </xs:sequence>
+        <xs:attribute name="classname" type="xs:string" use="required">
+          <xs:annotation>
+            <xs:documentation>The implementation class of the handler. The specified class must
+              implement (direcly or not) the "org.apache.felix.ipojo.Handler"
+              interface.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="name" type="xs:string" use="required">
+          <xs:annotation>
+            <xs:documentation>The name of the handler.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="namespace" type="xs:string" use="optional">
+          <xs:annotation>
+            <xs:documentation>The XML namespace of the handler.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="architecture" type="xs:boolean" use="optional" fixed="false">
+          <xs:annotation>
+            <xs:documentation>Enables or disables the architecture exposition. By default, the
+              architecture is not exposed. This allows handler introspection.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="level" type="xs:int" use="optional">
+          <xs:annotation>
+            <xs:documentation>The start level of the handler.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="InstanceType">
+    <xs:annotation>
+      <xs:documentation>Describes an instance of a component.</xs:documentation>
+    </xs:annotation>
+    <xs:complexContent>
+      <xs:extension base="RootElementType">
+        <xs:sequence minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="property" type="InstancePropertyType">
+            <xs:annotation>
+              <xs:documentation>The instance properties.</xs:documentation>
+            </xs:annotation>
+          </xs:element>
+        </xs:sequence>
+        <xs:attribute name="component" type="xs:string">
+          <xs:annotation>
+            <xs:documentation>The name of the instance component type.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="name" type="xs:string" use="optional">
+          <xs:annotation>
+            <xs:documentation>The (unique) name of the instance.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+        <xs:attribute name="version" type="xs:string" use="optional">
+          <xs:annotation>
+            <xs:documentation>The version of the factory to use.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="InstancePropertyType">
+    <xs:annotation>
+      <xs:documentation>Defines a property of an instance configuration.</xs:documentation>
+    </xs:annotation>
+    <xs:sequence>
+      <xs:element name="property" type="InstancePropertyType" minOccurs="0" maxOccurs="unbounded"/>
+    </xs:sequence>
+    <xs:attribute name="name" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Name of the property. Can be optional if a property is inside a structure.
+          The 'instance.name' property has a special semantic as it will be used as the instance
+          name.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="value" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Value of the property. Can be null for property containing other
+          properties.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="type" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Type of the property, used to create the adequate object. Supported values
+          are list, array, dictionary and map.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="RootElementType"/>
+  <xs:complexType name="ComponentType">
+    <xs:annotation>
+      <xs:documentation>Declares an atomic (i.e. primitive) component type.</xs:documentation>
+    </xs:annotation>
+    <xs:choice minOccurs="0" maxOccurs="unbounded">
+      <xs:element ref="callback" minOccurs="0" maxOccurs="unbounded">
+        <xs:annotation>
+          <xs:documentation>Describes the method(s) to invoke when the component's state
+            changes.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element ref="provides" minOccurs="0" maxOccurs="unbounded">
+        <xs:annotation>
+          <xs:documentation>Indicates the component provided service(s). By default, all implemented
+            interfaces are published.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element ref="requires" minOccurs="0" maxOccurs="unbounded">
+        <xs:annotation>
+          <xs:documentation>Indicates the service requirements of the component.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element ref="properties" minOccurs="0" maxOccurs="unbounded">
+        <xs:annotation>
+          <xs:documentation>Describes the properties of the component.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element ref="controller" minOccurs="0" maxOccurs="1">
+        <xs:annotation>
+          <xs:documentation>Lifecycle controller for this component.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"
+      > </xs:any>
+    </xs:choice>
+    <xs:attribute name="name" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Specifies the name of the component type. This name is used to identify
+          the factory attached to this type. If not specified, the factory name is the
+          implementation class name.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="public" type="xs:boolean" use="optional">
+      <xs:annotation>
+        <xs:documentation>Determines if the component type is public or private. A public factory
+          (default) can be used from any bundles.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="classname" type="xs:string" use="required">
+      <xs:annotation>
+        <xs:documentation>Specifies the implementation class of the component
+          type.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="architecture" type="xs:boolean" use="optional">
+      <xs:annotation>
+        <xs:documentation>Enables or disables the architecture exposition. By default, the
+          architecture is exposed. This allows instance introspection.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="immediate" type="xs:boolean" use="optional">
+      <xs:annotation>
+        <xs:documentation>Creates the object of the component implementation type as soon as the
+          component instance becomes valid. The default value is "true" if the component doesn't
+          provide any service, "false" otherwise.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="factory-method" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Factory method called to create POJO objects instead of the constructor.
+          The specified method must be a static method of the implementation class returning an
+          instance of this implementation class. The factory method can receive the bundle context
+          in argument.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="version" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Set the version of this component type</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="RequiresType">
+    <xs:annotation>
+      <xs:documentation>Description of component services requirements.</xs:documentation>
+    </xs:annotation>
+    <xs:complexContent>
+      <xs:extension base="ServiceDependencyType">
+        <xs:sequence minOccurs="0" maxOccurs="unbounded">
+          <xs:element name="callback" type="DependencyCallbackType">
+            <xs:annotation>
+              <xs:documentation>Service requirement method invocation description. Here can be
+                specified a bind method called when a service appears and an unbind method called
+                when a service disappears.</xs:documentation>
+            </xs:annotation>
+          </xs:element>
+        </xs:sequence>
+
+        <xs:attribute name="interface" type="xs:string" use="prohibited">
+          <xs:annotation>
+            <xs:documentation>The interface describing the required service type. This attribute is
+              needed only when using aggregate dependencies with field injection and when the type
+              of this field is a list, vector, collection and set. This attribute is deprecated, use
+              'specification'.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+
+        <xs:attribute name="field" type="xs:string" use="optional">
+          <xs:annotation>
+            <xs:documentation>The name of the field representing the service dependency in the
+              implementation class.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+
+        <xs:attribute name="constructor-parameter" type="xs:int" use="optional">
+          <xs:annotation>
+            <xs:documentation>The index of the parameter if the dependency is injected
+            using the constructor.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+
+        <xs:attribute name="nullable" type="xs:boolean" use="optional">
+          <xs:annotation>
+            <xs:documentation>Enable or disable the Nullable pattern on optional service
+              dependencies. By default, Nullable pattern is enabled. If disabled, iPOJO will inject
+              null instead of a Nullable object.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+
+        <xs:attribute name="default-implementation" type="xs:string" use="optional">
+          <xs:annotation>
+            <xs:documentation>Specifies the default implementation class for an optional service
+              dependency. If no providers are found, iPOJO creates an instance of the
+              default-implementation (nullary constructor) and injects it. The given class must
+              implement the required service interface.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+
+        <xs:attribute name="from" type="xs:string" use="optional">
+          <xs:annotation>
+            <xs:documentation>Specific service provider. The dependency can only be fulfilled by the
+              component with the matching name, or by the service with a matching
+              PID.</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+
+        <xs:attribute name="proxy" type="xs:boolean" use="optional">
+          <xs:annotation>
+            <xs:documentation>Enables or Disable the proxy injection (on field
+              injection)</xs:documentation>
+          </xs:annotation>
+        </xs:attribute>
+
+        <xs:attribute name="scope" use="optional">
+          <xs:simpleType>
+            <xs:restriction base="xs:string">
+              <xs:enumeration value="global"/>
+              <xs:enumeration value="composite"/>
+              <xs:enumeration value="composite+global"/>
+            </xs:restriction>
+          </xs:simpleType>
+        </xs:attribute>
+
+      </xs:extension>
+    </xs:complexContent>
+  </xs:complexType>
+  <xs:complexType name="DependencyCallbackType">
+    <xs:annotation>
+      <xs:documentation>Dependency callbacks are used to receive notification when service providers
+        arrive and leave.</xs:documentation>
+    </xs:annotation>
+    <xs:attribute name="method" type="xs:string" use="required">
+      <xs:annotation>
+        <xs:documentation>Method to call</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="type" use="required">
+      <xs:annotation>
+        <xs:documentation> Type of callback (bind, unbind, or updated). Bind means that the method
+          will be called when a provider arrives. Unbind means that the method will be called when a
+          provider leaves. Updated means that a service was modified but is still valid for the
+          service dependency. </xs:documentation>
+      </xs:annotation>
+      <xs:simpleType>
+        <xs:restriction base="xs:string">
+          <xs:enumeration value="bind"/>
+          <xs:enumeration value="unbind"/>
+          <xs:enumeration value="modified"/>
+        </xs:restriction>
+      </xs:simpleType>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="CallbackType">
+    <xs:annotation>
+      <xs:documentation>Lifecycle Callback. Allows a POJO to be notified when the instance becomes
+        valid or invalid.</xs:documentation>
+    </xs:annotation>
+    <xs:attribute name="method" type="xs:string" use="required">
+      <xs:annotation>
+        <xs:documentation>Specifies the method to call on the transition.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="transition" use="required">
+      <xs:annotation>
+        <xs:documentation>Specifies the transition when the callback needs to be
+          invoked.</xs:documentation>
+      </xs:annotation>
+      <xs:simpleType>
+        <xs:annotation>
+          <xs:documentation>Lifecycle transition state. "validate" means that the component's
+            instance was invalid and becomes valid, "invalidate" means that the component's intance
+            was valid and becomes invalid.</xs:documentation>
+        </xs:annotation>
+        <xs:restriction base="xs:string">
+          <xs:enumeration value="validate"/>
+          <xs:enumeration value="invalidate"/>
+        </xs:restriction>
+      </xs:simpleType>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:element name="provides" type="ProvidesType" id="provides"/>
+  <xs:complexType name="ProvidesType">
+    <xs:annotation>
+      <xs:documentation>Provided service(s) description.</xs:documentation>
+    </xs:annotation>
+    <xs:sequence minOccurs="0" maxOccurs="unbounded">
+      <xs:choice>
+      <xs:element name="property" type="PropertyType">
+        <xs:annotation>
+          <xs:documentation>List of service specific properties.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+      <xs:element name="controller" minOccurs="0" maxOccurs="1" type="ServiceControllerType">
+          <xs:annotation>
+            <xs:documentation>Service Controller impacting the current provided
+              service</xs:documentation>
+          </xs:annotation>
+       </xs:element>
+      </xs:choice>
+    </xs:sequence>
+    <xs:attribute name="interface" type="xs:string" use="prohibited">
+      <xs:annotation>
+        <xs:documentation>Deprecated attribute, use 'specifications' instead of
+          'interface'</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="specifications" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>The list of service specifications (i.e. interfaces) to expose. By
+          default, all interfaces implemented by the component implementation class are
+          published.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="factory" type="xs:string" use="prohibited">
+      <xs:annotation>
+        <xs:documentation>Use 'strategy' instead of 'factory'</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="strategy" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>POJO creation strategy. By default, the POJO object is created once
+          (singleton). If the factory is set to "SERVICE", the creation policy follows the OSGi
+          service factory policy (one object object per asking bundle). INSTANCE allows creating one
+          different POJO object per asking instance. Finally, a custom strategy can be used by
+          specifying the qualified name of the class extending CreationPolicy</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="post-registration" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Defines a callback called after the service registration. The callback takes a ServiceReference
+        as parameter</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="post-unregistration" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Defines a callback called after the service unregistration. The callback takes a ServiceReference
+        as parameter</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="ServiceControllerType">
+    <xs:annotation>
+      <xs:documentation> Defines a service controller. </xs:documentation>
+    </xs:annotation>
+    <xs:attribute name="field" type="xs:string" use="required">
+      <xs:annotation>
+        <xs:documentation> Field of the controller </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="value" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation> Intiail value of the controller </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:complexType name="PropertyType">
+    <xs:annotation>
+      <xs:documentation> Defines a component property. </xs:documentation>
+    </xs:annotation>
+    <xs:attribute name="field" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation> Field of the property </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="method" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation> Setter method of the property. This method is called to inject property
+          value. </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+	<xs:attribute name="constructor-parameter" type="xs:int" use="optional">
+      <xs:annotation>
+        <xs:documentation>The index of the parameter if the property is injected
+        using the constructor.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="name" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation> Name of the property. </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="value" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation> Default value of the property. </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="type" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation> Type of the property. </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="mandatory" type="xs:boolean" use="optional" default="false">
+      <xs:annotation>
+        <xs:documentation>Set the property as mandatory. A mandatory property MUST receive a value
+          either in the component type description or in the instance configuration. Properties are
+          optional by default.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+  <xs:element name="callback" type="CallbackType" id="callback"/>
+  <xs:element name="controller" type="ControllerType" id="controller">
+    <xs:annotation>
+      <xs:documentation/>
+    </xs:annotation>
+  </xs:element>
+  <xs:element name="requires" type="RequiresType" id="requires"/>
+  <xs:element name="component" type="ComponentType" id="component"/>
+  <xs:element name="handler" type="HandlerType" id="handler"/>
+  <xs:element name="instance" type="InstanceType" id="instance"/>
+
+  <xs:element name="properties" type="PropertiesType" id="properties"/>
+  <xs:complexType name="PropertiesType">
+    <xs:annotation>
+      <xs:documentation>List of component, instance or service properties. This field will receive
+        the property value.</xs:documentation>
+    </xs:annotation>
+    <xs:sequence minOccurs="0" maxOccurs="unbounded">
+      <xs:element name="property" type="PropertyType">
+        <xs:annotation>
+          <xs:documentation>The list of properties.</xs:documentation>
+        </xs:annotation>
+      </xs:element>
+    </xs:sequence>
+    <xs:attribute name="propagation" type="xs:boolean" use="optional">
+      <xs:annotation>
+        <xs:documentation>Propagation of the component properties to the provided services. If this
+          parameter is set to "true", each time properties are reconfigured, they are propagated to
+          each service published by the component.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="pid" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Unique identifier used to reconfigure components properties (via Managed
+          Services) with the Configuration Admin.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="updated" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>Method called when a reconfiguration is done</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+
+  <xs:complexType name="ServiceDependencyType">
+    <xs:attribute name="specification" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>The specification describing the required service type. This attribute is
+          needed only when using aggregate dependencies with field injection and when the type of
+          this field is a list, vector, collection and set.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="optional" type="xs:boolean" use="optional">
+      <xs:annotation>
+        <xs:documentation>Sets the service dependency optionality</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="aggregate" type="xs:boolean" use="optional">
+      <xs:annotation>
+        <xs:documentation>Sets the service dependency cardinality.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="policy" use="optional">
+      <xs:annotation>
+        <xs:documentation>Sets the binding policy of the dependency. Three policies are supported.
+          The dynamic policy supports service providers dynamism. The static policy freezes the
+          provider set as soon as the dependency is used. The dynamic-priority policy is an
+          extension of the dynamic policy, but providers are ranked.</xs:documentation>
+      </xs:annotation>
+      <xs:simpleType>
+        <xs:restriction base="xs:string">
+          <xs:enumeration value="dynamic"/>
+          <xs:enumeration value="static"/>
+          <xs:enumeration value="dynamic-priority"/>
+        </xs:restriction>
+      </xs:simpleType>
+    </xs:attribute>
+    <xs:attribute name="comparator" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>The comparator attribute allows specifying the class used to compare
+          providers. This class must implemented the java.util.Comparator class and must support the
+          comparison of service references.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="filter" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>LDAP filter used to filter providers</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+    <xs:attribute name="id" type="xs:string" use="optional">
+      <xs:annotation>
+        <xs:documentation>id of the service dependency. The id allows to indentify and to refert to
+          this dependency.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+
+  <xs:complexType name="ControllerType">
+    <xs:annotation>
+      <xs:documentation>Specifies the lifecycle controller of a component, which allows to validate
+        or invalidate component instances.</xs:documentation>
+    </xs:annotation>
+    <xs:attribute name="field" type="xs:string" use="required">
+      <xs:annotation>
+        <xs:documentation>The name of the component lifecycle controller field. The type of the
+          specified field must be boolean. Setting the value of the specified field to "true" means
+          the validation of the component instance while setting it to "false" means the
+          invalidation of the component instance.</xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
+  </xs:complexType>
+</xs:schema>
diff --git a/ipojo/runtime/core/src/main/resources/metadata.xml b/ipojo/runtime/core/src/main/resources/metadata.xml
new file mode 100644
index 0000000..977b083
--- /dev/null
+++ b/ipojo/runtime/core/src/main/resources/metadata.xml
@@ -0,0 +1,57 @@
+<!--
+	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.
+-->
+<ipojo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/CURRENT/core.xsd"
+       xmlns="org.apache.felix.ipojo">
+    <!-- Primitives handler -->
+    <handler
+            classname="org.apache.felix.ipojo.handlers.lifecycle.controller.ControllerHandler"
+            name="controller" architecture="false"/>
+    <handler
+            classname="org.apache.felix.ipojo.handlers.lifecycle.callback.LifecycleCallbackHandler"
+            name="callback" level="2" architecture="false"/>
+    <handler
+            classname="org.apache.felix.ipojo.handlers.dependency.DependencyHandler"
+            name="requires" level="0" architecture="false">
+        <!-- <controller field="m_state"/>  -->
+    </handler>
+    <handler
+            classname="org.apache.felix.ipojo.handlers.providedservice.ProvidedServiceHandler"
+            name="provides" level="3" architecture="false"/>
+    <handler
+            classname="org.apache.felix.ipojo.handlers.configuration.ConfigurationHandler"
+            name="properties" level="1" architecture="false"/>
+    <handler
+            classname="org.apache.felix.ipojo.handlers.architecture.ArchitectureHandler"
+            name="architecture" architecture="false">
+        <provides specifications="org.apache.felix.ipojo.architecture.Architecture">
+            <property field="m_name" name="architecture.instance"/>
+        </provides>
+    </handler>
+    <!-- iPOJO Online Manipulator -->
+    <component classname="org.apache.felix.ipojo.IPOJOURLHandler"
+               public="false"
+               immediate="true">
+        <provides>
+            <property name="url.handler.protocol" type="java.lang.String" value="ipojo"/>
+        </provides>
+        <callback transition="invalidate" method="stop"/>
+    </component>
+    <instance component="org.apache.felix.ipojo.IPOJOURLHandler"/>
+</ipojo>
\ No newline at end of file
diff --git a/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/SmartProxyTest.java b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/SmartProxyTest.java
new file mode 100644
index 0000000..f1e7005
--- /dev/null
+++ b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/dependency/SmartProxyTest.java
@@ -0,0 +1,115 @@
+package org.apache.felix.ipojo.handlers.dependency;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.felix.ipojo.ComponentFactory;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.test.MockBundle;
+import org.apache.felix.ipojo.util.Logger;
+import org.mockito.Mockito;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+public class SmartProxyTest extends TestCase {
+
+    public void setUp() {
+    }
+
+
+    /**
+     * Check that we don't create smart proxies for concrete and abstract classes.
+     */
+    public void testCannotProxyAbstractAndConcreteClasses() {
+        Bundle bundle = new MockBundle(Dependency.class.getClassLoader());
+
+        BundleContext context = (BundleContext) Mockito.mock(BundleContext.class);
+        Mockito.when(context.getProperty(DependencyHandler.PROXY_TYPE_PROPERTY)).thenReturn(null);
+        Mockito.when(context.getProperty(Logger.IPOJO_LOG_LEVEL_PROP)).thenReturn(null);
+        Mockito.when(context.getBundle()).thenReturn(bundle);
+
+        ComponentFactory factory = (ComponentFactory) Mockito.mock(ComponentFactory.class);
+        Mockito.when(factory.getBundleClassLoader()).thenReturn(Dependency.class.getClassLoader());
+
+        InstanceManager im = (InstanceManager) Mockito.mock(InstanceManager.class);
+        Mockito.when(im.getContext()).thenReturn(context);
+        Mockito.when(im.getFactory()).thenReturn(factory);
+
+        DependencyHandler handler = (DependencyHandler) Mockito.mock(DependencyHandler.class);
+        Mockito.when(handler.getInstanceManager()).thenReturn(im);
+        Logger logger = new Logger(context, "test", Logger.INFO);
+
+
+        Mockito.when(handler.getLogger()).thenReturn(logger);
+
+        Dependency dependency = new Dependency(handler, "a_field", ArrayList.class, null, false, false, false,
+                true, "dep", context, Dependency.DYNAMIC_BINDING_POLICY, null, null);
+        dependency.start();
+
+        // No service
+        Assert.assertNull(dependency.onGet(new Object(), "a_field", null));
+
+        dependency.stop();
+
+        // Try with an Object.
+        dependency = new Dependency(handler, "a_field", Object.class, null, false, false, false,
+                true, "dep", context, Dependency.DYNAMIC_BINDING_POLICY, null, null);
+        dependency.start();
+        // OK
+        Assert.assertNull(dependency.onGet(new Object(), "a_field", null));
+    }
+
+    /**
+     * Tests if we can proxies classes from java.* package.
+     * Indeed, a recent JVM bug fix introduces a bug:
+     * <code>
+     * [ERROR] test : Cannot create the proxy object
+     * java.lang.SecurityException: Prohibited package name: java.awt
+     * </code>
+     */
+    public void testProxiesOfJavaClasses() {
+        Bundle bundle = new MockBundle(Dependency.class.getClassLoader());
+
+        BundleContext context = (BundleContext) Mockito.mock(BundleContext.class);
+        Mockito.when(context.getProperty(DependencyHandler.PROXY_TYPE_PROPERTY)).thenReturn(null);
+        Mockito.when(context.getProperty(Logger.IPOJO_LOG_LEVEL_PROP)).thenReturn(null);
+        Mockito.when(context.getBundle()).thenReturn(bundle);
+
+        ComponentFactory factory = (ComponentFactory) Mockito.mock(ComponentFactory.class);
+        Mockito.when(factory.getBundleClassLoader()).thenReturn(Dependency.class.getClassLoader());
+
+        InstanceManager im = (InstanceManager) Mockito.mock(InstanceManager.class);
+        Mockito.when(im.getContext()).thenReturn(context);
+        Mockito.when(im.getFactory()).thenReturn(factory);
+
+        DependencyHandler handler = (DependencyHandler) Mockito.mock(DependencyHandler.class);
+        Mockito.when(handler.getInstanceManager()).thenReturn(im);
+        Logger logger = new Logger(context, "test", Logger.INFO);
+
+
+        Mockito.when(handler.getLogger()).thenReturn(logger);
+
+        // Try with java.List
+        Dependency dependency = new Dependency(handler, "a_field", List.class, null, false, false, false,
+                true, "dep", context, Dependency.DYNAMIC_BINDING_POLICY, null, null);
+        dependency.start();
+
+        // OK
+        Assert.assertNotNull(dependency.onGet(new Object(), "a_field", null));
+        Assert.assertTrue(dependency.onGet(new Object(), "a_field", null) instanceof List);
+
+        dependency.stop();
+
+        // Try with javax.sql.CommonDataSource
+        dependency = new Dependency(handler, "a_field", javax.sql.CommonDataSource.class, null, false, false, false,
+                true, "dep", context, Dependency.DYNAMIC_BINDING_POLICY, null, null);
+        dependency.start();
+        // OK
+        Assert.assertNotNull(dependency.onGet(new Object(), "a_field", null));
+        Assert.assertTrue(dependency.onGet(new Object(), "a_field", null) instanceof javax.sql.CommonDataSource);
+    }
+
+}
diff --git a/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/providedservice/ComponentTestWithAnotherSuperClass.java b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/providedservice/ComponentTestWithAnotherSuperClass.java
new file mode 100644
index 0000000..7bc4996
--- /dev/null
+++ b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/providedservice/ComponentTestWithAnotherSuperClass.java
@@ -0,0 +1,12 @@
+package org.apache.felix.ipojo.handlers.providedservice;
+
+import java.beans.MethodDescriptor;
+import java.lang.reflect.Method;
+
+public class ComponentTestWithAnotherSuperClass extends MethodDescriptor {
+
+    public ComponentTestWithAnotherSuperClass(Method method) {
+        super(method);
+    }
+
+}
diff --git a/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/providedservice/ComponentTestWithSuperClass.java b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/providedservice/ComponentTestWithSuperClass.java
new file mode 100644
index 0000000..ab61262
--- /dev/null
+++ b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/providedservice/ComponentTestWithSuperClass.java
@@ -0,0 +1,7 @@
+package org.apache.felix.ipojo.handlers.providedservice;
+
+import java.beans.SimpleBeanInfo;
+
+public class ComponentTestWithSuperClass extends SimpleBeanInfo {
+
+}
diff --git a/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerTest.java b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerTest.java
new file mode 100644
index 0000000..0034064
--- /dev/null
+++ b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/handlers/providedservice/ProvidedServiceHandlerTest.java
@@ -0,0 +1,160 @@
+package org.apache.felix.ipojo.handlers.providedservice;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.felix.ipojo.*;
+import org.apache.felix.ipojo.architecture.ComponentTypeDescription;
+import org.apache.felix.ipojo.handlers.dependency.DependencyHandler;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.PojoMetadata;
+import org.apache.felix.ipojo.test.MockBundle;
+import org.apache.felix.ipojo.util.Logger;
+import org.mockito.Mockito;
+import org.osgi.framework.BundleContext;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Dictionary;
+import java.util.Properties;
+
+public class ProvidedServiceHandlerTest extends TestCase {
+
+    BundleContext context;
+    ComponentFactory factory;
+    InstanceManager im;
+    ComponentTypeDescription desc;
+    ProvidedServiceHandler handler;
+    Logger logger;
+
+    public void setUp() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        context = (BundleContext) Mockito.mock(BundleContext.class);
+        Mockito.when(context.getProperty(DependencyHandler.PROXY_TYPE_PROPERTY)).thenReturn(null);
+        Mockito.when(context.getProperty(Logger.IPOJO_LOG_LEVEL_PROP)).thenReturn(null);
+        Mockito.when(context.getBundle()).thenReturn(new MockBundle(this.getClass().getClassLoader()));
+
+        factory = (ComponentFactory) Mockito.mock(ComponentFactory.class);
+        Mockito.when(factory.getBundleClassLoader()).thenReturn(ProvidedServiceHandler.class.getClassLoader());
+        logger = Mockito.spy(new Logger(context, "TEST", Logger.INFO));
+        Mockito.when(factory.getLogger()).thenReturn(logger);
+
+        im = (InstanceManager) Mockito.mock(InstanceManager.class);
+        Mockito.when(im.getContext()).thenReturn(context);
+        Mockito.when(im.getGlobalContext()).thenReturn(context);
+        Mockito.when(im.getFactory()).thenReturn(factory);
+        Mockito.when(im.getInstanceName()).thenReturn("an.instance");
+
+        desc = (ComponentTypeDescription) Mockito.mock(ComponentTypeDescription.class);
+        Mockito.when(desc.getFactory()).thenReturn(factory);
+        Mockito.when(desc.getBundleContext()).thenReturn(context);
+
+        handler = new ProvidedServiceHandler();
+        handler.setFactory(factory);
+
+        // Attach the handler
+        Method method = PrimitiveHandler.class.getDeclaredMethod("attach", new Class[]{ComponentInstance.class});
+        method.setAccessible(true);
+        method.invoke(handler, new Object[]{im});
+
+    }
+
+    public void testServiceDetectionNoInterface() throws ConfigurationException {
+        String classname = "org.apache.felix.ipojo.handlers.providedservice.ComponentTest";
+
+        Element metadata = new Element("component", "");
+        Element manipulation = new Element("manipulation", "");
+        metadata.addAttribute(new Attribute("classname", classname));
+        metadata.addElement(new Element("provides", ""));
+        metadata.addElement(manipulation);
+        manipulation.addAttribute(new Attribute("classname", classname));
+
+        Mockito.when(factory.getPojoMetadata()).thenReturn(new PojoMetadata(metadata));
+        Mockito.when(factory.getClassName()).thenReturn(classname);
+
+        handler.initializeComponentFactory(desc, metadata);
+
+        //Expected behavior: the implementation classname
+        Assert.assertEquals("{org.apache.felix.ipojo.handlers.providedservice.ComponentTest}",
+                metadata.getElements("provides")[0].getAttribute("specifications"));
+    }
+
+    public void testServiceDetectionSuperClass() throws ConfigurationException {
+        String classname = "org.apache.felix.ipojo.handlers.providedservice.ComponentTestWithSuperClass";
+
+        Element metadata = new Element("component", "");
+        Element manipulation = new Element("manipulation", "");
+        metadata.addAttribute(new Attribute("classname", classname));
+        Element provides = new Element("provides", "");
+        provides.addAttribute(new Attribute("specifications", "java.beans.SimpleBeanInfo"));
+        metadata.addElement(provides);
+        metadata.addElement(manipulation);
+        manipulation.addAttribute(new Attribute("classname", classname));
+        manipulation.addAttribute(new Attribute("super", "java.beans.SimpleBeanInfo"));
+        Mockito.when(factory.getPojoMetadata()).thenReturn(new PojoMetadata(metadata));
+        Mockito.when(factory.getClassName()).thenReturn(classname);
+
+        handler.initializeComponentFactory(desc, metadata);
+
+        System.out.println(metadata);
+
+    }
+
+    public void testServiceDetectionImplementationClass() throws ConfigurationException {
+        String classname = "org.apache.felix.ipojo.handlers.providedservice.ComponentTestWithSuperClass";
+
+        Element metadata = new Element("component", "");
+        Element manipulation = new Element("manipulation", "");
+        metadata.addAttribute(new Attribute("classname", classname));
+        Element provides = new Element("provides", "");
+        provides.addAttribute(new Attribute("specifications", classname));
+        metadata.addElement(provides);
+        metadata.addElement(manipulation);
+        manipulation.addAttribute(new Attribute("classname", classname));
+        manipulation.addAttribute(new Attribute("super", "java.beans.SimpleBeanInfo"));
+        Mockito.when(factory.getPojoMetadata()).thenReturn(new PojoMetadata(metadata));
+        Mockito.when(factory.getClassName()).thenReturn(classname);
+
+        handler.initializeComponentFactory(desc, metadata);
+
+        System.out.println(metadata);
+
+    }
+
+    public void testServiceDetectionSuperSuperClass() throws ConfigurationException {
+        String classname = "org.apache.felix.ipojo.handlers.providedservice.ComponentTestWithAnotherSuperClass";
+
+        Element metadata = new Element("component", "");
+        Element manipulation = new Element("manipulation", "");
+        metadata.addAttribute(new Attribute("classname", classname));
+        Element provides = new Element("provides", "");
+        provides.addAttribute(new Attribute("specifications", "java.beans.FeatureDescriptor"));
+        metadata.addElement(provides);
+        metadata.addElement(manipulation);
+        manipulation.addAttribute(new Attribute("classname", classname));
+        manipulation.addAttribute(new Attribute("super", "java.beans.MethodDescriptor"));
+
+        Mockito.when(factory.getPojoMetadata()).thenReturn(new PojoMetadata(metadata));
+        Mockito.when(factory.getClassName()).thenReturn(classname);
+
+        handler.initializeComponentFactory(desc, metadata);
+
+        System.out.println(metadata);
+
+    }
+
+    public void testWhenRequiresFilterIsPropagated() throws Exception {
+        Dictionary dictionary = new Properties();
+        Dictionary requiresfilter = new Properties();
+        requiresfilter.put("id1", "(filter1)");
+        dictionary.put("requires.filter", requiresfilter);
+
+
+        ProvidedService providedService = new ProvidedService(handler, new String[] {Runnable.class.getName()}, ProvidedService.SINGLETON_STRATEGY, null, new Properties());
+        Assert.assertEquals(2, providedService.getProperties().length); // instance.name, service.pid
+        providedService.addProperties(dictionary);
+
+        Assert.assertEquals(2 + 1, providedService.getProperties().length);
+    }
+
+}
diff --git a/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/ManipulationMetadataTest.java b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/ManipulationMetadataTest.java
new file mode 100644
index 0000000..7658320
--- /dev/null
+++ b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/ManipulationMetadataTest.java
@@ -0,0 +1,257 @@
+/*
+ * 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.parser;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.jar.Manifest;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.ipojo.metadata.Element;
+
+/**
+ * Check manipulation metadata written in the manifest.
+ */
+public class ManipulationMetadataTest extends TestCase {
+
+	private String header;
+
+	public void setUp() {
+		File manFile = new File("src/test/resources/manipulation/MANIFEST.MF");
+		Manifest manifest;
+		try {
+			manifest = new Manifest(new FileInputStream(manFile));
+			header = manifest.getMainAttributes().getValue("iPOJO-Components");
+		} catch (FileNotFoundException e) {
+			fail(e.getMessage());
+		} catch (IOException e) {
+			fail(e.getMessage());
+		}
+	}
+
+	public void testGetMetadata() {
+		Element elem = null;
+		try {
+			elem = ManifestMetadataParser.parseHeaderMetadata(header);
+		} catch (ParseException e) {
+			fail("Parse Exception when parsing iPOJO-Component");
+		}
+
+		assertNotNull("Check elem not null", elem);
+
+		Element manip = getManipulationForComponent(elem, "ManipulationMetadata-FooProviderType-1");
+		assertNotNull("Check manipulation metadata not null for " + "FooProviderType-1", manip);
+	}
+
+	public void testInterface() {
+		String comp_name = "ManipulationMetadata-FooProviderType-1";
+		Element manip = getManipulationForComponent(comp_name);
+		Element[] itf = manip.getElements("Interface");
+		assertEquals("Check interfaces number", itf.length, 1);
+		assertEquals("Check itf name", itf[0].getAttribute("name"),
+				"org.apache.felix.ipojo.test.scenarios.manipulation.service.FooService");
+	}
+
+	public void testInterfaces() {
+		String comp_name = "ManipulationMetadata-FooBarProviderType-1";
+		Element manip = getManipulationForComponent(comp_name);
+		Element[] itf = manip.getElements("Interface");
+		assertEquals("Check interfaces number", itf.length, 2);
+		assertEquals("Check itf name", itf[0].getAttribute("name"),
+				"org.apache.felix.ipojo.test.scenarios.manipulation.service.FooService");
+		assertEquals("Check itf name", itf[1].getAttribute("name"),
+				"org.apache.felix.ipojo.test.scenarios.manipulation.service.BarService");
+	}
+
+	public void testFields() {
+		String comp_name = "ManipulationMetadata-FooProviderType-Dyn";
+		Element manip = getManipulationForComponent(comp_name);
+		Element[] fields = manip.getElements("field");
+		assertEquals("Check field count " + fields.length, fields.length, 5);
+		/*
+		private int intProp;
+		private String strProp;
+		private String[] strAProp;
+		private int[] intAProp;
+		private boolean boolProp;
+		 */
+
+		Element field;
+
+		field = getFieldFromName(manip, "intProp");
+		assertEquals("Check field name : " + field.getAttribute("name"), field.getAttribute("name"), "intProp");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "int");
+
+		field = getFieldFromName(manip, "strProp");
+		assertEquals("Check field name : " + field.getAttribute("name"), field.getAttribute("name"), "strProp");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "java.lang.String");
+
+		field = getFieldFromName(manip, "strAProp");
+		assertEquals("Check field name : " + field.getAttribute("name"), field.getAttribute("name"), "strAProp");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "java.lang.String[]");
+
+		field = getFieldFromName(manip, "intAProp");
+		assertEquals("Check field name : " + field.getAttribute("name"), field.getAttribute("name"), "intAProp");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "int[]");
+
+		field = getFieldFromName(manip, "boolProp");
+		assertEquals("Check field name : " + field.getAttribute("name"), field.getAttribute("name"), "boolProp");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "boolean");
+	}
+
+	public void testPrimitivesFields() {
+		String comp_name = "ManipulationMetadata-PrimitiveManipulationTester";
+		Element manip = getManipulationForComponent(comp_name);
+		Element[] fields = manip.getElements("Field");
+		assertEquals("Check field count", fields.length, 16);
+		/*
+		byte b = 1;
+		short s = 1;
+		int i = 1;
+		long l = 1;
+		double d = 1.1;
+		float f = 1.1f;
+		char c = 'a';
+		boolean bool = false;
+		byte[] bs = new byte[] {0,1,2};
+		short[] ss = new short[] {0,1,2};
+		int[] is = new int[] {0,1,2};
+		long[] ls = new long[] {0,1,2};
+		double[] ds = new double[] {0.0, 1.1, 2.2};
+		float[] fs = new float[] {0.0f, 1.1f, 2.2f};
+		char[] cs = new char[] {'a', 'b', 'c'};
+		boolean[] bools = new boolean[] {false, true, false};
+		 */
+		Element field;
+
+		field = getFieldFromName(manip, "b");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "byte");
+		field = getFieldFromName(manip, "s");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "short");
+		field = getFieldFromName(manip, "i");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "int");
+		field = getFieldFromName(manip, "l");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "long");
+		field = getFieldFromName(manip, "d");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "double");
+		field = getFieldFromName(manip, "f");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "float");
+		field = getFieldFromName(manip, "c");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "char");
+		field = getFieldFromName(manip, "bool");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "boolean");
+
+		field = getFieldFromName(manip, "bs");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "byte[]");
+		field = getFieldFromName(manip, "ss");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "short[]");
+		field = getFieldFromName(manip, "is");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "int[]");
+		field = getFieldFromName(manip, "ls");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "long[]");
+		field = getFieldFromName(manip, "ds");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "double[]");
+		field = getFieldFromName(manip, "fs");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "float[]");
+		field = getFieldFromName(manip, "cs");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "char[]");
+		field = getFieldFromName(manip, "bools");
+		assertEquals("Check field type : " + field.getAttribute("name"), field.getAttribute("type"), "boolean[]");
+	}
+
+	public void testNoArgMethod() {
+		String comp_name = "ManipulationMetadata-SimpleMultipleCheckServiceProvider";
+		Element manip = getManipulationForComponent(comp_name);
+		Element method = getMethodFromName(manip, "check");
+		assertFalse("Check no args", method.containsAttribute("arguments"));
+		assertEquals("Check return", method.getAttribute("return"), "boolean");
+	}
+
+	public void testOneArgsMethod() {
+		String comp_name = "ManipulationMetadata-SimpleMultipleCheckServiceProvider";
+		Element manip = getManipulationForComponent(comp_name);
+		Element method = getMethodFromName(manip, "refBind");
+		assertEquals("Check args", method.getAttribute("arguments"), "{org.osgi.framework.ServiceReference}");
+		assertEquals("Check args count", 1, ParseUtils.parseArrays("{org.osgi.framework.ServiceReference}").length);
+		assertFalse("Check return", method.containsAttribute("return"));
+	}
+
+	public void testTwoArgsMethod() {
+		String comp_name = "ManipulationMetadata-SimpleMultipleCheckServiceProvider";
+		Element manip = getManipulationForComponent(comp_name);
+		Element method = getMethodFromName(manip, "doNothing");
+		assertEquals("Check args", method.getAttribute("arguments"), "{java.lang.Object,java.lang.String}");
+		assertEquals("Check args count", 2, ParseUtils.parseArrays("{java.lang.Object,java.lang.String}").length);
+		assertEquals("Check return", method.getAttribute("return"), "java.lang.Object");
+	}
+
+	private Element getManipulationForComponent(Element metadata, String comp_name) {
+		Element[] comps = metadata.getElements("component");
+		for(int i = 0; i < comps.length; i++) {
+			if(comps[i].containsAttribute("factory") && comps[i].getAttribute("factory").equals(comp_name)) {
+				return comps[i].getElements("manipulation")[0];
+			}
+            if(comps[i].containsAttribute("name") && comps[i].getAttribute("name").equals(comp_name)) {
+                return comps[i].getElements("manipulation")[0];
+            }
+		}
+		return null;
+	}
+
+	private Element getManipulationForComponent(String comp_name) {
+		Element elem = null;
+		try {
+			elem = ManifestMetadataParser.parseHeaderMetadata(header);
+		} catch (ParseException e) {
+			fail("Parse Exception when parsing iPOJO-Component");
+		}
+
+		assertNotNull("Check elem not null", elem);
+		Element manip = getManipulationForComponent(elem, comp_name);
+		assertNotNull("Check manipulation metadata not null for " + comp_name, manip);
+		return manip;
+	}
+
+	private Element getMethodFromName(Element manip, String name) {
+		Element methods[] = manip.getElements("Method");
+		for(int i = 0; i < methods.length; i++) {
+			if(methods[i].containsAttribute("name") && methods[i].getAttribute("name").equals(name)) {
+				return methods[i];
+			}
+		}
+		fail("Method " + name + " not found");
+		return null;
+	}
+
+	private Element getFieldFromName(Element manip, String name) {
+		Element fields[] = manip.getElements("Field");
+		for(int i = 0; i < fields.length; i++) {
+			if(fields[i].containsAttribute("name") && fields[i].getAttribute("name").equals(name)) {
+				return fields[i];
+			}
+		}
+		fail("Field " + name + " not found");
+		return null;
+	}
+
+
+}
diff --git a/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/PojoMetadataTest.java b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/PojoMetadataTest.java
new file mode 100644
index 0000000..050590f
--- /dev/null
+++ b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/parser/PojoMetadataTest.java
@@ -0,0 +1,322 @@
+/*
+ * 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.parser;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.jar.Manifest;
+
+import junit.framework.TestCase;
+
+import org.apache.felix.ipojo.ConfigurationException;
+import org.apache.felix.ipojo.metadata.Element;
+
+public class PojoMetadataTest extends TestCase {
+
+    PojoMetadata FooProviderType1, FooBarProviderType1, FooProviderTypeDyn, PrimitiveManipulationTester, SimpleMultipleCheckServiceProvider;
+
+    private String header;
+
+	public void setUp() {
+		File manFile = new File("src/test/resources/manipulation/MANIFEST.MF");
+		Manifest manifest;
+		try {
+			manifest = new Manifest(new FileInputStream(manFile));
+			header = manifest.getMainAttributes().getValue("iPOJO-Components");
+		} catch (FileNotFoundException e) {
+			fail(e.getMessage());
+		} catch (IOException e) {
+			fail(e.getMessage());
+		}
+
+        String comp_name = "ManipulationMetadata-FooProviderType-1";
+        FooProviderType1 = getManipulationMetadataForComponent(comp_name);
+
+        comp_name = "ManipulationMetadata-FooBarProviderType-1";
+        FooBarProviderType1 = getManipulationMetadataForComponent(comp_name);
+
+        comp_name = "ManipulationMetadata-FooProviderType-Dyn";
+        FooProviderTypeDyn = getManipulationMetadataForComponent(comp_name);
+
+        comp_name = "ManipulationMetadata-PrimitiveManipulationTester";
+        PrimitiveManipulationTester = getManipulationMetadataForComponent(comp_name);
+
+        comp_name = "ManipulationMetadata-SimpleMultipleCheckServiceProvider";
+        SimpleMultipleCheckServiceProvider = getManipulationMetadataForComponent(comp_name);
+	}
+
+	public void testGetMetadata() {
+		Element elem = null;
+		try {
+			elem = ManifestMetadataParser.parseHeaderMetadata(header);
+		} catch (ParseException e) {
+			fail("Parse Exception when parsing iPOJO-Component");
+		}
+
+		assertNotNull("Check elem not null", elem);
+
+		Element manip = getMetadataForComponent(elem, "ManipulationMetadata-FooProviderType-1");
+        assertNotNull("Check manipulation metadata not null for " + "Manipulation-FooProviderType-1", manip);
+        PojoMetadata mm;
+        try {
+            mm = new PojoMetadata(manip);
+            assertNotNull("Check mm not null", mm);
+        } catch (ConfigurationException e) {
+            fail("The creation of pojo metadata has failed");
+        }
+	}
+
+	public void testInterface() {
+	    PojoMetadata manip = FooProviderType1;
+
+        String[] itf = manip.getInterfaces();
+		assertEquals("Check interfaces number", itf.length, 1);
+		assertEquals("Check itf name", itf[0], "org.apache.felix.ipojo.test.scenarios.manipulation.service.FooService");
+
+        assertTrue("Check Foo Service implementation", manip.isInterfaceImplemented("org.apache.felix.ipojo.test.scenarios.manipulation.service.FooService"));
+        assertFalse("Check Bar Service implementation", manip.isInterfaceImplemented("org.apache.felix.ipojo.test.scenarios.manipulation.service.BarService"));
+	}
+
+	public void testInterfaces() {
+	    PojoMetadata manip = FooBarProviderType1;
+        String[] itf = manip.getInterfaces();
+		assertEquals("Check interfaces number", itf.length, 2);
+		assertEquals("Check itf name", itf[0], "org.apache.felix.ipojo.test.scenarios.manipulation.service.FooService");
+		assertEquals("Check itf name", itf[1], "org.apache.felix.ipojo.test.scenarios.manipulation.service.BarService");
+
+        assertTrue("Check Foo Service implementation", manip.isInterfaceImplemented("org.apache.felix.ipojo.test.scenarios.manipulation.service.FooService"));
+        assertTrue("Check Bar Service implementation", manip.isInterfaceImplemented("org.apache.felix.ipojo.test.scenarios.manipulation.service.BarService"));
+	}
+
+	public void testFields() {
+	    PojoMetadata manip = FooProviderTypeDyn;
+
+		FieldMetadata[] fields = manip.getFields();
+		assertEquals("Check field count + " + fields.length, fields.length, 5);
+		/*
+		private int intProp;
+		private String strProp;
+		private String[] strAProp;
+		private int[] intAProp;
+		private boolean boolProp;
+		 */
+
+		FieldMetadata field;
+
+		field = manip.getField("intProp");
+		assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "intProp");
+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int");
+        assertEquals("Check field reflective type : " + field.getFieldName(), FieldMetadata.getReflectionType(field.getFieldType()), "int");
+
+        field = manip.getField("intProp", "int");
+        assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "intProp");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int");
+
+        field = manip.getField("intProp", "long");
+        assertNull("Check bad field", field);
+
+		field = manip.getField("strProp");
+		assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "strProp");
+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "java.lang.String");
+        assertEquals("Check field reflective type : " + field.getFieldName(), FieldMetadata.getReflectionType(field.getFieldType()), "java.lang.String");
+
+        field = manip.getField("strProp", "String");
+        assertNull("Check bad field", field);
+
+        field = manip.getField("strProp", "java.lang.String");
+        assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "strProp");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "java.lang.String");
+
+		field = manip.getField("strAProp");
+		assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "strAProp");
+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "java.lang.String[]");
+        assertEquals("Check field reflective type : " + field.getFieldName() + " -> " + FieldMetadata.getReflectionType(field.getFieldType()), FieldMetadata.getReflectionType(field.getFieldType()), "[Ljava.lang.String;");
+
+        field = manip.getField("strAProp", "java.lang.String[]");
+        assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "strAProp");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "java.lang.String[]");
+
+        field = manip.getField("strAProp", "String[]");
+        assertNull("Check bad field", field);
+
+		field = manip.getField("intAProp");
+		assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "intAProp");
+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int[]");
+        assertEquals("Check field reflective type : " + field.getFieldName() + " -> " + FieldMetadata.getReflectionType(field.getFieldType()), FieldMetadata.getReflectionType(field.getFieldType()), "[I");
+
+        field = manip.getField("intAProp", "int[]");
+        assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "intAProp");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int[]");
+
+        field = manip.getField("intAProp", "String[]");
+        assertNull("Check bad field", field);
+
+		field = manip.getField("boolProp");
+		assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "boolProp");
+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "boolean");
+        assertEquals("Check field reflective type : " + field.getFieldName(), FieldMetadata.getReflectionType(field.getFieldType()), "boolean");
+
+        field = manip.getField("boolProp", "boolean");
+        assertEquals("Check field name : " + field.getFieldName(), field.getFieldName(), "boolProp");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "boolean");
+
+        field = manip.getField("boolProp", "bool");
+        assertNull("Check bad field", field);
+	}
+
+	public void testPrimitivesFields() {
+	    PojoMetadata manip = PrimitiveManipulationTester;
+		FieldMetadata[] fields = manip.getFields();
+		assertEquals("Check field count", fields.length, 16);
+
+		FieldMetadata field;
+
+		field = manip.getField("b");
+		assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "byte");
+		field = manip.getField("s");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "short");
+		field = manip.getField("i");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int");
+		field = manip.getField("l");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "long");
+		field = manip.getField("d");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "double");
+		field = manip.getField("f");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "float");
+		field = manip.getField("c");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "char");
+		field = manip.getField("bool");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "boolean");
+
+		field = manip.getField("bs");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "byte[]");
+		field = manip.getField("ss");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "short[]");
+		field = manip.getField("is");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "int[]");
+		field = manip.getField("ls");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "long[]");
+		field = manip.getField("ds");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "double[]");
+		field = manip.getField("fs");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "float[]");
+		field = manip.getField("cs");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "char[]");
+		field = manip.getField("bools");
+        assertEquals("Check field type : " + field.getFieldName(), field.getFieldType(), "boolean[]");
+	}
+
+	public void testNoArgMethod() {
+	    PojoMetadata manip = SimpleMultipleCheckServiceProvider;
+		MethodMetadata method = manip.getMethod("check");
+		assertEquals("Check no args", method.getMethodArguments().length, 0);
+		assertEquals("Check return", method.getMethodReturn(), "boolean");
+
+        method = manip.getMethod("check", new String[0]);
+        assertEquals("Check no args", method.getMethodArguments().length, 0);
+        assertEquals("Check return", method.getMethodReturn(), "boolean");
+	}
+
+	public void testOneArgsMethod() {
+	    PojoMetadata manip = SimpleMultipleCheckServiceProvider;
+        MethodMetadata method = manip.getMethods("refBind")[0];
+		assertEquals("Check args count", method.getMethodArguments().length, 1);
+        assertEquals("Check args", method.getMethodArguments()[0], "org.osgi.framework.ServiceReference");
+		assertEquals("Check return", method.getMethodReturn(), "void");
+
+        method = manip.getMethod("refBind", new String[] {"org.osgi.framework.ServiceReference"});
+        assertEquals("Check args count", method.getMethodArguments().length, 1);
+        assertEquals("Check args", method.getMethodArguments()[0], "org.osgi.framework.ServiceReference");
+        assertEquals("Check return", method.getMethodReturn(), "void");
+	}
+
+	public void testTwoArgsMethod() {
+	    PojoMetadata manip = SimpleMultipleCheckServiceProvider;
+        MethodMetadata method = manip.getMethods("doNothing")[0];
+        assertEquals("Check args count", 2, method.getMethodArguments().length);
+		assertEquals("Check args - 1", method.getMethodArguments()[0], "java.lang.Object");
+        assertEquals("Check args - 2", method.getMethodArguments()[1], "java.lang.String");
+		assertEquals("Check return", method.getMethodReturn(), "java.lang.Object");
+
+        method = manip.getMethod("doNothing", new String[] {"java.lang.Object", "java.lang.String"});
+        assertEquals("Check args count", 2, method.getMethodArguments().length);
+        assertEquals("Check args - 1", method.getMethodArguments()[0], "java.lang.Object");
+        assertEquals("Check args - 2", method.getMethodArguments()[1], "java.lang.String");
+        assertEquals("Check return", method.getMethodReturn(), "java.lang.Object");
+	}
+
+	public void testSuper() {
+		String comp_name = "org.apache.felix.ipojo.test.scenarios.component.Child";
+		PojoMetadata manip = getManipulationMetadataForComponent(comp_name);
+		assertEquals("org.apache.felix.ipojo.test.scenarios.component.Parent", manip.getSuperClass());
+		assertEquals(1, manip.getConstructors().length);
+	}
+
+	public void testConstructors() {
+		String comp_name = "org.apache.felix.ipojo.test.scenarios.component.Multiconstructor";
+		PojoMetadata manip = getManipulationMetadataForComponent(comp_name);
+		assertEquals(3, manip.getConstructors().length);
+		assertNotNull(manip.getConstructor(new String[] {String.class.getName(), String.class.getName()}));
+		assertNotNull(manip.getConstructor(new String[] {String.class.getName(), String.class.getName(), Integer.TYPE.getName()}));
+		assertNotNull(manip.getConstructor(new String[] {String.class.getName(), Integer.TYPE.getName()}));
+		assertNull(manip.getConstructor(new String[] {String.class.getName()}));
+	}
+
+
+	private Element getMetadataForComponent(Element metadata, String comp_name) {
+		Element[] comps = metadata.getElements("component");
+		for(int i = 0; i < comps.length; i++) {
+			if(comps[i].containsAttribute("factory") && comps[i].getAttribute("factory").equals(comp_name)) {
+				return comps[i];
+			}
+            if(comps[i].containsAttribute("name") && comps[i].getAttribute("name").equals(comp_name)) {
+                return comps[i];
+            }
+            if(comps[i].containsAttribute("classname") && comps[i].getAttribute("classname").equals(comp_name)) {
+                return comps[i];
+            }
+		}
+		return null;
+	}
+
+
+    private PojoMetadata getManipulationMetadataForComponent(String comp_name) {
+        Element elem = null;
+        try {
+            elem = ManifestMetadataParser.parseHeaderMetadata(header);
+        } catch (ParseException e) {
+            e.printStackTrace();
+            fail("Parse Exception when parsing iPOJO-Component " + e);
+        }
+
+        assertNotNull("Check elem not null", elem);
+
+        Element manip = getMetadataForComponent(elem, comp_name);
+        assertNotNull("Check manipulation metadata not null for " + comp_name, manip);
+        try {
+            return new PojoMetadata(manip);
+        } catch (ConfigurationException e) {
+            fail("The creation of pojo metadata for " + comp_name + " has failed");
+            return null;
+        }
+    }
+
+}
diff --git a/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/test/MockBundle.java b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/test/MockBundle.java
new file mode 100644
index 0000000..ddca7e6
--- /dev/null
+++ b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/test/MockBundle.java
@@ -0,0 +1,172 @@
+package org.apache.felix.ipojo.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.security.cert.X509Certificate;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+
+import org.osgi.framework.*;
+
+public class MockBundle implements Bundle {
+
+    private final ClassLoader m_classloader;
+
+    /**
+     * @param cl the Classloader to load classes and resources.
+     */
+    public MockBundle(ClassLoader cl) {
+        m_classloader = cl;
+    }
+
+    public int getState() {
+        return 0;
+    }
+
+    public void start(int i) throws BundleException {
+    }
+
+    public void start() throws BundleException {
+    }
+
+    public void stop(int i) throws BundleException {
+    }
+
+    public void stop() throws BundleException {
+    }
+
+    public void update() throws BundleException {
+    }
+
+    public void update(InputStream in) throws BundleException {
+    }
+
+    public void uninstall() throws BundleException {
+    }
+
+    public Dictionary getHeaders() {
+        return null;
+    }
+
+    public long getBundleId() {
+        return 1; // 0 is the system bundle
+    }
+
+    public String getLocation() {
+        return null;
+    }
+
+    public ServiceReference[] getRegisteredServices() {
+        return null;
+    }
+
+    public ServiceReference[] getServicesInUse() {
+        return null;
+    }
+
+    public boolean hasPermission(Object permission) {
+        return false;
+    }
+
+    public URL getResource(String name) {
+        return m_classloader.getResource(name);
+    }
+
+    public Dictionary getHeaders(String locale) {
+        return null;
+    }
+
+    public String getSymbolicName() {
+        return null;
+    }
+
+    public Class loadClass(String name) throws ClassNotFoundException {
+        return m_classloader.loadClass(name);
+    }
+
+    public Enumeration getResources(String name) throws IOException {
+        return m_classloader.getResources(name);
+    }
+
+    public Enumeration getEntryPaths(String path) {
+        return null;
+    }
+
+    public URL getEntry(String name) {
+        return null;
+    }
+
+    public long getLastModified() {
+        return 0;
+    }
+
+    public Enumeration findEntries(String path, String filePattern,
+            boolean recurse) {
+        return null;
+    }
+
+    public BundleContext getBundleContext() {
+        return null;
+    }
+
+    public Map<X509Certificate, List<X509Certificate>> getSignerCertificates(int i) {
+        return null;
+    }
+
+    public Version getVersion() {
+        return null;
+    }
+
+    public <A> A adapt(Class<A> aClass) {
+        return null;
+    }
+
+    public File getDataFile(String s) {
+        return null;
+    }
+
+    /**
+     * Compares this object with the specified object for order.  Returns a
+     * negative integer, zero, or a positive integer as this object is less
+     * than, equal to, or greater than the specified object.
+     * <p/>
+     * <p>The implementor must ensure <tt>sgn(x.compareTo(y)) ==
+     * -sgn(y.compareTo(x))</tt> for all <tt>x</tt> and <tt>y</tt>.  (This
+     * implies that <tt>x.compareTo(y)</tt> must throw an exception iff
+     * <tt>y.compareTo(x)</tt> throws an exception.)
+     * <p/>
+     * <p>The implementor must also ensure that the relation is transitive:
+     * <tt>(x.compareTo(y)&gt;0 &amp;&amp; y.compareTo(z)&gt;0)</tt> implies
+     * <tt>x.compareTo(z)&gt;0</tt>.
+     * <p/>
+     * <p>Finally, the implementor must ensure that <tt>x.compareTo(y)==0</tt>
+     * implies that <tt>sgn(x.compareTo(z)) == sgn(y.compareTo(z))</tt>, for
+     * all <tt>z</tt>.
+     * <p/>
+     * <p>It is strongly recommended, but <i>not</i> strictly required that
+     * <tt>(x.compareTo(y)==0) == (x.equals(y))</tt>.  Generally speaking, any
+     * class that implements the <tt>Comparable</tt> interface and violates
+     * this condition should clearly indicate this fact.  The recommended
+     * language is "Note: this class has a natural ordering that is
+     * inconsistent with equals."
+     * <p/>
+     * <p>In the foregoing description, the notation
+     * <tt>sgn(</tt><i>expression</i><tt>)</tt> designates the mathematical
+     * <i>signum</i> function, which is defined to return one of <tt>-1</tt>,
+     * <tt>0</tt>, or <tt>1</tt> according to whether the value of
+     * <i>expression</i> is negative, zero or positive.
+     *
+     * @param o the object to be compared.
+     * @return a negative integer, zero, or a positive integer as this object
+     *         is less than, equal to, or greater than the specified object.
+     * @throws ClassCastException if the specified object's type prevents it
+     *                            from being compared to this object.
+     */
+    public int compareTo(Bundle o) {
+        return 0;
+    }
+}
\ No newline at end of file
diff --git a/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/util/ManifestMetadataParserTest.java b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/util/ManifestMetadataParserTest.java
new file mode 100644
index 0000000..eaaae70
--- /dev/null
+++ b/ipojo/runtime/core/src/test/java/org/apache/felix/ipojo/util/ManifestMetadataParserTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.util;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+
+/**
+ * Test the {@link ManifestMetadataParser}
+ */
+public class ManifestMetadataParserTest extends TestCase {
+
+	/**
+	 * Test FELIX-2685.
+	 * The element name contains ':' as in:
+	 * "//jasmine.ow2.org/rules/1.0.0:configuration"
+	 * @throws ParseException
+	 */
+	public void testNameWithColumn() throws ParseException {
+		// Create a test element
+		String header = "http://jasmine.ow2.org/rules/1.0.0:configuration {}";
+		Element elem = ManifestMetadataParser.parse(header);
+
+		Assert.assertEquals("http://jasmine.ow2.org/rules/1.0.0", elem.getNameSpace());
+		Assert.assertEquals("configuration", elem.getName());
+	}
+
+	/**
+	 * Check the parsing of handler element using {@link ManifestMetadataParser#parseHeader(String)}
+	 * @throws ParseException
+	 */
+	public void testHandlerHeader() throws ParseException {
+		String header = "handler { $name=\"wbp\" $classname=\"org.apache.felix.ipojo.handler.wbp.WhiteBoardPatternHandler\"" +
+				" $namespace=\"org.apache.felix.ipojo.whiteboard\" manipulation { $super=\"org.apache.felix.ipojo.PrimitiveHandler\"" +
+				" field { $name=\"m_managers\" $type=\"java.util.List\" }method { $name=\"$init\" }method { $arguments=" +
+				"\"{org.apache.felix.ipojo.metadata.Element,java.util.Dictionary}\" $name=\"configure\" }method { $name=\"start\"" +
+				" }method { $arguments=\"{int}\" $name=\"stateChanged\" }method { $name=\"stop\" }}}";
+
+		ManifestMetadataParser parser = new ManifestMetadataParser();
+		parser.parseHeader(header);
+
+		Element[] elems = parser.getComponentsMetadata();
+		Assert.assertEquals(1, elems.length);
+
+		Element element = elems[0];
+		Assert.assertEquals("handler", element.getName());
+		Assert.assertNull(element.getNameSpace());
+
+		Assert.assertEquals("wbp", element.getAttribute("name"));
+		Assert.assertEquals("org.apache.felix.ipojo.handler.wbp.WhiteBoardPatternHandler", element.getAttribute("classname"));
+		Assert.assertEquals("org.apache.felix.ipojo.whiteboard", element.getAttribute("namespace"));
+
+		// Check the manipulation element
+		Element[] manip = element.getElements("manipulation");
+		Assert.assertNotNull(manip[0]);
+
+		Element[] methods = manip[0].getElements("method");
+		Assert.assertEquals(5, methods.length);
+	}
+
+	/**
+	 * Check the parsing of handler element using {@link ManifestMetadataParser#parseHeaderMetadata(String)}
+	 * @throws ParseException
+	 */
+	public void testHandlerHeader2() throws ParseException {
+		String header = "handler { $name=\"wbp\" $classname=\"org.apache.felix.ipojo.handler.wbp.WhiteBoardPatternHandler\"" +
+				" $namespace=\"org.apache.felix.ipojo.whiteboard\" manipulation { $super=\"org.apache.felix.ipojo.PrimitiveHandler\"" +
+				" field { $name=\"m_managers\" $type=\"java.util.List\" }method { $name=\"$init\" }method { $arguments=" +
+				"\"{org.apache.felix.ipojo.metadata.Element,java.util.Dictionary}\" $name=\"configure\" }method { $name=\"start\"" +
+				" }method { $arguments=\"{int}\" $name=\"stateChanged\" }method { $name=\"stop\" }}}";
+
+		// This method returns an iPOJO root element
+		Element elem = ManifestMetadataParser.parseHeaderMetadata(header);
+		Element element = elem.getElements("handler")[0];
+
+		Assert.assertEquals("handler", element.getName());
+		Assert.assertNull(element.getNameSpace());
+
+		Assert.assertEquals("wbp", element.getAttribute("name"));
+		Assert.assertEquals("org.apache.felix.ipojo.handler.wbp.WhiteBoardPatternHandler", element.getAttribute("classname"));
+		Assert.assertEquals("org.apache.felix.ipojo.whiteboard", element.getAttribute("namespace"));
+
+		// Check the manipulation element
+		Element[] manip = element.getElements("manipulation");
+		Assert.assertNotNull(manip[0]);
+
+		Element[] methods = manip[0].getElements("method");
+		Assert.assertEquals(5, methods.length);
+	}
+
+}
diff --git a/ipojo/runtime/core/src/test/resources/manipulation/MANIFEST.MF b/ipojo/runtime/core/src/test/resources/manipulation/MANIFEST.MF
new file mode 100644
index 0000000..4becd87
--- /dev/null
+++ b/ipojo/runtime/core/src/test/resources/manipulation/MANIFEST.MF
@@ -0,0 +1,142 @@
+Manifest-Version: 1.0
+Export-Package: org.apache.felix.ipojo.test.scenarios.manipulation.ser
+ vice
+iPOJO-Components: component { $name="ManipulationMetadata-FooProviderT
+ ype-1" $classname="org.apache.felix.ipojo.test.scenarios.component.Fo
+ oProviderType1" $architecture="true" provides { }manipulation { field
+  { $name="m_context" $type="org.osgi.framework.BundleContext" }field 
+ { $name="m_foo" $type="java.lang.String" }field { $name="m_bar" $type
+ ="int" }method { $arguments="{org.osgi.framework.BundleContext}" $nam
+ e="singleton" $return="org.apache.felix.ipojo.test.scenarios.componen
+ t.FooProviderType1" }method { $arguments="{org.osgi.framework.BundleC
+ ontext}" $name="several" $return="org.apache.felix.ipojo.test.scenari
+ os.component.FooProviderType1" }method { $arguments="{org.osgi.framew
+ ork.BundleContext}" $name="$init" }method { $name="foo" $return="bool
+ ean" }method { $name="fooProps" $return="java.util.Properties" }metho
+ d { $name="testException" }method { $name="testTry" }method { $argume
+ nts="{java.lang.String}" $name="testTry2" }method { $arguments="{java
+ .lang.String}" $name="nexttry" }method { $name="getBoolean" $return="
+ boolean" }method { $name="getDouble" $return="double" }method { $name
+ ="getInt" $return="int" }method { $name="getLong" $return="long" }met
+ hod { $name="getObject" $return="java.lang.Boolean" }method { $argume
+ nts="{int,java.lang.String,org.osgi.framework.BundleContext}" $name="
+ $init" }interface { $name="org.apache.felix.ipojo.test.scenarios.mani
+ pulation.service.FooService" }}}component { $name="ManipulationMetada
+ ta-FooBarProviderType-1" $classname="org.apache.felix.ipojo.test.scen
+ arios.component.FooBarProviderType1" $architecture="true" provides { 
+ }manipulation { method { $name="$init" }method { $name="foo" $return=
+ "boolean" }method { $name="fooProps" $return="java.util.Properties" }
+ method { $name="bar" $return="boolean" }method { $name="getProps" $re
+ turn="java.util.Properties" }method { $name="getBoolean" $return="boo
+ lean" }method { $name="getDouble" $return="double" }method { $name="g
+ etInt" $return="int" }method { $name="getLong" $return="long" }method
+  { $name="getObject" $return="java.lang.Boolean" }interface { $name="
+ org.apache.felix.ipojo.test.scenarios.manipulation.service.FooService
+ " }interface { $name="org.apache.felix.ipojo.test.scenarios.manipulat
+ ion.service.BarService" }}}component { $name="ManipulationMetadata-Fo
+ oProviderType-Dyn" $classname="org.apache.felix.ipojo.test.scenarios.
+ component.FooProviderTypeDyn" $architecture="true" provides { propert
+ y { $field="intProp" $mandatory="false" $name="int" $value="2" }prope
+ rty { $field="boolProp" $mandatory="false" $name="boolean" $value="fa
+ lse" }property { $field="strProp" $mandatory="false" $name="string" $
+ value="foo" }property { $field="strAProp" $mandatory="false" $name="s
+ trAProp" $value="[foo, bar]" }property { $field="intAProp" $mandatory
+ ="false" $name="intAProp" $value="[ 1,2,3]" }}manipulation { field { 
+ $name="boolProp" $type="boolean" }field { $name="strProp" $type="java
+ .lang.String" }field { $name="strAProp" $type="java.lang.String[]" }f
+ ield { $name="intProp" $type="int" }field { $name="intAProp" $type="i
+ nt[]" }method { $name="$init" }method { $name="foo" $return="boolean"
+  }method { $name="fooProps" $return="java.util.Properties" }method { 
+ $name="getBoolean" $return="boolean" }method { $name="getDouble" $ret
+ urn="double" }method { $name="getInt" $return="int" }method { $name="
+ getLong" $return="long" }method { $name="getObject" $return="java.lan
+ g.Boolean" }interface { $name="org.apache.felix.ipojo.test.scenarios.
+ manipulation.service.FooService" }}}component { $name="ManipulationMe
+ tadata-PrimitiveManipulationTester" $classname="org.apache.felix.ipoj
+ o.test.scenarios.component.Manipulation23Tester" $architecture="true"
+  provides { }manipulation { field { $name="f" $type="float" }field { 
+ $name="d" $type="double" }field { $name="is" $type="int[]" }field { $
+ name="bools" $type="boolean[]" }field { $name="b" $type="byte" }field
+  { $name="ls" $type="long[]" }field { $name="c" $type="char" }field {
+  $name="l" $type="long" }field { $name="bs" $type="byte[]" }field { $
+ name="cs" $type="char[]" }field { $name="i" $type="int" }field { $nam
+ e="s" $type="short" }field { $name="fs" $type="float[]" }field { $nam
+ e="ss" $type="short[]" }field { $name="bool" $type="boolean" }field {
+  $name="ds" $type="double[]" }method { $name="$init" }method { $name=
+ "getBoolean" $return="boolean" }method { $name="getBooleans" $return=
+ "boolean[]" }method { $name="getByte" $return="byte" }method { $name=
+ "getBytes" $return="byte[]" }method { $name="getChar" $return="char" 
+ }method { $name="getChars" $return="char[]" }method { $name="getDoubl
+ e" $return="double" }method { $name="getDoubles" $return="double[]" }
+ method { $name="getFloat" $return="float" }method { $name="getFloats"
+  $return="float[]" }method { $name="getInt" $return="int" }method { $
+ name="getInts" $return="int[]" }method { $name="getLong" $return="lon
+ g" }method { $name="getLongs" $return="long[]" }method { $name="getSh
+ ort" $return="short" }method { $name="getShorts" $return="short[]" }m
+ ethod { $arguments="{boolean}" $name="setBoolean" }method { $argument
+ s="{boolean[]}" $name="setBooleans" }method { $arguments="{byte}" $na
+ me="setByte" }method { $arguments="{byte[]}" $name="setBytes" }method
+  { $arguments="{char}" $name="setChar" }method { $arguments="{char[]}
+ " $name="setChars" }method { $arguments="{double}" $name="setDouble" 
+ }method { $arguments="{double[]}" $name="setDoubles" }method { $argum
+ ents="{float}" $name="setFloat" }method { $arguments="{float[]}" $nam
+ e="setFloats" }method { $arguments="{int}" $name="setInt" }method { $
+ arguments="{int[]}" $name="setInts" }method { $arguments="{long}" $na
+ me="setLong" }method { $arguments="{long[]}" $name="setLongs" }method
+  { $arguments="{short}" $name="setShort" }method { $arguments="{short
+ []}" $name="setShorts" }method { $arguments="{long,java.lang.String}"
+  $name="setLong" }interface { $name="org.apache.felix.ipojo.test.scen
+ arios.manipulation.service.PrimitiveManipulationTestService" }}}compo
+ nent { $name="ManipulationMetadata-SimpleMultipleCheckServiceProvider
+ " $classname="org.apache.felix.ipojo.test.scenarios.component.Multipl
+ eCheckService" $architecture="true" provides { }manipulation { field 
+ { $name="refU" $type="int" }field { $name="objectU" $type="int" }fiel
+ d { $name="bothB" $type="int" }field { $name="objectB" $type="int" }f
+ ield { $name="bothU" $type="int" }field { $name="fs" $type="org.apach
+ e.felix.ipojo.test.scenarios.manipulation.service.FooService[]" }fiel
+ d { $name="simpleU" $type="int" }field { $name="simpleB" $type="int" 
+ }field { $name="refB" $type="int" }method { $name="$init" }method { $
+ name="check" $return="boolean" }method { $name="getBoolean" $return="
+ boolean" }method { $name="getInt" $return="int" }method { $name="getL
+ ong" $return="long" }method { $name="getDouble" $return="double" }met
+ hod { $arguments="{java.lang.Object,java.lang.String}" $name="doNothi
+ ng" $return="java.lang.Object" }method { $name="getProps" $return="ja
+ va.util.Properties" }method { $name="voidBind" }method { $name="voidU
+ nbind" }method { $arguments="{org.apache.felix.ipojo.test.scenarios.m
+ anipulation.service.FooService}" $name="objectBind" }method { $argume
+ nts="{org.apache.felix.ipojo.test.scenarios.manipulation.service.FooS
+ ervice}" $name="objectUnbind" }method { $arguments="{org.osgi.framewo
+ rk.ServiceReference}" $name="refBind" }method { $arguments="{org.osgi
+ .framework.ServiceReference}" $name="refUnbind" }method { $arguments=
+ "{org.apache.felix.ipojo.test.scenarios.manipulation.service.FooServi
+ ce,org.osgi.framework.ServiceReference}" $name="bothBind" }method { $
+ arguments="{org.apache.felix.ipojo.test.scenarios.manipulation.servic
+ e.FooService,org.osgi.framework.ServiceReference}" $name="bothUnbind"
+  }interface { $name="org.apache.felix.ipojo.test.scenarios.manipulati
+ on.service.CheckService" }}requires { $field="fs" }}component { $clas
+ sname="org.apache.felix.ipojo.test.scenarios.component.Child" manipul
+ ation { $super="org.apache.felix.ipojo.test.scenarios.component.Paren
+ t" method { $arguments="{java.lang.String}" $name="$init" }}}componen
+ t { $classname="org.apache.felix.ipojo.test.scenarios.component.Multi
+ constructor" manipulation { method { $arguments="{java.lang.String,ja
+ va.lang.String}" $name="$init" }method { $arguments="{java.lang.Strin
+ g,int}" $name="$init" }method { $arguments="{java.lang.String,java.la
+ ng.String,int}" $name="$init" }}}
+Test-Suite: org.apache.felix.ipojo.test.scenarios.manipulation.Manipul
+ ationTestSuite
+Built-By: clement
+Tool: Bnd-0.0.357
+Bundle-Name: iPOJO Manipulation Metadata Test Suite
+Created-By: Apache Maven Bundle Plugin & iPOJO  1.6.0
+Build-Jdk: 1.6.0_22
+Bundle-Version: 1.5.0.SNAPSHOT
+Bnd-LastModified: 1292762858403
+Bundle-ManifestVersion: 2
+Import-Package: org.osgi.service.log;version=1.3, org.apache.felix.ipo
+ jo.test.scenarios.manipulation.service, org.apache.felix.ipojo.junit4
+ osgi, junit.framework, org.apache.felix.ipojo.architecture;version=1.
+ 6, org.apache.felix.ipojo;version=1.6, org.osgi.framework;version=1.5
+ , org.osgi.service.cm;version=1.2, org.apache.felix.ipojo.metadata, o
+ rg.apache.felix.ipojo.parser;version=1.6
+Bundle-SymbolicName: tests.manipulation.metadata
+
diff --git a/ipojo/runtime/org.apache.felix.ipojo.runtime-project.iml b/ipojo/runtime/org.apache.felix.ipojo.runtime-project.iml
new file mode 100644
index 0000000..b4692a3
--- /dev/null
+++ b/ipojo/runtime/org.apache.felix.ipojo.runtime-project.iml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/target/classes" />
+    <output-test url="file://$MODULE_DIR$/target/test-classes" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/target" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.0" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.easymock:easymock:2.4" level="project" />
+    <orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-all:1.7" level="project" />
+  </component>
+</module>
+
diff --git a/ipojo/runtime/pom.xml b/ipojo/runtime/pom.xml
new file mode 100644
index 0000000..07c3eca
--- /dev/null
+++ b/ipojo/runtime/pom.xml
@@ -0,0 +1,120 @@
+<!--
+  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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>felix-parent</artifactId>
+        <version>1.2.1</version>
+        <relativePath>../../pom/pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>org.apache.felix.ipojo.runtime-project</artifactId>
+    <version>1.9.0-SNAPSHOT</version>
+    <name>Apache Felix iPOJO Runtime Project</name>
+    <packaging>pom</packaging>
+
+    <description>
+        The iPOJO runtime project contains the core iPOJO bundle, the composite support and the annotations.
+    </description>
+
+    <modules>
+        <module>core</module>
+        <module>composite</module>
+        <module>annotations</module>
+    </modules>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+            <resource>
+                <directory>.</directory>
+                <targetPath>META-INF</targetPath>
+                <includes>
+                    <include>LICENSE*</include>
+                    <include>NOTICE*</include>
+                    <include>DEPENDENCIES*</include>
+                </includes>
+            </resource>
+        </resources>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>make-assembly</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                                <configuration>
+                                    <descriptorRefs>
+                                        <descriptorRef>project</descriptorRef>
+                                    </descriptorRefs>
+                                    <!-- we don't want to attach all the assemblies, such as bz2 -->
+                                    <attach>false</attach>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <!-- only attach the project and bin assemblies, in tar.gz and zip flavors -->
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>attach-assemblies</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>attach-artifact</goal>
+                                </goals>
+                                <configuration>
+                                    <artifacts>
+                                        <artifact>
+                                            <file>
+                                                ${project.build.directory}/${project.artifactId}-${project.version}-project.tar.gz
+                                            </file>
+                                            <classifier>project</classifier>
+                                            <type>tar.gz</type>
+                                        </artifact>
+                                        <artifact>
+                                            <file>
+                                                ${project.build.directory}/${project.artifactId}-${project.version}-project.zip
+                                            </file>
+                                            <classifier>project</classifier>
+                                            <type>zip</type>
+                                        </artifact>
+                                    </artifacts>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
