/*
 * 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.lambda;

import java.util.Dictionary;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;

import org.apache.felix.dm.Component;
import org.apache.felix.dm.Component.ServiceScope;
import org.apache.felix.dm.ComponentStateListener;
import org.apache.felix.dm.Dependency;
import org.apache.felix.dm.lambda.callbacks.InstanceCb;
import org.apache.felix.dm.lambda.callbacks.InstanceCbComponent;
import org.osgi.annotation.versioning.ProviderType;

/**
 * Builds a Dependency Manager Component. <p> Components are the main building blocks for OSGi applications. 
 * They can publish themselves as a service, and they can have dependencies. 
 * These dependencies will influence their life cycle as component will only be activated when all 
 * required dependencies are available. This interface is also the base interface for extended components like 
 * aspects, adapters, etc ...
 *
 * <p> Example of a component that depends on a LogServce service. The dependency is injected by reflection
 * on fields having a compatible type with the LogService interface:
 * 
 * <pre>{@code
 * public class Activator extends DependencyManagerActivator {
 *   public void init(BundleContext ctx, DependencyManager dm) throws Exception {
 *       component(comp -> comp.impl(Pojo.class).withSvc(LogService.class));
 *   }
 * }
 * } </pre>
 *
 * @param <B> the type of a builder that may extends this builder interface (aspect/adapter).
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
@ProviderType
public interface ComponentBuilder<B extends ComponentBuilder<B>> {
	
	/**
	 * Configures the component scope.
	 */
	B scope(ServiceScope scope);
    
    /**
     * Configures the component implementation. Can be a class name, or a component implementation object.
     * 
     * @param impl the component implementation (a class, or an Object).
     * @return this builder
     */
    B impl(Object impl);   
    
    /**
     * Sets the factory to use when creating the implementation. You can specify both the factory class and method to invoke. The method should return the implementation, 
     * and can use any method to create it. Actually, this can be used together with setComposition to create a composition of instances that work together to implement 
     * a component. The factory itself can also be instantiated lazily by not specifying an instance, but a Class. 
     * 
     * @param factory the factory instance, or the factory class.
     * @param createMethod the create method called on the factory in order to instantiate the component.
     * @return this builder
     */
    B factory(Object factory, String createMethod);
        
    /**
     * Configures a factory that can be used to create this component implementation.
     * Example: 
     * 
     * <pre> {@code
     * factory(ComponentImpl::new)", or "factory(() -> new ComponentImpl())
     * }</pre>
     * 
     * @param create the factory used to create the component implementation.
     * @return this builder
     */
    B factory(Supplier<?> create);
    
    /**
     * Configures a factory used to create this component implementation using a Factory object and a method in the Factory object.
     * Example:
     * 
     * <pre> {@code
     * factory(Factory::new, Factory::create)
     * }</pre>
     * 
     * @param <U> the type of the factory returned by the supplier
     * @param <V> the type of the object that is returned by the factory create method.
     * @param factory the function used to create the Factory itself
     * @param create the method reference on the Factory method that is used to create the Component implementation
     * @return this builder
     */
    <U, V> B factory(Supplier<U> factory, Function<U, V> create);
        
    /**
     * Configures a factory used to create this component implementation using a Factory object and a "getComposition" factory method.
     * the Factory method may then return multiple objects that will be part of this component implementation, and 
     * all of them will be searched when injecting any of the dependencies.
     * 
     * Example:
     * 
     * <pre> {@code
     * CompositionManager mngr = new CompositionManager();
     * ...
     * factory(mngr::create, mngr::getComposition)
     * }</pre>
     * 
     * @param factory the supplier used to return the main component implementation instance
     * @param getComposition the supplier that returns the list of instances that are part of the component implementation classes.
     * @return this builder
     */
    B factory(Supplier<?> factory, Supplier<Object[]> getComposition);

    /**
     * Configures a factory that also returns a composition of objects for this component implemenation.
     * 
     * Example:
     * 
     * <pre> {@code
     * factory(CompositionManager::new, CompositionManager::create, CompositionManager::getComposition).
     * }</pre>
     * 
     * Here, the CompositionManager will act as a factory (the create method will return the component implementation object), the
     * CompositionManager.getComposition() method will return all the objects that are also part of the component implementation, 
     * and all of them will be searched for injecting any of the dependencies.
     * 
     * @param <U> the type of the object returned by the supplier factory
     * @param factory the function used to create the Factory itself
     * @param create the Factory method used to create the main component implementation object
     * @param getComposition the Factory method used to return the list of objects that are also part of the component implementation.
     * @return this builder
     */
    <U> B factory(Supplier<U> factory, Function<U, ?> create, Function<U, Object[]> getComposition);

    /**
     * Sets the public interface under which this component should be registered in the OSGi service registry.
     * 
     * @param iface the public interface to register in the OSGI service registry.
     * @return this builder
     */
	B provides(Class<?>  iface);
	
	/**
     * Sets the public interface under which this component should be registered in the OSGi service registry.
     * 
     * @param iface the public interface to register in the OSGI service registry.
	 * @param name a property name for the provided service
	 * @param value a property value for the provided service
	 * @param rest the rest of property name/value pairs.
	 * @return this builder.
	 */
	B provides(Class<?>  iface, String name, Object value, Object ... rest);
	
	/**
     * Sets the public interface under which this component should be registered in the OSGi service registry.
     * Warning: you can only use this method if you compile your application using the "-parameters" javac option.
     * 
     * code example:
     * 
     * <pre> {@code
     *  provides(MyService.class, property1 -> "value1", property2 -> 123);
     * }</pre>
     *
     * @param iface the public interface to register in the OSGI service registry.
	 * @param properties a list of fluent service properties for the provided service. You can specify a list of lambda expression, each one implementing the
	 * {@link FluentProperty} interface that allows to define a property name using a lambda parameter.
     * @return this builder.
     * @deprecated Fluent properties are only supported using java8 and this method will be removed in next DM release
	 */
	B provides(Class<?>  iface, FluentProperty ... properties);
	
	/**
     * Sets the public interface under which this component should be registered in the OSGi service registry.
     * @param iface the public interface to register in the OSGI service registry.
	 * @param properties the properties for the provided service
     * @return this builder.
	 */
    B provides(Class<?>  iface, Dictionary<?,?> properties);
    
    /**
     * Sets the public interfaces under which this component should be registered in the OSGi service registry.
     * 
     * @param ifaces list of services provided by the component.
     * @return this builder.
     */
    B provides(Class<?>[] ifaces);
    
    /**
     * Sets the public interfaces under which this component should be registered in the OSGi service registry.
     * 
     * @param ifaces the public interfaces to register in the OSGI service registry.
     * @param name a property name for the provided service
     * @param value a property value for the provided service
     * @param rest the rest of property name/value pairs.
     * @return this builder.
     */
    B provides(Class<?>[] ifaces, String name, Object value, Object ... rest);
    
    /**
     * Sets the public interfaces under which this component should be registered in the OSGi service registry.
     * Warning: you can only use this method if you compile your application using the "-parameters" javac option. 
     * code example:
     * 
     * <pre> {@code
     *    provides(new Class[] { MyService.class, MyService2.class }, property1 -> "value1", property2 -> 123);
     * }</pre>
     *
     * @param ifaces the public interfaces to register in the OSGI service registry.
     * @param properties a list of fluent service properties for the provided service. You can specify a list of lambda expression, each one implementing the
     * {@link FluentProperty} interface that allows to define a property name using a lambda parameter.
     * @return this builder.
     * @deprecated Fluent properties are only supported using java8 and this method will be removed in next DM release
     */
    B provides(Class<?>[] ifaces, FluentProperty ... properties);
    
    /**
     * Sets the public interfaces under which this component should be registered in the OSGi service registry.
     * 
     * @param ifaces the public interfaces to register in the OSGI service registry.
     * @param properties the properties for the provided service
     * @return this builder.
     */
    B provides(Class<?>[] ifaces, Dictionary<?,?> properties);

    /**
     * Sets the public interface under which this component should be registered in the OSGi service registry.
     * 
     * @param iface the service provided by this component.
     * @return this builder.
     */
    B provides(String iface);
    
    /**
     * Sets the public interface under which this component should be registered in the OSGi service registry.
     * 
     * @param iface the public interface to register in the OSGI service registry.
     * @param name a property name for the provided service
     * @param value a property value for the provided service
     * @param rest the rest of property name/value pairs.
     * @return this builder.
     */
    B provides(String iface, String name, Object value, Object ... rest);
    
    /**
     * Sets the public interface under which this component should be registered in the OSGi service registry. 
     * Warning: you can only use this method if you compile your application using the "-parameters" javac option.
     * code example:
     * 
     * <pre> {@code 
     * provides(MyService.class, property1 -> "value1", property2 -> 123);
     * }</pre>
     *
     * @param iface the public interface to register in the OSGI service registry.
     * @param properties a list of fluent service properties for the provided service. You can specify a list of lambda expression, each one implementing the
     * {@link FluentProperty} interface that allows to define a property name using a lambda parameter.
     * @return this builder.
     * @deprecated Fluent properties are only supported using java8 and this method will be removed in next DM release
     */
    B provides(String iface, FluentProperty ... properties);
    
    /**
     * Sets the public interface under which this component should be registered in the OSGi service registry.
     * @param iface the public interface to register in the OSGI service registry.
     * @param properties the properties for the provided service
     * @return this builder.
     */
    B provides(String iface, Dictionary<?,?> properties);
    
    /**
     * Sets the public interfaces under which this component should be registered in the OSGi service registry.
     * 
     * @param ifaces the list of services provided by the component.
     * @return this builder.
     */
    B provides(String[] ifaces);
    
    /**
     * Sets the public interfaces under which this component should be registered in the OSGi service registry.
     * 
     * @param ifaces the public interfaces to register in the OSGI service registry.
     * @param name a property name for the provided service
     * @param value a property value for the provided service
     * @param rest the rest of property name/value pairs.
     * @return this builder.
     */
    B provides(String[] ifaces, String name, Object value, Object ... rest);
    
    /**
     * Sets the public interfaces under which this component should be registered in the OSGi service registry.
     * Warning: you can only use this method if you compile your application using the "-parameters" javac option.
     * 
     * code example:
     * <pre> {@code 
     * provides(new Class[] { MyService.class, MyService2.class }, property1 -> "value1", property2 -> 123);
     * }</pre>
     * 
     * @param ifaces the public interfaces to register in the OSGI service registry.
     * @param properties a list of fluent service properties for the provided service. You can specify a list of lambda expression, each one implementing the
     * {@link FluentProperty} interface that allows to define a property name using a lambda parameter.
     * @return this builder.
     * @deprecated Fluent properties are only supported using java8 and this method will be removed in next DM release
     */
    B provides(String[] ifaces, FluentProperty ... properties);
    
    /**
     * Sets the public interfaces under which this component should be registered in the OSGi service registry.
     * 
     * @param ifaces the public interfaces to register in the OSGI service registry.
     * @param properties the properties for the provided service
     * @return this builder.
     */
    B provides(String[] ifaces, Dictionary<?,?> properties);

    /**
     * Sets the component's service properties
     * @param properties the component's service properties
     * @return this builder
     */
    B properties(Dictionary<?,?> properties);     
    
    /**
     * Sets the components's service properties using varargs. The number of parameters must be even, representing a list of pair property key-value.
     * 
     * <pre> {@code 
     * Example: properties("param1", "value1", "service.ranking", 3)
     * }</pre>
     * 
     * @param name the first property name
     * @param value the first property value
     * @param rest the rest of properties key/value pairs.
     * @return this builder
     */
    B properties(String name, Object value, Object ... rest);  
    
    /**
     * Sets the components's service properties using List of lamda properties. 
     *  
     * Example: 
     * 
     * <pre> {@code
     *   properties(param1 -> "value1, param2 -> 2);
     * }</pre>
     * 
     * When you use this method, you must compile your source code using the "-parameters" option, and the "arg0" parameter
     * name is now allowed.
     * 
     * @param properties the fluent properties
     * @return this builder
     * @deprecated Fluent properties are only supported using java8 and this method will be removed in next DM release
     */
    B properties(FluentProperty ... properties);  

    /**
     * Adds a service dependency built using a Consumer lambda that is provided with a ServiceDependencyBuilder. 
     * 
     * @param <U> the type of the dependency service
     * @param service the service
     * @param consumer the lambda used to build the service dependency
     * @return this builder.
     */
    <U> B withSvc(Class<U> service, Consumer<ServiceDependencyBuilder<U>> consumer);
    
    /**
     * Adds in one shot multiple service dependencies injected in compatible class fields.
     * 
     * @param services some dependencies to inject in compatible class fields.
     * @return this builder
     */
    @SuppressWarnings("unchecked")
    default B withSvc(Class<?> ... services) {
        Stream.of(services).forEach(s -> withSvc(s, svc -> svc.autoConfig()));
        return (B) this;
    }

    /**
     * Adds in one shot multiple service dependencies injected in compatible class fields.
     * 
     * @param required true if the dependency is required, false if not
     * @param services some dependencies to inject in compatible class fields.
     * @return this builder
     */
    @SuppressWarnings("unchecked")
    default B withSvc(boolean required, Class<?> ... services) {
        Stream.of(services).forEach(s -> withSvc(s, svc -> svc.required(required)));
        return (B) this;
    }
    
    /**
     * Adds a service dependency injected in compatible class fields.
     * 
     * @param service a service dependency
     * @param required true if the dependency is required, false if not
     * @return this builder
     */
    @SuppressWarnings("unchecked")
    default B withSvc(Class<?> service, boolean required) {
        withSvc(service, svc -> svc.required(required));
        return (B) this;
    }
      
    /**
     * Adds a service dependency injected in compatible class fields.
     * 
     * @param <T> the service dependency type
     * @param service the service dependency.
     * @param filter the service filter
     * @param required true if the dependency is required, false if not
     * @return this builder
     */
    default <T> B withSvc(Class<T> service, String filter, boolean required) {
        return withSvc(service, svc -> svc.filter(filter).required(required));
    }
    
    /**
     * Adds a service dependency injected in a given compatible class field.
     * 
     * @param <T> the service dependency type
     * @param service the service dependency
     * @param filter the service filter
     * @param field the class field when the dependency has to be injected
     * @param required true if the dependency is required, false if not
     * @return this builder
     */
    default <T> B withSvc(Class<T> service, String filter, String field, boolean required) {
        return withSvc(service, svc -> svc.filter(filter).autoConfig(field).required(required));
    }
    
    /**
     * Adds a configuration dependency.
     * @param consumer the lambda used to build the configuration dependency.
     * @return this builder.
     */
    B withCnf(Consumer<ConfigurationDependencyBuilder> consumer);     
    
    /**
     * Adds multiple configuration dependencies in one single call. All configurations are injected by default in the "updated" callback.
     * @param pids list of configuration pids.
     * @return this builder
     */
    @SuppressWarnings("unchecked")
    default B withCnf(String ... pids) {
        Stream.of(pids).forEach(pid -> withCnf(cnf -> cnf.pid(pid)));
        return (B) this;
    }
    
    /**
     * Adds a configuration dependency using a configuration type. The configuration is injected in an updated callback which takes in argument
     * an implementation of the specified configuration type.
     * 
     * @param configType the configuration type that will be injected to the "updated" callback
     * @return this builder
     * @see ConfigurationDependencyBuilder
     */
    default B withCnf(Class<?> configType) {
        return withCnf(cnf -> cnf.update(configType, "updated"));
    }
    
    /**
     * Adds a bundle dependency.
     * @param consumer the lambda used to build the bundle dependency.
     * @return this builder.
     */
    B withBundle(Consumer<BundleDependencyBuilder> consumer);        

    /**
     * Adds a CompletableFuture dependency.
     * 
     * @param <U> the type of the result of the CompletableFuture.
     * @param future a CompletableFuture on which the dependency will wait for
     * @param consumer the builder used to build the dependency
     * @return this builder.
     */
    <U> B withFuture(CompletableFuture<U> future, Consumer<FutureDependencyBuilder<U>> consumer);
        
    /**
     * Adds a generic Dependency Manager dependency. You can use this method if you want to add a dependency
     * that you have built using the Dependency Manager API, or a specific custom DM dependency (like toggles, etc ...).
     */
    B withDep(Dependency dependency);    
    
    /**
     * Sets the name of the method used as the "init" callback. This method, when found, is
     * invoked as part of the life cycle management of the component implementation. 
     * This method is useful because when it is invoked, all required dependencies defines in the Activator
     * are already injected, and you can then add more extra dependencies from the init() method.
     * And once all extra dependencies will be available and injected, then the "start" callback will be invoked.
     * <p>The dependency manager will look for a method of this name with the following signatures,
     * in this order:
     * <ol>
     * <li>method(Component component)</li>
     * <li>method()</li>
     * </ol>
     * 
     * @param callback the callback name
     * @return this builder.
     */
    B init(String callback);
    
    /**
     * Sets a callback instance and the name of the method used as the "init" callback. This method, when found, is
     * invoked as part of the life cycle management of the component implementation. 
     * This method is useful because when it is invoked, all required dependencies defines in the Activator
     * are already injected, and you can then add more extra dependencies from the init() method.
     * And once all extra dependencies will be available and injected, then the "start" callback will be invoked.
     * <p>The dependency manager will look for a method of this name with the following signatures,
     * in this order:
     * <ol>
     * <li>method(Component component)</li>
     * <li>method()</li>
     * </ol>
     * 
     * @param callbackInstance a callback instance object the callback is invoked on
     * @param callback the callback name
     * @return this builder.
     */
    B init(Object callbackInstance, String callback);

    /**
     * Sets an Object instance method reference used as the "init" callback. It is invoked as part of the life cycle management of the component 
     * implementation. 
     * This method is useful because when it is invoked, all required dependencies defines in the Activator
     * are already injected, and you can then add more extra dependencies from the init() method.
     * And once all extra dependencies will be available and injected, then the "start" callback will be invoked.
     * The method does not take any parameters.
     * 
     * @param callback an Object instance method reference. The method does not take any parameters.
     * @return this builder
     */
    B init(InstanceCb callback);
 
    /**
     * Sets an Object instance method reference used as the "init" callback. It is invoked as part of the life cycle management of the component 
     * implementation. 
     * This method is useful because when it is invoked, all required dependencies defines in the Activator
     * are already injected, and you can then add more extra dependencies from the init() method.
     * And once all extra dependencies will be available and injected, then the "start" callback will be invoked.
     * The method takes as argument a Component parameter.
     * 
     * @param callback an Object instance method reference. The method takes as argument a Component parameter.
     * @return this builder
     */
    B init(InstanceCbComponent callback);
   
    /**
     * Sets a callback instance and the name of the method used as the "start" callback. This method, when found, is
     * invoked as part of the life cycle management of the component implementation. <p>The
     * dependency manager will look for a method of this name with the following signatures,
     * in this order:
     * <ol>
     * <li>method(Component component)</li>
     * <li>method()</li>
     * </ol>
     * 
     * @param callback the callback name
     * @return this builder.
     */
    B start(String callback);
    
    /**
     * Sets the name of the method used as the "start" callback. This method, when found, is
     * invoked as part of the life cycle management of the component implementation. <p>The
     * dependency manager will look for a method of this name with the following signatures,
     * in this order:
     * <ol>
     * <li>method(Component component)</li>
     * <li>method()</li>
     * </ol>
     * 
     * @param callbackInstance a callback instance object the callback is invoked on
     * @param callback the callback name
     * @return this builder.
     */
    B start(Object callbackInstance, String callback);

    /**
     * Sets an Object instance method reference used as the "start" callback. 
     * This method is invoked as part of the life cycle management of the component implementation. 
     * The method does not take any parameters.
     *
     * @param callback an Object instance method reference. The method does not take any parameters.
     * @return this builder.
     */
    B start(InstanceCb callback);
  
    /**
     * Sets an Object instance method reference used as the "start" callback.
     * This method is invoked as part of the life cycle management of the component implementation. 
     * The method takes as argument a Component parameter.
     *
     * @param callback an Object instance method reference. The method takes as argument a Component parameter.
     * @return this builder.
     */
    B start(InstanceCbComponent callback);
    
    /**
     * Sets the name of the method used as the "stop" callback. This method, when found, is
     * invoked as part of the life cycle management of the component implementation. <p>The
     * dependency manager will look for a method of this name with the following signatures,
     * in this order:
     * <ol>
     * <li>method(Component component)</li>
     * <li>method()</li>
     * </ol>
     * 
     * @param callback the callback name
     * @return this builder.
     */
    B stop(String callback);
    
    /**
     * Sets a callback instance and the name of the method used as the "stop" callback. This method, when found, is
     * invoked as part of the life cycle management of the component implementation. <p>The
     * dependency manager will look for a method of this name with the following signatures,
     * in this order:
     * <ol>
     * <li>method(Component component)</li>
     * <li>method()</li>
     * </ol>
     * 
     * @param callbackInstance a callback instance object the callback is invoked on
     * @param callback the callback name
     * @return this builder.
     */
    B stop(Object callbackInstance, String callback);

    /**
     * Sets an Object instance method reference used as the "stop" callback. It is invoked as part of the life cycle management of the component 
     * implementation. 
     * This method is useful because when it is invoked, all required dependencies defines in the Activator
     * are already injected, and you can then add more extra dependencies from the init() method.
     * And once all extra dependencies will be available and injected, then the "start" callback will be invoked.
     * The method does not take any parameters.
     * 
     * @param callback an Object instance method reference. The method does not take any parameters.
     * @return this builder
     */
    B stop(InstanceCb callback);
  
    /**
     * Sets an Object instance method reference used as the "stop" callback. 
     * This method is invoked as part of the life cycle management of the component implementation. 
     * The method takes as argument a Component parameter.
     *
     * @param callback an Object instance method reference. The method takes as argument a Component parameter.
     * @return this builder.
     */
    B stop(InstanceCbComponent callback);
  
    /**
     * Sets the name of the method used as the "destroy" callback. This method, when found, is
     * invoked as part of the life cycle management of the component implementation. <p>The
     * dependency manager will look for a method of this name with the following signatures,
     * in this order:
     * <ol>
     * <li>method(Component component)</li>
     * <li>method()</li>
     * </ol>
     * 
     * @param callback the callback name
     * @return this builder.
     */
    B destroy(String callback);
    
    /**
     * Sets a callback instance and the name of the method used as the "destroy" callback. This method, when found, is
     * invoked as part of the life cycle management of the component implementation. <p>The
     * dependency manager will look for a method of this name with the following signatures,
     * in this order:
     * <ol>
     * <li>method(Component component)</li>
     * <li>method()</li>
     * </ol>
     * 
     * @param callbackInstance a callback instance object the callback is invoked on
     * @param callback the callback name
     * @return this builder.
     */
    B destroy(Object callbackInstance, String callback);

    /**
     * Sets an Object instance method reference used as the "destroy" callback. It is invoked as part of the life cycle management of the component 
     * implementation. 
     * This method is useful because when it is invoked, all required dependencies defines in the Activator
     * are already injected, and you can then add more extra dependencies from the init() method.
     * And once all extra dependencies will be available and injected, then the "start" callback will be invoked.
     * The method does not take any parameters.
     * 
     * @param callback an Object instance method reference. The method does not take any parameters.
     * @return this builder
     */
    B destroy(InstanceCb callback);

    /**
     * Sets an Object instance method reference used as the "destroy" callback. 
     * This method is invoked as part of the life cycle management of the component implementation. 
     * The method takes as argument a Component parameter.
     *
     * @param callback an Object instance method reference. The method takes as argument a Component parameter.
     * @return this builder.
     */
    B destroy(InstanceCbComponent callback);

    /**
     * Configures OSGi object (BundleContext, Component, etc ...) that will be injected in any field having the same OSGi object type.
     * @param clazz the OSGi object type (BundleContext, Component, DependencyManager).
     * @param autoConfig true if the OSGi object has to be injected, false if not
     * @return this builder
     */
    B autoConfig(Class<?> clazz, boolean autoConfig); 
    
    /**
     * Configures OSGi object (BundleContext, Component, etc ...) that will be injected in a given field.
     * @param clazz the OSGi object type (BundleContext, Component, DependencyManager).
     * @param field the field that will be injected with the OSGI object
     * @return this builder
     */
    B autoConfig(Class<?> clazz, String field);
    
    /**
     * Activates debug mode
     * @param label the debug label
     * @return this builder
     */
    B debug(String label);
    
    /**
     * Automatically adds this component to its DependencyManager object. When a lambda builds a Component using this builder, by default
     * the built component is auto added to its DependencyManager object, unless you invoke autoAdd(false).
     * 
     * @param autoAdd true for automatically adding this component to the DependencyManager object, false if not
     * @return this builder
     */
    B autoAdd(boolean autoAdd);
    
    /**
     * Sets the method to invoke on the service implementation to get back all
     * instances that are part of a composition and need dependencies injected.
     * All of them will be searched to inject any of the dependencies. The method that
     * is invoked must return an <code>Object[]</code>.
     * 
     * @param getCompositionMethod the method to invoke
     * @return this builder
     */
    B composition(String getCompositionMethod);
    
    /**
     * Sets the instance and method to invoke to get back all instances that
     * are part of a composition and need dependencies injected. All of them
     * will be searched to inject any of the dependencies. The method that is
     * invoked must return an <code>Object[]</code>.
     * 
     * @param instance the instance that has the method
     * @param getCompositionMethod the method to invoke
     * @return this builder
     */
    B composition(Object instance, String getCompositionMethod);

    /**
     * Sets a java8 method reference to a Supplier that returns all instances that are part of a composition and need dependencies injected.
     * All of them will be searched for any of the dependencies. The method that
     * is invoked must return an <code>Object[]</code>.
     * 
     * @param getCompositionMethod the method to invoke
     * @return this builder
     */
    B composition(Supplier<Object[]> getCompositionMethod);
        
    /**
     * Adds a component state listener to this component.
     * 
     * @param listener the state listener
     */
	B listener(ComponentStateListener listener);
    
    /**
     * Builds the real DependencyManager Component.
     * @return the real DependencyManager Component.
     */
    Component build();
}
