FELIX-5180: Support for Java8 Repeatable Properties in DM annotations. Also, fixed some javadoc issues.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1728893 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java
index bf64c19..209a442 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AdapterService.java
@@ -37,11 +37,12 @@
  * <p> Here, the AdapterService is registered into the OSGI registry each time an AdapteeService
  * is found from the registry. The AdapterImpl class adapts the AdapteeService to the AdapterService.
  * The AdapterService will also have a service property (param=value), and will also include eventual
- * service properties found from the AdapteeService:<p>
+ * service properties found from the AdapteeService:
  * <blockquote>
  * <pre>
  * 
- * &#64;AdapterService(adapteeService = AdapteeService.class, properties={&#64;Property(name="param", value="value")})
+ * &#64;AdapterService(adapteeService = AdapteeService.class)
+ * &#64;Property(name="param", value="value")
  * class AdapterImpl implements AdapterService {
  *     // The service we are adapting (injected by reflection)
  *     protected AdapteeService adaptee;
@@ -62,62 +63,73 @@
 {
     /**
      * Sets the adapter service interface(s). By default, the directly implemented interface(s) is (are) used.
+     * @return the adapter service interface(s)
      */
     Class<?>[] provides() default {};
 
     /**
      * Sets some additional properties to use with the adapter service registration. By default, 
      * the adapter will inherit all adaptee service properties.
+     * @return some additional properties
      */
     Property[] properties() default {};
 
     /**
      * Sets the adaptee service interface this adapter is applying to.
+     * @return the adaptee service interface this adapter is applying to.
      */
     Class<?> adapteeService();
     
     /**
      * Sets the filter condition to use with the adapted service interface.
+     * @return the adaptee filter
      */
     String adapteeFilter() default "";
     
     /**
      * Sets the static method used to create the adapter service implementation instance.
      * By default, the default constructor of the annotated class is used.
+     * @return the factory method
      */
     String factoryMethod() default "";
     
     /**
      * Sets the field name where to inject the original service. By default, the original service is injected
      * in any attributes in the aspect implementation that are of the same type as the aspect interface.
+     * @return the field used to inject the original service
      */
     String field() default "";
     
     /**
      * The callback method to be invoked when the original service is available. This attribute can't be mixed with
      * the field attribute.
+     * @return the add callback
      */
     String added() default "";
 
     /**
      * The callback method to be invoked when the original service properties have changed. When this attribute is used, 
      * then the added attribute must also be used.
+     * @return the changed callback
      */
     String changed() default "";
 
     /**
      * name of the callback method to invoke on swap.
+     * @return the swap callback
      */
     String swap() default "";
 
     /**
      * The callback method to invoke when the service is lost. When this attribute is used, then the added attribute 
      * must also be used.
+     * @return the remove callback
      */
     String removed() default "";
     
     /**
      * Specifies if adaptee service properties should be propagated to the adapter service.
+     * @return the service propagation flag
      */
     boolean propagate() default true;
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AspectService.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AspectService.java
index 600ba85..9a3961a 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AspectService.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/AspectService.java
@@ -30,7 +30,7 @@
  * The aspect will be applied to any service that matches the specified interface and filter and 
  * will be registered with the same interface and properties as the original service, plus any 
  * extra properties you supply here. It will also inherit all dependencies, 
- * and if you declare the original service as a member it will be injected.<p>
+ * and if you declare the original service as a member it will be injected.
  * 
  * <h3>Usage Examples</h3>
  * 
@@ -38,11 +38,12 @@
  * is found from the registry. The AspectService class intercepts the InterceptedService, and decorates
  * its "doWork()" method. This aspect uses a rank with value "10", meaning that it will intercept some
  * other eventual aspects with lower ranks. The Aspect also uses a service property (param=value), and 
- * include eventual service properties found from the InterceptedService:<p>
+ * include eventual service properties found from the InterceptedService:
  * <blockquote>
  * <pre>
  * 
- * &#64;AspectService(ranking=10), properties={&#64;Property(name="param", value="value")})
+ * &#64;AspectService(ranking=10))
+ * &#64;Property(name="param", value="value")
  * class AspectService implements InterceptedService {
  *     // The service we are intercepting (injected by reflection)
  *     protected InterceptedService intercepted;
@@ -62,52 +63,60 @@
 {
     /**
      * Sets the service interface to apply the aspect to. By default, the directly implemented interface is used.
+     * @return the service aspect
      */
     Class<?> service() default Object.class;
 
     /**
      * Sets the filter condition to use with the service interface this aspect is applying to.
+     * @return the service aspect filter
      */
     String filter() default "";
     
     /**
      * Sets Additional properties to use with the aspect service registration
+     * @return the aspect service properties.
      */
     Property[] properties() default {};
     
     /**
      * Sets the ranking of this aspect. Since aspects are chained, the ranking defines the order in which they are chained.
-     * Chain ranking is implemented as a service ranking so service lookups automatically retrieve the top of the
-     * chain.
+     * Chain ranking is implemented as a service ranking so service lookups automatically retrieve the top of the chain.
+     * @return the aspect service rank
      */
     int ranking();
     
     /**
      * Sets the field name where to inject the original service. By default, the original service is injected
      * in any attributes in the aspect implementation that are of the same type as the aspect interface.
+     * @return the field used to inject the original service
      */
     String field() default "";
     
     /**
      * The callback method to be invoked when the original service is available. This attribute can't be mixed with
      * the field attribute.
+     * @return the add callback
      */
     String added() default "";
 
     /**
      * The callback method to be invoked when the original service properties have changed. When this attribute is used, 
      * then the added attribute must also be used.
+     * @return the changed callback
      */
     String changed() default "";
 
     /**
      * The callback method to invoke when the service is lost. When this attribute is used, then the added attribute 
      * must also be used.
+     * @return the remove callback
      */
     String removed() default "";
     
     /**
      * name of the callback method to invoke on swap.
+     * @return the swap callback
      */
     String swap() default "";
 
@@ -115,6 +124,7 @@
      * Sets the static method used to create the AspectService implementation instance. The
      * default constructor of the annotated class is used. The factoryMethod can be used to provide a specific
      * aspect implements, like a DynamicProxy.
+     * @return the aspect service factory method
      */
     String factoryMethod() default "";
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/BundleAdapterService.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/BundleAdapterService.java
index 7c0d5e9..c559e40 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/BundleAdapterService.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/BundleAdapterService.java
@@ -40,7 +40,7 @@
  * 
  * <p> In the following example, a "VideoPlayer" Service is registered into the OSGi registry each time
  * an active bundle containing a "Video-Path" manifest header is detected:
- * <p>
+ * 
  * <blockquote>
  * <pre>
  * &#64;BundleAdapterService(filter = "(Video-Path=*)", stateMask = Bundle.ACTIVE, propagate=true)
@@ -66,31 +66,37 @@
     /**
      * The interface(s) to use when registering adapters. By default, the interface(s) directly implemented
      * by the annotated class is (are) used.
+     * @return the interface(s) to use when registering adapters
      */
     Class<?>[] provides() default {};
     
     /**
      * Additional properties to use with the service registration
+     * @return the bundle adapter properties
      */
     Property[] properties() default {};
     
    /**
      * The filter used to match a given bundle.
+     * @return the bundle adapter filter
      */
     String filter();
     
     /**
      * the bundle state mask to apply
+     * @return the bundle state mask to apply
      */
     int stateMask() default Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE;
     
     /**
      * Specifies if manifest headers from the bundle should be propagated to the service properties.
+     * @return the propagation flag
      */
     boolean propagate() default true;
     
     /**
      * Sets the static method used to create the BundleAdapterService implementation instance.
+     * @return the factory method
      */
     String factoryMethod() default "";
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/BundleDependency.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/BundleDependency.java
index 2c0adaf..273f9bc 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/BundleDependency.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/BundleDependency.java
@@ -37,7 +37,7 @@
  * <p> In the following example, the "SCR" Component allows to track 
  * all bundles containing a specific "Service-Component" OSGi header, in order to load
  * and manage all Declarative Service components specified in the SCR xml documents referenced by the header:
- * <p>
+ * 
  * <blockquote>
  * <pre>
  * &#64;Component
@@ -66,32 +66,38 @@
 {
     /**
      * Returns the callback method to be invoked when the service have changed.
+     * @return the change callback
      */
     String changed() default "";
 
     /**
      * Returns the callback method to invoke when the service is lost.
+     * @return the remove callback
      */
     String removed() default "";
     
     /**
      * Returns whether the dependency is required or not.
+     * @return the required flag
      */
     boolean required() default true;
     
     /**
      * Returns the filter dependency
+     * @return the filter
      */
     String filter() default "";
      
     /**
      * Returns the bundle state mask
+     * @return the state mask
      */
     int stateMask() default Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE;
 
     /**
      * Specifies if the manifest headers from the bundle should be propagated to 
      * the service properties.
+     * @return the propagation flag
      */
     boolean propagate() default false;
     
@@ -104,6 +110,7 @@
      * your named dependencies, which will then be calculated once the init() method returns.
      * 
      * <p> See {@link Init} annotation for an example usage of a dependency dynamically configured from the init method.
+     * @return the dependency name used to dynamically configure the dependency from the init callback
      */
     String name() default "";
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Component.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Component.java
index 0aa07ed..8f9a443 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Component.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Component.java
@@ -41,7 +41,7 @@
  *
  * <h3>Usage Examples</h3>
  * 
- * <p> Here is a sample showing a X component, which depends on a configuration dependency:<p>
+ * Here is a sample showing a X component, which depends on a configuration dependency:
  * <blockquote>
  * 
  * <pre>
@@ -69,7 +69,7 @@
  * </blockquote>
  * 
  * Here is a sample showing how a Y component may dynamically instantiate several X component instances, 
- * using the {@link #factoryName()} attribute:<p>
+ * using the {@link #factoryName()} attribute:
  * <blockquote>
  * 
  * <pre>
@@ -157,11 +157,14 @@
 
     /**
      * Sets list of provided interfaces. By default, the directly implemented interfaces are provided.
+     * @return the provided interfaces
      */
     Class<?>[] provides() default {};
 
     /**
-     * Sets list of provided service properties.
+     * Sets list of provided service properties. Since R7 version, Property annotation is repeatable and you can directly
+     * apply it on top of the component class multiple times, instead of using the Component properties attribute.
+     * @return the component properties.
      */
     Property[] properties() default {};
 
@@ -186,6 +189,7 @@
      * using the {@value #FACTORY_INSTANCE} key. 
      * 
      * @deprecated use {@link #factoryName()} instead of a factorySet.
+     * @return the factory set name
      */
     String factorySet() default "";
     
@@ -204,6 +208,7 @@
      * 
      * <p>Optionally, the dictionary registered into the factory set may provide an implementation instance for the component to be created,
      * using a "dm.runtime.factory.instance" key.
+     * @return the factory name
      */
     String factoryName() default "";
 
@@ -212,11 +217,13 @@
      * {@link #factoryName()} attribute is used. If specified, then this attribute references a callback method, which is called 
      * for providing the configuration supplied by the factory that instantiated this component. The current component service properties will be 
      * also updated with all public properties (which don't start with a dot).
+     * @return the factory configure callback name
      */
     String factoryConfigure() default "";
     
     /**
      * Sets the static method used to create the components implementation instance.
+     * @return the factory method used to instantiate the component
      */
     String factoryMethod() default "";        
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Composition.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Composition.java
index b62ac70..3ee2435 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Composition.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Composition.java
@@ -40,7 +40,7 @@
  * 
  * <p> Here, the "MyComponent" component is composed of the Helper class, which is also injected with 
  * service dependencies. The lifecycle callbacks are also invoked in the Helper (if the Helper defines 
- * them):<p>
+ * them):
  * <blockquote>
  * <pre>
  *
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ConfigurationDependency.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ConfigurationDependency.java
index 30ebf46..4a09be2 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ConfigurationDependency.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ConfigurationDependency.java
@@ -91,6 +91,7 @@
      * Returns the pid from a class name. The full class name will be used as the configuration PID.
      * You can use this method when you use an interface annoted with standard bndtols metatype annotations.
      * (see http://www.aqute.biz/Bnd/MetaType).
+     * @return the pid class
      */
     Class<?> pidClass() default Object.class;
 
@@ -150,6 +151,7 @@
      *      }
      *  }
      *  </pre></blockquote>
+     *  @return the dependency name used to configure the dependency dynamically from init callback
      */
     String name() default "";
     
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Destroy.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Destroy.java
index 4934c89a..f81088a 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Destroy.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Destroy.java
@@ -28,7 +28,7 @@
  * The method is called when the component's bundle is stopped, or when one of its
  * required dependency is lost (unless the dependency has been defined as an "instance bound" 
  * dependency using the Dependency Manager API).
- * </ul>
+ * 
  * 
  * <h3>Usage Examples</h3>
  * <blockquote>
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/FactoryConfigurationAdapterService.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/FactoryConfigurationAdapterService.java
index 44fc281..245a12c 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/FactoryConfigurationAdapterService.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/FactoryConfigurationAdapterService.java
@@ -29,7 +29,7 @@
  * factory configuration matching the specified factoryPid, an instance of this service will be created.
  * The adapter will be registered with the specified interface, and with the specified adapter service properties.
  * Depending on the <code>propagate</code> parameter, every public factory configuration properties 
- * (which don't start with ".") will be propagated along with the adapter service properties. <p>
+ * (which don't start with ".") will be propagated along with the adapter service properties.
  * 
  * <h3>Usage Examples</h3>
  * Here, a "Dictionary" service instance is created for each existing "sample.DictionaryConfiguration" factory pids.
@@ -50,7 +50,7 @@
  *   String lang();
  *
  *   &#64;AD(description = "Declare here the list of words supported by this dictionary.")
- *   List<String> words();
+ *   List&#60;String&#62; words();
  * }
  * </pre>
  * </blockquote>
@@ -88,18 +88,21 @@
     /**
      * The interface(s) to use when registering adapters. By default, directly implemented 
      * interfaces will be registered in the OSGi registry.
+     * @return the registered service interfaces
      */
     Class<?>[] provides() default {};
 
     /**
      * Adapter Service properties. Notice that public factory configuration is also registered in service properties,
      * (only if propagate is true). Public factory configuration properties are those which don't starts with a dot (".").
+     * @return the adapter service properties
      */
     Property[] properties() default {};
 
     /**
      * Returns the factory pid whose configurations will instantiate the annotated service class. (By default, the pid is the 
      * service class name).
+     * @return the factory pid
      */
     String factoryPid() default "";
     
@@ -107,11 +110,13 @@
      * Returns the factory pid from a class name. The full class name will be used as the configuration PID.
      * You can use this method when you use an interface annoted with standard bndtols metatype annotations.
      * (see http://www.aqute.biz/Bnd/MetaType).
+     * @return the factory pid class
      */
     Class<?> factoryPidClass() default Object.class;
 
     /**
      * The Update method to invoke (defaulting to "updated"), when a factory configuration is created or updated
+     * @return the updated callback
      */
     String updated() default "updated";
 
@@ -145,6 +150,7 @@
     
     /**
      * Sets the static method used to create the adapter instance.
+     * @return the factory method
      */
     String factoryMethod() default "";
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Init.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Init.java
index 0bc5448..4eb71d0 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Init.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Init.java
@@ -27,7 +27,7 @@
  * Annotates a method used to configure dynamic dependencies.
  * When this method is invoked, all required dependencies (except the ones declared with a <code>name</code> 
  * attribute) are already injected, and optional dependencies on class fields 
- * are also already injected (possibly with NullObjects).<p>
+ * are also already injected (possibly with NullObjects).
  * 
  * The purpose of the @Init method is to either declare more dynamic dependencies using the DM API, or to
  * return a Map used to dynamically configure dependencies that are annotated using a <code>name</code> attribute. 
@@ -66,9 +66,9 @@
  * 
  *     // Dynamically configure the dependency declared with a "storage" name.
  *     &#64;Init
- *     Map<String, String> init() {
+ *     Map&#60;String, String&#62; init() {
  *        log.log(LogService.LOG_WARNING, "init: storage type=" + storageType + ", storageRequired=" + storageRequired);
- *        Map<String, String> props = new HashMap<>();
+ *        Map&#60;String, String&#62; props = new HashMap&#60;&#62;();
  *        props.put("storage.required", Boolean.toString(_xmlConfiguration.isStorageRequired()))
  *        props.put("storage.filter", "(type=" + _xmlConfiguration.getStorageType() + ")");
  *        return props;       
@@ -80,7 +80,7 @@
  *        log.log(LogService.LOG_WARNING, "start");
  *     }
  * 
- *     @Override
+ *     &#64;Override
  *     void store(String key, String value) {
  *        storage.store(key, value);
  *     }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Inject.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Inject.java
index e97c627..42e9739 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Inject.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Inject.java
@@ -33,7 +33,6 @@
  * <li>Component: the component instance of the dependency manager
  * </ul>
  * 
- * <p>
  * <h3>Usage Examples</h3>
  * <blockquote>
  * 
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/LifecycleController.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/LifecycleController.java
index afd9295..0f42364 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/LifecycleController.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/LifecycleController.java
@@ -31,15 +31,15 @@
  * can be invoked in order to start/register (or stop/unregister) a Service at any time. When this annotation 
  * is used, then the Service on which this annotation is applied is not activated by default, and you have to 
  * call the injected Runnable yourself. 
- * <p>
+ *
  * <h3>Usage Examples</h3>
  * <blockquote>
  * 
  * <pre>
  * &#47;**
- *   * This Service will be registered programatically into the OSGi registry, using the LifecycleController annotation.
+ *   * This Service will be registered programmatically into the OSGi registry, using the LifecycleController annotation.
  *   *&#47;
- * &#64;Service
+ * &#64;Component
  * class X implements Z {
  *     &#64;LifecycleController
  *     Runnable starter
@@ -69,7 +69,7 @@
  *         // This method will be called after we invoke our starter Runnable, and our service will be
  *         // published after our method returns, as in normal case.
  *     }
-
+ *
  *     &#64;Stop
  *     public void stop() {
  *         // This method will be called after we invoke our "stop" Runnable, and our service will be
@@ -87,9 +87,11 @@
 public @interface LifecycleController
 {
     /**
-     * Specifies the action to be performed when the Injected runnable is invoked. By default, the
+     * Specifies the action to be performed when the injected runnable is invoked. By default, the
      * Runnable will fire a Service Component activation, when invoked. If you specify this attribute
      * to false, then the Service Component will be stopped, when the runnable is invoked.
+     * @return true if the component must be started when you invoke the injected runnable, or false if
+     * the component must stopped when invoking the runnable.
      */
     public boolean start() default true;
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Property.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Property.java
index f760ee9..9c55b88 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Property.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Property.java
@@ -19,6 +19,7 @@
 package org.apache.felix.dm.annotation.api;
 
 import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
@@ -28,9 +29,10 @@
  * declaring {@link Component#properties()} attribute.<p>
  * 
  * Property value(s) type is String by default, and the type is scalar if the value is single-valued, 
- * or an array if the value is multi-valued.
+ * or an array if the value is multi-valued. You can apply this annotation on a component class multiple times
+ * (it's a java8 repeatable property).
  * 
- * Eight primitive types are supported:<p>
+ * Eight primitive types are supported:
  * <ul>
  * <li> String (default type)
  * <li> Long
@@ -48,17 +50,15 @@
  * Notice that you can also specify service properties dynamically by returning a Map from a method
  * annotated with {@link Start}.
  * 
- * <p>
  * <h3>Usage Examples</h3>
  * <blockquote>
- * 
  * <pre>
- * &#64;Component(properties={
- *     &#64;Property(name="p1", value="v")})                    // String value type (scalar)
- *     &#64;Property(name="p2", value={"s1", "s2")})            // Array of Strings
- *     &#64;Property(name="service.ranking", intValue=10)       // Integer value type (scalar)
- *     &#64;Property(name="p3", intValue={1,2})                 // Array of Integers
- *     &#64;Property(name="p3", value={"1"), type=Long.class})  // Long value (scalar)
+ * &#64;Component
+ * &#64;Property(name="p1", value="v")                      // String value type (scalar)
+ * &#64;Property(name="p2", value={"s1", "s2"})             // Array of Strings
+ * &#64;Property(name="service.ranking", intValue=10)       // Integer value type (scalar)
+ * &#64;Property(name="p3", intValue={1,2})                 // Array of Integers
+ * &#64;Property(name="p3", value="1", type=Long.class)     // Long value (scalar)
  * class ServiceImpl implements Service {
  * }
  * </pre>
@@ -67,7 +67,8 @@
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
 @Retention(RetentionPolicy.CLASS)
-@Target( { ElementType.ANNOTATION_TYPE })
+@Target( { ElementType.TYPE, ElementType.ANNOTATION_TYPE })
+@Repeatable(RepeatableProperty.class)
 public @interface Property
 {
     /**
@@ -96,41 +97,49 @@
     
     /**
      * A Long value or an array of Long values. 
+     * @return the long value(s). 
      */
     long[] longValue() default {};
 
     /**
      * A Double value or an array of Double values. 
+     * @return the double value(s). 
      */
     double[] doubleValue() default {};
 
     /**
      * A Float value or an array of Float values. 
+     * @return the float value(s). 
      */
     float[] floatValue() default {};
 
     /**
      * An Integer value or an array of Integer values. 
+     * @return the int value(s). 
      */
     int[] intValue() default {};
 
     /**
      * A Byte value or an array of Byte values. 
+     * @return the byte value(s). 
      */
     byte[] byteValue() default {};
 
     /**
      * A Character value or an array of Character values. 
+     * @return the char value(s). 
      */
     char[] charValue() default {};
 
     /**
-     * A Boolean value or an array of Boolean values. 
+     * A Boolean value or an array of Boolean values.
+     * @return the boolean value(s). 
      */
     boolean[] booleanValue() default {};
 
     /**
      * A Short value or an array of Short values. 
+     * @return the short value(s). 
      */
     short[] shortValue() default {};
     
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/PropertyMetaData.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/PropertyMetaData.java
index 8e7d724..5a701d8 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/PropertyMetaData.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/PropertyMetaData.java
@@ -27,7 +27,7 @@
 /**
  * This annotation describes the data types of a configuration Property.
  * It can be used by other annotations which require meta type support.
- * For now, the following annotations are using <code>PropertyMetaData</code:
+ * For now, the following annotations are using <code>PropertyMetaData</code>:
  * <ul>
  *   <li>{@link ConfigurationDependency}: This dependency allows to define a 
  *   dependency over a <code>Configuration Admin</code> configuration dictionaries, whose 
@@ -56,7 +56,7 @@
     String id();
 
     /**
-     * Return the property primitive type. If must be either one of the following types:<p>
+     * Return the property primitive type. If must be either one of the following types:
      * <ul>
      *    <li>String.class</li>
      *    <li>Long.class</li>
@@ -67,15 +67,17 @@
      *    <li>Float.class</li>
      *    <li>Boolean.class</li>
      * </ul>
+     * @return the property type
      */
     Class<?> type() default String.class;
 
     /**
-     * Return a default for this property. The object must be of the appropriate type as defined by the cardinality and getType(). 
+     * Return default value(s) for this property. The object must be of the appropriate type as defined by the cardinality and getType(). 
      * The return type is a list of String  objects that can be converted to the appropriate type. The cardinality of the return 
      * array must follow the absolute cardinality of this type. E.g. if the cardinality = 0, the array must contain 1 element. 
      * If the cardinality is 1, it must contain 0 or 1 elements. If it is -5, it must contain from 0 to max 5 elements. Note that 
-     * the special case of a 0 cardinality, meaning a single value, does not allow arrays or vectors of 0 elements. 
+     * the special case of a 0 cardinality, meaning a single value, does not allow arrays or vectors of 0 elements.
+     * @return the default values 
      */
     String[] defaults() default {};
 
@@ -88,20 +90,22 @@
 
     /**
      * Return the cardinality of this property. The OSGi environment handles multi valued properties in arrays ([]) or in Vector objects. 
-     * The return value is defined as follows:<p>
+     * The return value is defined as follows:
      *
      * <ul>
      * <li> x = Integer.MIN_VALUE    no limit, but use Vector</li>
-     * <li> x < 0                    -x = max occurrences, store in Vector</li>
-     * <li> x > 0                     x = max occurrences, store in array []</li>
-     * <li> x = Integer.MAX_VALUE    no limit, but use array []</li>
-     * <li> x = 0                     1 occurrence required</li>
+     * <li> x lower than 0                    -x = max occurrences, store in Vector</li>
+     * <li> x greater than 0                     x = max occurrences, store in array []</li>
+     * <li> x equals Integer.MAX_VALUE    no limit, but use array []</li>
+     * <li> x equals 0                     1 occurrence required</li>
      * </ul>
+     * @return the property cardinality
      */
     int cardinality() default 0;
 
     /**
      * Tells if this property is required or not.
+     * @return true if the property is required, false if not
      */
     boolean required() default true;
 
@@ -116,6 +120,7 @@
     /**
      * Return a list of option values that this property can take. This list must be in the same sequence as the {@link #optionLabels()} 
      * attribute.
+     * @return the option values
      */
    String[] optionValues() default {};
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Registered.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Registered.java
index 5c34855..40d0c53 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Registered.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Registered.java
@@ -29,7 +29,6 @@
  * When a service is registered, the ServiceRegistration used to register the service is
  * also passed to the method (if it takes a ServiceRegistration as parameter).
  * 
- * <p>
  * <h3>Usage Examples</h3>
  * <blockquote>
  * 
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/RepeatableProperty.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/RepeatableProperty.java
new file mode 100644
index 0000000..53e2d93
--- /dev/null
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/RepeatableProperty.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.dm.annotation.api;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation used to describe repeated Property annotation. You actually don't have to use directly this annotation,
+ * which is used used to allow to repeat several times the {@link Property} annotation on a given component class.
+ * 
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target( { ElementType.TYPE, ElementType.ANNOTATION_TYPE })
+public @interface RepeatableProperty
+{
+    /**
+     * Returns the set of repeated {@link Property} applied on a given component class.
+     * @return the set of repeated {@link Property} applied on a given component class.
+     */
+    Property[] value();
+}
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ResourceAdapterService.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ResourceAdapterService.java
index bfa388b..92d4114 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ResourceAdapterService.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ResourceAdapterService.java
@@ -47,7 +47,7 @@
  * <blockquote>
  * <pre>
  * 
- * &#64;ResourceAdapterService(filter = "(&(path=/videos/*.mkv)(host=localhost))", propagate = true)
+ * &#64;ResourceAdapterService(filter = "(&#38;(path=/videos/*.mkv)(host=localhost))", propagate = true)
  * public class VideoPlayerImpl implements VideoPlayer {
  *     // Injected by reflection
  *     URL resource;
@@ -128,31 +128,37 @@
 {
     /**
      * The interface(s) to use when registering adapters
+     * @return the provided interfaces
      */
     Class<?>[] provides() default {};
 
     /**
      * Additional properties to use with the adapter service registration
+     * @return the properties
      */
     Property[] properties() default {};
 
    /**
      * The filter condition to use with the resource.
+     * @return the filter
      */
     String filter();
 
     /**
      * <code>true</code> if properties from the resource should be propagated to the service properties.
+     * @return the propagate flag
      */
     boolean propagate() default false;
     
     /**
      * The callback method to be invoked when the Resource has changed.
+     * @return the changed callback
      */
     String changed() default "";
 
     /**
      * Sets the static method used to create the AdapterService implementation instance.
+     * @return the factory method
      */
     String factoryMethod() default "";
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ResourceDependency.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ResourceDependency.java
index 5da30ff..b62863d 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ResourceDependency.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ResourceDependency.java
@@ -113,26 +113,31 @@
     /**
      * Returns the callback method to be invoked when the service is available. This attribute is only meaningful when 
      * the annotation is applied on a class field.
+     * @return the add callback
      */
     String added() default "";
 
     /**
      * Returns the callback method to be invoked when the service properties have changed.
+     * @return the change callback
      */
     String changed() default "";
 
     /**
      * Returns the callback method to invoke when the service is lost.
+     * @return the remove callback
      */
     String removed() default "";
 
     /**
      * Returns whether the Service dependency is required or not.
+     * @return the required flag
      */
     boolean required() default true;
     
     /**
      * Returns the Service dependency OSGi filter.
+     * @return the filter
      */
     String filter() default "";
 
@@ -140,6 +145,7 @@
      * Specifies if the resource URL properties must be propagated. If set to true, then the URL properties 
      * ("protocol"/"host"/"port"/"path") will be propagated to the service properties of the component which 
      * is using this dependency. 
+     * @return the propagate flag
      */
     boolean propagate() default false;
     
@@ -152,6 +158,7 @@
      * your named dependencies, which will then be calculated once the init() method returns.
      * 
      * <p> See {@link Init} annotation for an example usage of a dependency dynamically configured from the init method.
+     * @return the dependency name
      */
     String name() default "";   
 }
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ServiceDependency.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ServiceDependency.java
index 50105a1..1dcee0d 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ServiceDependency.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/ServiceDependency.java
@@ -46,37 +46,44 @@
     /**
      * The type if the service this dependency is applying on. By default, the method parameter 
      * (or the class field) is used as the type.
+     * @return the service dependency
      */
     Class<?> service() default Object.class;
 
     /**
      * The Service dependency OSGi filter.
+     * @return the service filter
      */
     String filter() default "";
 
     /**
      * The class for the default implementation, if the dependency is not available.
+     * @return the default implementation class
      */
     Class<?> defaultImpl() default Object.class;
 
     /**
      * Whether the Service dependency is required or not.
+     * @return the required flag
      */
     boolean required() default true;
 
     /**
      * The callback method to be invoked when the service is available. This attribute is only meaningful when 
      * the annotation is applied on a class field.
+     * @return the add callback
      */
     String added() default "";
 
     /**
      * The callback method to be invoked when the service properties have changed.
+     * @return the change callback
      */
     String changed() default "";
 
     /**
      * The callback method to invoke when the service is lost.
+     * @return the remove callback
      */
     String removed() default "";
     
@@ -89,13 +96,12 @@
      * the service dependency criteria. If no service replacement is available, then any method invocation 
      * (through the dynamic proxy) will block during a configurable timeout. On timeout, an unchecked 
      * <code>IllegalStateException</code> exception is raised (but the service is not deactivated).<p>
-     * Notice that the changed/removed callbacks are not used when the timeout parameter is > -1.
-     * <p> 
+     * Notice that the changed/removed callbacks are not used when the timeout parameter is greater than -1. 
      * 
      * -1 means no timeout at all (default). 0 means that invocation on a missing service will fail 
      * immediately. A positive number represents the max timeout in millis to wait for the service availability.
      * 
-     * <p> Sample Code:<p>
+     * Sample Code:
      * <blockquote><pre>
      * &#64;Component
      * class MyServer implements Runnable {
@@ -115,6 +121,7 @@
      *     }
      *   }   
      * </pre></blockquote>
+     * @return the wait time when the dependency is unavailable
      */
     long timeout() default -1;
     
@@ -127,6 +134,7 @@
      * your named dependencies, which will then be calculated once the init() method returns.
      * 
      * <p> See {@link Init} annotation for an example usage of a dependency dynamically configured from the init method.
+     * @return the dependency name used to dynamically configure the filter and required flag from the init callback.
      */
     String name() default "";
     
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Start.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Start.java
index da61b70..ec9e31a 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Start.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Start.java
@@ -30,7 +30,6 @@
  * a Map which will be propagated to the provided service properties.<p>
  * Service activation/deactivation can be programatically controlled using {@link LifecycleController}.
  *      
- * <p>
  * <h3>Usage Examples</h3>
  * <blockquote>
  * 
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Stop.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Stop.java
index 672b7ea..f963db0 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Stop.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Stop.java
@@ -29,7 +29,6 @@
  * The method is called when the component's bundle is stopped, or when one of its
  * required dependency is lost, or when a {@link LifecycleController} is programatically used to
  * stop a service.
- * </ul>
  * 
  * <h3>Usage Examples</h3>
  * <blockquote>
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Unregistered.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Unregistered.java
index c59a435..26ac430 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Unregistered.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/api/Unregistered.java
@@ -28,7 +28,6 @@
  * At this point, the component has been unregistered from the OSGI registry (if it provides some services).
  * The method must not take any parameters.
  * 
- * <p>
  * <h3>Usage Examples</h3>
  * <blockquote>
  * 
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
index b3f3758..2cbc288 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/AnnotationCollector.java
@@ -38,6 +38,7 @@
 import org.apache.felix.dm.annotation.api.Inject;
 import org.apache.felix.dm.annotation.api.LifecycleController;
 import org.apache.felix.dm.annotation.api.Registered;
+import org.apache.felix.dm.annotation.api.RepeatableProperty;
 import org.apache.felix.dm.annotation.api.ResourceAdapterService;
 import org.apache.felix.dm.annotation.api.ResourceDependency;
 import org.apache.felix.dm.annotation.api.ServiceDependency;
@@ -72,6 +73,7 @@
     private final static String A_LIFCLE_CTRL = LifecycleController.class.getName();
 
     private final static String A_COMPONENT = Component.class.getName();
+    private final static String A_REPEATABLE_PROPERTY = RepeatableProperty.class.getName();
     private final static String A_SERVICE_DEP = ServiceDependency.class.getName();
     private final static String A_CONFIGURATION_DEPENDENCY = ConfigurationDependency.class.getName();
     private final static String A_BUNDLE_DEPENDENCY = BundleDependency.class.getName();
@@ -93,7 +95,7 @@
     private String m_method;
     private String m_descriptor;
     private Set<String> m_dependencyNames = new HashSet<String>();
-    private List<EntryWriter> m_writers = new ArrayList<EntryWriter>(); // Last elem is either Service or AspectService
+    private List<EntryWriter> m_writers = new ArrayList<EntryWriter>();
     private MetaType m_metaType;
     private String m_startMethod;
     private String m_stopMethod;
@@ -109,11 +111,9 @@
     private String m_componentField;
     private String m_registeredMethod;
     private String m_unregisteredMethod;
-
-    /**
-     * This class represents a DependencyManager component descriptor entry.
-     * (Service, a ServiceDependency ... see EntryType enum).
-     */
+    private Annotation m_repeatableProperty;
+    private final List<EntryType> m_componentTypes = Arrays.asList(EntryType.Component, EntryType.AspectService, EntryType.AdapterService,
+        EntryType.BundleAdapterService, EntryType.ResourceAdapterService, EntryType.FactoryConfigurationAdapterService);
 
     /**
      * Makes a new Collector for parsing a given class.
@@ -263,7 +263,11 @@
         else if (annotation.getName().getFQN().equals(A_INJECT))
         {
             parseInject(annotation);
-        }
+        } 
+        else if (annotation.getName().getFQN().equals(A_REPEATABLE_PROPERTY))
+        {
+            parseRepeatableProperties(annotation);
+        } 
     }
 
     /**
@@ -278,10 +282,24 @@
             return false;
         }
 
-        // We must have at least a Service annotation.
-        checkServiceDeclared(EntryType.Component, EntryType.AspectService, EntryType.AdapterService,
-            EntryType.BundleAdapterService,
-            EntryType.ResourceAdapterService, EntryType.FactoryConfigurationAdapterService);
+        // We must have at least a valid component annotation type (component, aspect, or adapters)
+        
+        EntryWriter componentWriter = m_writers.stream()
+            .filter(writer -> m_componentTypes.indexOf(writer.getEntryType()) != -1)
+            .findFirst()
+            .orElseThrow(() -> new IllegalStateException(": the class " + m_className + " must be annotated with either one of the following types: " + m_componentTypes));                   
+        
+        // Add any repeated @Property annotation to the component (or to the aspect, or adapter).
+                
+        if (m_repeatableProperty != null)
+        {
+            Object[] properties = m_repeatableProperty.get("value");
+            for (Object property : properties)
+            {
+                // property is actually a @Property annotation.
+                parseProperty((Annotation) property, componentWriter);
+            }
+        }
         
         StringBuilder sb = new StringBuilder();
         sb.append("Parsed annotation for class ");
@@ -328,6 +346,15 @@
         return m_exportService;
     }
     
+    /**
+     * Parses a Property annotation that is applied on the component class.
+     * @param property the Property annotation.
+     */
+    private void parseRepeatableProperties(Annotation repeatedProperties)
+    {
+        m_repeatableProperty = repeatedProperties;
+    }
+    
     private void parseComponentAnnotation(Annotation annotation)
     {
         EntryWriter writer = new EntryWriter(EntryType.Component);
@@ -340,7 +367,7 @@
         writer.put(EntryParam.impl, m_className);
 
         // properties attribute
-        parseProperties(annotation, EntryParam.properties, writer);
+        parseProperties(annotation, writer);
 
         // provides attribute.
         if (writer.putClassArray(annotation, EntryParam.provides, m_interfaces, m_exportService) == 0)
@@ -642,7 +669,7 @@
         writer.put(EntryParam.impl, m_className);
 
         // Parse Aspect properties.
-        parseProperties(annotation, EntryParam.properties, writer);
+        parseProperties(annotation, writer);
         
         // Parse field/added/changed/removed attributes
         parseAspectOrAdapterCallbackMethods(annotation, writer);
@@ -727,7 +754,7 @@
         writer.putClass(annotation, EntryParam.adapteeService);
 
         // Parse Adapter properties.
-        parseProperties(annotation, EntryParam.properties, writer);
+        parseProperties(annotation, writer);
 
         // Parse the provided adapter service (use directly implemented interface by default).
         if (writer.putClassArray(annotation, EntryParam.provides, m_interfaces, m_exportService) == 0)
@@ -774,7 +801,7 @@
             Bundle.INSTALLED | Bundle.RESOLVED | Bundle.ACTIVE).toString());
 
         // Parse Adapter properties.
-        parseProperties(annotation, EntryParam.properties, writer);
+        parseProperties(annotation, writer);
 
         // Parse the optional adapter service (use directly implemented interface by default).
         if (writer.putClassArray(annotation, EntryParam.provides, m_interfaces, m_exportService) == 0)
@@ -813,7 +840,7 @@
         }
 
         // Parse Adapter properties.
-        parseProperties(annotation, EntryParam.properties, writer);
+        parseProperties(annotation, writer);
 
         // Parse the provided adapter service (use directly implemented interface by default).
         if (writer.putClassArray(annotation, EntryParam.provides, m_interfaces, m_exportService) == 0)
@@ -862,7 +889,7 @@
         }
 
         // Parse Adapter properties.
-        parseProperties(annotation, EntryParam.properties, writer);
+        parseProperties(annotation, writer);
 
         // Parse optional meta types for configuration description.
         parseMetaTypes(annotation, factoryPid, true);
@@ -1036,96 +1063,111 @@
      *  }
      * }
      * 
-     * @param annotation the annotation where the Param annotation is defined
-     * @param attribute the attribute name which is of Param type
-     * @param writer the object where the parsed attributes are written
+     * @param component the component annotation which contains a "properties" attribute. The component can be either a @Component, or an aspect, or an adapter.
+     * @param writer the object where the parsed attributes are written.
      */
-    private void parseProperties(Annotation annotation, EntryParam attribute, EntryWriter writer)
+    private void parseProperties(Annotation component, EntryWriter writer)
+    {            
+        Object[] properties = component.get(EntryParam.properties.toString());
+        if (properties != null)
+        {
+            for (Object property : properties)
+            {
+                Annotation propertyAnnotation = (Annotation) property;
+                parseProperty(propertyAnnotation, writer);
+            }             
+        }
+    }
+    
+    /**
+     * Parses a Property annotation. The result is added to the associated writer object
+     * @param annotation the @Property annotation.
+     * @param writer the writer object where the parsed property will be added to.
+     */
+    private void parseProperty(Annotation property, EntryWriter writer)
     {
+        EntryParam attribute = EntryParam.properties;
         try
         {
-            Object[] parameters = annotation.get(attribute.toString());
-            if (parameters != null)
+            JSONObject properties = writer.getJsonObject(attribute);
+            if (properties == null) {
+                properties = new JSONObject();
+            }
+                        
+            String name = (String) property.get("name");
+            String type = parseClassAttrValue(property.get("type"));
+            Class<?> classType;
+            try
             {
-                JSONObject properties = new JSONObject();
-                for (Object p : parameters)
-                {
-                    Annotation a = (Annotation) p;
-                    String name = (String) a.get("name");
+                classType = (type == null) ? String.class : Class.forName(type);
+            }
+            catch (ClassNotFoundException e)
+            {
+                // Theorically impossible
+                throw new IllegalArgumentException("Invalid Property type " + type
+                    + " from annotation " + property + " in class " + m_className);
+            }
 
-                    String type = parseClassAttrValue(a.get("type"));
-                    Class<?> classType;
-                    try
-                    {
-                        classType = (type == null) ? String.class : Class.forName(type);
-                    }
-                    catch (ClassNotFoundException e)
-                    {
-                        // Theorically impossible
-                        throw new IllegalArgumentException("Invalid Property type " + type
-                            + " from annotation " + annotation + " in class " + m_className);
-                    }
+            Object[] values;
 
-                    Object[] values;
+            if ((values = property.get("value")) != null)
+            {
+                values = checkPropertyType(name, classType, values);
+                addProperty(properties, name, values, classType);
+            }
+            else if ((values = property.get("values")) != null)
+            { // deprecated
+                values = checkPropertyType(name, classType, values);
+                addProperty(properties, name, values, classType);
+            }
+            else if ((values = property.get("longValue")) != null)
+            {
+                addProperty(properties, name, values, Long.class);
+            }
+            else if ((values = property.get("doubleValue")) != null)
+            {
+                addProperty(properties, name, values, Double.class);
+            }
+            else if ((values = property.get("floatValue")) != null)
+            {
+                addProperty(properties, name, values, Float.class);
+            }
+            else if ((values = property.get("intValue")) != null)
+            {
+                addProperty(properties, name, values, Integer.class);
+            }
+            else if ((values = property.get("byteValue")) != null)
+            {
+                addProperty(properties, name, values, Byte.class);
+            }
+            else if ((values = property.get("charValue")) != null)
+            {
+                addProperty(properties, name, values, Character.class);
+            }
+            else if ((values = property.get("booleanValue")) != null)
+            {
+                addProperty(properties, name, values, Boolean.class);
+            }
+            else if ((values = property.get("shortValue")) != null)
+            {
+                addProperty(properties, name, values, Short.class);
+            }
+            else
+            {
+                throw new IllegalArgumentException(
+                    "Missing Property value from annotation " + property + " in class " + m_className);
+            }
 
-                    if ((values = a.get("value")) != null)
-                    {
-                        values = checkPropertyType(name, classType, values);
-                        addProperty(properties, name, values, classType);
-                    }
-                    else if ((values = a.get("values")) != null)
-                    { // deprecated
-                        values = checkPropertyType(name, classType, values);
-                        addProperty(properties, name, values, classType);
-                    }
-                    else if ((values = a.get("longValue")) != null)
-                    {
-                        addProperty(properties, name, values, Long.class);
-                    }
-                    else if ((values = a.get("doubleValue")) != null)
-                    {
-                        addProperty(properties, name, values, Double.class);
-                    }
-                    else if ((values = a.get("floatValue")) != null)
-                    {
-                        addProperty(properties, name, values, Float.class);
-                    }
-                    else if ((values = a.get("intValue")) != null)
-                    {
-                        addProperty(properties, name, values, Integer.class);
-                    }
-                    else if ((values = a.get("byteValue")) != null)
-                    {
-                        addProperty(properties, name, values, Byte.class);
-                    }
-                    else if ((values = a.get("charValue")) != null)
-                    {
-                        addProperty(properties, name, values, Character.class);
-                    }
-                    else if ((values = a.get("booleanValue")) != null)
-                    {
-                        addProperty(properties, name, values, Boolean.class);
-                    }
-                    else if ((values = a.get("shortValue")) != null)
-                    {
-                        addProperty(properties, name, values, Short.class);
-                    }
-                    else
-                    {
-                        throw new IllegalArgumentException("Missing Property value from annotation "
-                            + annotation + " in class " + m_className);
-                    }
-                }
+            if (properties.length() > 0) {
                 writer.putJsonObject(attribute, properties);
             }
         }
         catch (JSONException e)
         {
-            throw new IllegalArgumentException("UNexpected exception while parsing Property from annotation "
-                + annotation + " in class " + m_className, e);
+            throw new IllegalArgumentException("Unexpected exception while parsing Property from class " + m_className, e);
         }
     }
-    
+
     /**
      * Checks if a property contains values that are compatible with a give primitive type.
      * 
@@ -1291,35 +1333,6 @@
     }
     
     /**
-     * Checks if the class is annotated with some given annotations. Notice that the Service
-     * is always parsed at end of parsing, so, we have to check the last element of our m_writers
-     * List.
-     * @return true if one of the provided annotations has been found from the parsed class.
-     */
-    private void checkServiceDeclared(EntryType... types)
-    {
-        boolean ok = false;
-        if (m_writers.size() > 0)
-        {
-            for (EntryType type: types)
-            {
-                if (m_writers.get(m_writers.size() - 1).getEntryType() == type)
-                {
-                    ok = true;
-                    break;
-                }
-            }
-        }
-
-        if (!ok)
-        {
-            throw new IllegalStateException(
-                ": the class must be annotated with either one of the following types: "
-                    + Arrays.toString(types));
-        }
-    }
-
-    /**
      * This method checks if the @Registered and/or @Unregistered annotations have been defined
      * while they should not, because the component does not provide a service.
      */
diff --git a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
index 89cdb82..25cb4e6 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.annotation/src/org/apache/felix/dm/annotation/plugin/bnd/EntryWriter.java
@@ -118,6 +118,22 @@
     {
         m_json.put(param.toString(),  jsonObject);
     }
+    
+    /**
+     * Gets a json object associated to the given parameter name.
+     * @throws JSONException 
+     */
+    public JSONObject getJsonObject(EntryParam param) 
+    {
+        try
+        {
+            return (JSONObject) m_json.get(param.toString());
+        }
+        catch (JSONException e)
+        {
+            return null;
+        }
+    }
 
     /**
      * Get a String attribute value from an annotation and write it into this descriptor entry.
diff --git a/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/Felix4357.java b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/Felix4357.java
index f2948ea..d585000 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/Felix4357.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/Felix4357.java
@@ -33,49 +33,37 @@
  * 
  * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
  */
-@Component(properties={
-        @Property(name="v1", value="s"),
-        @Property(name="v2", value={"s1", "s2"}),
-        @Property(name="v3", values={"s1", "s2"}),
-
-        @Property(name="v4", value="1", type=Long.class),
-        @Property(name="v5", longValue=1),
-        @Property(name="v6", longValue={1, 2}),
-        
-        @Property(name="v7", value="1", type=Double.class),
-        @Property(name="v8", doubleValue=1),
-        @Property(name="v9", doubleValue={1, 2}),
-
-        @Property(name="v10", value="1", type=Float.class),
-        @Property(name="v11", floatValue=1),
-        @Property(name="v12", floatValue={1, 2}),
-
-        @Property(name="v13", value="1", type=Integer.class),
-        @Property(name="v14", intValue=1),
-        @Property(name="v15", intValue={1, 2}),
-
-        @Property(name="v16", value="65", type=Byte.class),
-        @Property(name="v17", byteValue=65),
-        @Property(name="v18", byteValue={65, 66}),
-
-        @Property(name="v19", value="A", type=Character.class),
-        @Property(name="v20", charValue='A'),
-        @Property(name="v21", charValue={'A', 'B'}),
-
-        @Property(name="v22", value="true", type=Boolean.class),
-        @Property(name="v23", booleanValue=true),
-        @Property(name="v24", booleanValue={true, false}),
-
-        @Property(name="v25", value="1", type=Short.class),
-        @Property(name="v26", shortValue=1),
-        @Property(name="v27", shortValue={1, 2}),
-        
-        @Property(name="v28", value="65", type=Character.class),
-        @Property(name="v29", charValue=65),
-        @Property(name="v30", charValue={65, 66}),
-    },
-    provides=Felix4357.class
-)
+@Component(provides=Felix4357.class)
+@Property(name="v1", value="s")
+@Property(name="v2", value={"s1", "s2"})
+@Property(name="v3", values={"s1", "s2"})
+@Property(name="v4", value="1", type=Long.class)
+@Property(name="v5", longValue=1)
+@Property(name="v6", longValue={1, 2})
+@Property(name="v7", value="1", type=Double.class)
+@Property(name="v8", doubleValue=1)
+@Property(name="v9", doubleValue={1, 2})
+@Property(name="v10", value="1", type=Float.class)
+@Property(name="v11", floatValue=1)
+@Property(name="v12", floatValue={1, 2})
+@Property(name="v13", value="1", type=Integer.class)
+@Property(name="v14", intValue=1)
+@Property(name="v15", intValue={1, 2})
+@Property(name="v16", value="65", type=Byte.class)
+@Property(name="v17", byteValue=65)
+@Property(name="v18", byteValue={65, 66})
+@Property(name="v19", value="A", type=Character.class)
+@Property(name="v20", charValue='A')
+@Property(name="v21", charValue={'A', 'B'})
+@Property(name="v22", value="true", type=Boolean.class)
+@Property(name="v23", booleanValue=true)
+@Property(name="v24", booleanValue={true, false})
+@Property(name="v25", value="1", type=Short.class)
+@Property(name="v26", shortValue=1)
+@Property(name="v27", shortValue={1, 2})
+@Property(name="v28", value="65", type=Character.class)
+@Property(name="v29", charValue=65)
+@Property(name="v30", charValue={65, 66})
 public class Felix4357 {
     public final static String ENSURE = "Felix4357";
     
diff --git a/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/ResourceAdapterServiceTestWithPublisher.java b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/ResourceAdapterServiceTestWithPublisher.java
index 5b77a33..f2f923d 100644
--- a/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/ResourceAdapterServiceTestWithPublisher.java
+++ b/dependencymanager/org.apache.felix.dependencymanager.runtime.itest/src/org/apache/felix/dm/runtime/itest/components/ResourceAdapterServiceTestWithPublisher.java
@@ -160,8 +160,9 @@
             }
         }
     }
-
-    @ResourceAdapterService(filter = "(&(path=/path/to/test1.txt)(host=localhost))", properties = {@Property(name = "foo", value = "bar")}, propagate = true)
+    
+    @ResourceAdapterService(filter = "(&(path=/path/to/test1.txt)(host=localhost))", propagate = true)
+    @Property(name = "foo", value = "bar")
     public static class ProviderImpl implements Provider {
         @LifecycleController
         volatile Runnable m_publisher; // injected and used to register our service