Copy transaction handler test suite to the trunk

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@786967 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/IPOJOHelper.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/IPOJOHelper.java
new file mode 100644
index 0000000..0fbe4d9
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/IPOJOHelper.java
@@ -0,0 +1,730 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.transaction.test;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.Factory;
+import org.apache.felix.ipojo.Handler;
+import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.ServiceContext;
+import org.apache.felix.ipojo.architecture.Architecture;
+import org.apache.felix.ipojo.metadata.Element;
+import org.apache.felix.ipojo.parser.ManifestMetadataParser;
+import org.apache.felix.ipojo.parser.ParseException;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ManagedServiceFactory;
+
+/**
+ * iPOJO Helper.
+ * This helper helps getting {@link Factory}, and managing
+ * {@link ComponentInstance}.
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public class IPOJOHelper {
+
+    /**
+     * The bundle context.
+     */
+    private BundleContext m_context;
+
+
+    /**
+     * List of instances.
+     */
+    private List<ComponentInstance> m_instances;
+
+    /**
+     * Creates a IPOJOHelper.
+     * @param tc the OSGi Test Case
+     */
+    public IPOJOHelper(BundleContext context) {
+        m_context = context;
+        m_instances = new ArrayList<ComponentInstance>();
+    }
+
+    /**
+     * Disposes created instances.
+     * @see org.apache.felix.ipojo.junit4osgi.Helper#dispose()
+     */
+    public void dispose() {
+        for (int i = 0; i < m_instances.size(); i++) {
+            ((ComponentInstance) m_instances.get(i)).dispose();
+        }
+        m_instances.clear();
+    }
+
+    /**
+     * Gets a created instance from the instance name.
+     * @param name the instance name.
+     * @return the created {@link ComponentInstance} or <code>null</code>
+     * if the instance was not created during the session.
+     */
+    public ComponentInstance getInstanceByName(String name) {
+        for (int i = 0; i < m_instances.size(); i++) {
+            if (((ComponentInstance) m_instances.get(i)).getInstanceName()
+                    .equals(name)) {
+                return (ComponentInstance) m_instances.get(i);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Creates a new component instance with the given name (and empty
+     * configuration), from the factory specified in the given bundle.
+     * 
+     * @param bundle the bundle from which the component factory is defined.
+     * @param factoryName the name of the component factory, defined in the
+     *            specified bundle.
+     * @param instanceName the name of the component instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(Bundle bundle,
+            String factoryName, String instanceName) {
+
+        // Create the instance configuration
+        Properties configuration = new Properties();
+        configuration.put("instance.name", instanceName);
+
+        return createComponentInstance(bundle, factoryName, configuration);
+    }
+
+    /**
+     * Creates a new component instance with the given configuration, from the
+     * factory specified in the given bundle.
+     * 
+     * @param bundle the bundle from which the component factory is defined.
+     * @param factoryName the name of the component factory, defined in the
+     *            specified bundle.
+     * @param configuration the configuration of the component instance to
+     *            create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(Bundle bundle,
+            String factoryName, Dictionary configuration) {
+
+        // Retrieve the component factory.
+        Factory fact = getFactory(bundle, factoryName);
+
+        if (fact == null) {
+            // Factory not found...
+            throw new IllegalArgumentException(
+                    "Cannot find the component factory (" + factoryName
+                            + ") in the specified bundle ("
+                            + bundle.getSymbolicName() + ").");
+        }
+
+        try {
+            return fact.createComponentInstance(configuration);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(
+                    "Cannot create the component instance with the given configuration:"
+                            + e.getMessage());
+        }
+    }
+
+    /**
+     * Creates a new component instance with the given name and configuration,
+     * from the factory specified in the given bundle.
+     * 
+     * @param bundle the bundle from which the component factory is defined.
+     * @param factoryName the name of the component factory, defined in the
+     *            specified bundle.
+     * @param instanceName the name of the component instance to create.
+     * @param configuration the configuration of the instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(Bundle bundle,
+            String factoryName, String instanceName, Dictionary configuration) {
+
+        // Add the instance name to the configuration
+        configuration.put("instance.name", instanceName);
+
+        return createComponentInstance(bundle, factoryName, configuration);
+    }
+
+    /**
+     * Creates a new component instance with the given name (and an empty
+     * configuration), from the factory specified in the given service context.
+     * 
+     * @param serviceContext the service context in which the component factory
+     *            service is registered.
+     * @param factoryName the name of the component factory, defined in the
+     *            specified service context.
+     * @param instanceName the name of the component instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(
+            ServiceContext serviceContext, String factoryName,
+            String instanceName) {
+
+        // Create the instance configuration
+        Properties configuration = new Properties();
+        configuration.put("instance.name", instanceName);
+
+        return createComponentInstance(serviceContext, factoryName,
+                configuration);
+    }
+
+    /**
+     * Creates a new component instance with the given name and configuration,
+     * from the factory specified in the given service context.
+     * 
+     * @param serviceContext the service context in which the component factory
+     *            service is registered.
+     * @param factoryName the name of the component factory, defined in the
+     *            specified service context.
+     * @param configuration the configuration of the instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(
+            ServiceContext serviceContext, String factoryName,
+            Dictionary configuration) {
+
+        // Retrieve the component factory.
+        Factory fact = getFactory(serviceContext, factoryName);
+
+        if (fact == null) {
+            // Factory not found...
+            throw new IllegalArgumentException(
+                    "Cannot find the component factory (" + factoryName
+                            + ") in the specified service context.");
+        }
+
+        try {
+            return fact.createComponentInstance(configuration);
+        } catch (Exception e) {
+            throw new IllegalArgumentException(
+                    "Cannot create the component instance with the given configuration: "
+                            + e.getMessage());
+        }
+    }
+
+    /**
+     * Creates a new component instance with the given name and configuration,
+     * from the factory specified in the given service context.
+     * 
+     * @param serviceContext the service context in which the component factory
+     *            service is registered.
+     * @param factoryName the name of the component factory, defined in the
+     *            specified service context.
+     * @param instanceName the name of the component instance to create.
+     * @param configuration the configuration of the instance to create.
+     * @return the newly created component instance.
+     */
+    public static ComponentInstance createComponentInstance(
+            ServiceContext serviceContext, String factoryName,
+            String instanceName, Dictionary configuration) {
+
+        // Add the instance name to the configuration
+        configuration.put("instance.name", instanceName);
+
+        return createComponentInstance(serviceContext, factoryName,
+                configuration);
+    }
+
+    /**
+     * Creates a new component instance with the given name (and empty
+     * configuration), from the factory specified in the local bundle.
+     * 
+     * @param factoryName the name of the component factory, defined in the
+     *            local bundle.
+     * @param instanceName the name of the component instance to create.
+     * @return the newly created component instance.
+     */
+    public ComponentInstance createComponentInstance(String factoryName,
+            String instanceName) {
+        ComponentInstance ci = createComponentInstance(m_context.getBundle(),
+                factoryName, instanceName);
+        m_instances.add(ci);
+        return ci;
+    }
+
+    /**
+     * Creates a new component instance with the given configuration, from the
+     * factory specified in the local bundle.
+     * 
+     * @param factoryName the name of the component factory, in the local
+     *            bundle.
+     * @param configuration the configuration of the component instance to
+     *            create.
+     * @return the newly created component instance.
+     */
+    public ComponentInstance createComponentInstance(String factoryName,
+            Dictionary configuration) {
+        ComponentInstance ci = createComponentInstance(m_context.getBundle(),
+                factoryName, configuration);
+        m_instances.add(ci);
+        return ci;
+    }
+
+    /**
+     * Creates a new component instance with no configuration, from the factory
+     * specified in the local bundle.
+     * 
+     * @param factoryName the name of the component factory, in the local
+     *            bundle.
+     * @return the newly created component instance.
+     */
+    public ComponentInstance createComponentInstance(String factoryName) {
+        ComponentInstance ci = createComponentInstance(m_context.getBundle(),
+                factoryName, (Dictionary) null);
+        m_instances.add(ci);
+        return ci;
+    }
+
+    /**
+     * Creates a new component instance with the given name and configuration,
+     * from the factory specified in the given bundle.
+     * 
+     * @param factoryName the name of the component factory, defined in the
+     *            specified bundle.
+     * @param instanceName the name of the component instance to create.
+     * @param configuration the configuration of the instance to create.
+     * @return the newly created component instance.
+     */
+    public ComponentInstance createComponentInstance(String factoryName,
+            String instanceName, Dictionary configuration) {
+        ComponentInstance ci = createComponentInstance(m_context.getBundle(),
+                factoryName, instanceName, configuration);
+        m_instances.add(ci);
+        return ci;
+    }
+
+    /**
+     * Returns the component factory with the given name in the local bundle.
+     * 
+     * @param factoryName the name of the factory to retrieve.
+     * @return the component factory with the given name in the local bundle, or
+     *         {@code null} if not found.
+     */
+    public Factory getFactory(String factoryName) {
+        return getFactory(m_context.getBundle(), factoryName);
+    }
+
+    /**
+     * Returns the handler factory with the given name in the local bundle.
+     * 
+     * @param factoryName the name of the handler factory to retrieve.
+     * @return the handler factory with the given name in the local bundle, or
+     *         {@code null} if not found.
+     */
+    public HandlerFactory getHandlerFactory(String factoryName) {
+        return getHandlerFactory(m_context.getBundle(), factoryName);
+    }
+
+    /**
+     * Returns the metadata description of the component defined in this bundle.
+     * 
+     * @param component the name of the locally defined component.
+     * @return the metadata description of the component with the given name,
+     *         defined in this given bundle, or {@code null} if not found.
+     */
+    public Element getMetadata(String component) {
+        return getMetadata(m_context.getBundle(), component);
+    }
+
+    /**
+     * Returns the component factory with the given name in the given bundle.
+     * 
+     * @param bundle the bundle from which the component factory is defined.
+     * @param factoryName the name of the defined factory.
+     * @return the component factory with the given name in the given bundle, or
+     *         {@code null} if not found.
+     */
+    public static Factory getFactory(Bundle bundle, String factoryName) {
+        ServiceReference[] refs;
+        try {
+            // Retrieves the component factories services in the bundle.
+            refs = bundle.getBundleContext().getServiceReferences(
+                    Factory.class.getName(),
+                    "(factory.name=" + factoryName + ")");
+            if (refs != null) {
+                return (Factory) bundle.getBundleContext().getService(refs[0]);
+            }
+
+            // Factory not found...
+            return null;
+
+        } catch (InvalidSyntaxException e) {
+            throw new IllegalArgumentException(
+                    "Cannot get the component factory services: "
+                            + e.getMessage());
+        }
+    }
+
+    /**
+     * Returns the component factory with the given name, registered in the
+     * given service context.
+     * 
+     * @param serviceContext the service context in which the factory service is
+     *            defined.
+     * @param factoryName the name of the factory.
+     * @return the component factory with the given name, registered in the
+     *         given service context.
+     */
+    public static Factory getFactory(ServiceContext serviceContext,
+            String factoryName) {
+        ServiceReference[] refs;
+        try {
+            // Retrieves the component factories services in the service
+            // context.
+            refs = serviceContext.getServiceReferences(Factory.class.getName(),
+                    "(factory.name=" + factoryName + ")");
+            if (refs != null) {
+                return (Factory) serviceContext.getService(refs[0]);
+            }
+            return null;
+
+        } catch (InvalidSyntaxException e) {
+            System.err.println("Cannot get the factory " + factoryName + " : "
+                    + e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * Returns the handler factory with the given name in the given bundle.
+     * 
+     * @param bundle the bundle from which the handler factory is defined.
+     * @param factoryName the name of the handler factory to retrieve.
+     * @return the handler factory with the given name in the given bundle, or
+     *         {@code null} if not found.
+     */
+    public static HandlerFactory getHandlerFactory(Bundle bundle,
+            String factoryName) {
+        ServiceReference[] refs;
+        try {
+            // Retrieves the handler factories services in the bundle.
+            refs = bundle.getBundleContext().getServiceReferences(
+                    HandlerFactory.class.getName(),
+                    "(" + Handler.HANDLER_NAME_PROPERTY + "=" + factoryName
+                            + ")");
+            if (refs != null) {
+                return (HandlerFactory) bundle.getBundleContext().getService(
+                        refs[0]);
+            }
+
+            // Factory not found...
+            return null;
+        } catch (InvalidSyntaxException e) {
+            throw new IllegalArgumentException(
+                    "Cannot get the handler factory services: "
+                            + e.getMessage());
+        }
+    }
+
+    /**
+     * Returns the metadata description of the component with the given name,
+     * defined in the given bundle.
+     * 
+     * @param bundle the bundle from which the component is defined.
+     * @param component the name of the defined component.
+     * @return the metadata description of the component with the given name,
+     *         defined in the given bundle, or {@code null} if not found.
+     */
+    public static Element getMetadata(Bundle bundle, String component) {
+
+        // Retrieves the component description from the bundle's manifest.
+        String elem = (String) bundle.getHeaders().get("iPOJO-Components");
+        if (elem == null) {
+            throw new IllegalArgumentException(
+                    "Cannot find iPOJO-Components descriptor in the specified bundle ("
+                            + bundle.getSymbolicName()
+                            + "). Not an iPOJO bundle.");
+        }
+
+        // Parses the retrieved description and find the component with the
+        // given name.
+        try {
+            Element element = ManifestMetadataParser.parseHeaderMetadata(elem);
+            Element[] childs = element.getElements("component");
+            for (int i = 0; i < childs.length; i++) {
+                String name = childs[i].getAttribute("name");
+                String clazz = childs[i].getAttribute("classname");
+                if (name != null && name.equalsIgnoreCase(component)) {
+                    return childs[i];
+                }
+                if (clazz.equalsIgnoreCase(component)) {
+                    return childs[i];
+                }
+            }
+
+            // Component not found...
+            return null;
+
+        } catch (ParseException e) {
+            throw new IllegalStateException(
+                    "Cannot parse the components from specified bundle ("
+                            + bundle.getSymbolicName() + "): " + e.getMessage());
+        }
+    }
+
+    /**
+     * Returns the service object of a service registered in the specified
+     * service context, offering the specified interface and matching the given
+     * filter.
+     * 
+     * @param serviceContext the service context in which the service is
+     *            searched.
+     * @param itf the interface provided by the searched service.
+     * @param filter an additional filter (can be {@code null}).
+     * @return the service object provided by the specified bundle, offering the
+     *         specified interface and matching the given filter.
+     */
+    public static Object getServiceObject(ServiceContext serviceContext,
+            String itf, String filter) {
+        ServiceReference ref = getServiceReference(serviceContext, itf, filter);
+        if (ref != null) {
+            return serviceContext.getService(ref);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the service objects of the services registered in the specified
+     * service context, offering the specified interface and matching the given
+     * filter.
+     * 
+     * @param serviceContext the service context in which services are searched.
+     * @param itf the interface provided by the searched services.
+     * @param filter an additional filter (can be {@code null}).
+     * @return the service objects provided by the specified bundle, offering
+     *         the specified interface and matching the given filter.
+     */
+    public static Object[] getServiceObjects(ServiceContext serviceContext,
+            String itf, String filter) {
+        ServiceReference[] refs = getServiceReferences(serviceContext, itf,
+                filter);
+        if (refs != null) {
+            Object[] list = new Object[refs.length];
+            for (int i = 0; i < refs.length; i++) {
+                list[i] = serviceContext.getService(refs[i]);
+            }
+            return list;
+        } else {
+            return new Object[0];
+        }
+    }
+
+    /**
+     * Returns the service reference of a service registered in the specified
+     * service context, offering the specified interface and matching the given
+     * filter.
+     * 
+     * @param serviceContext the service context in which services are searched.
+     * @param itf the interface provided by the searched service.
+     * @param filter an additional filter (can be {@code null}).
+     * @return a service reference registered in the specified service context,
+     *         offering the specified interface and matching the given filter.
+     *         If no service is found, {@code null} is returned.
+     */
+    public static ServiceReference getServiceReference(
+            ServiceContext serviceContext, String itf, String filter) {
+        ServiceReference[] refs = getServiceReferences(serviceContext, itf,
+                filter);
+        if (refs.length != 0) {
+            return refs[0];
+        } else {
+            // No service found
+            return null;
+        }
+    }
+
+    /**
+     * Returns the service reference of the service registered in the specified
+     * service context, offering the specified interface and having the given
+     * persistent ID.
+     * 
+     * @param serviceContext the service context in which services are searched.
+     * @param itf the interface provided by the searched service.
+     * @param pid the persistent ID of the searched service.
+     * @return a service registered in the specified service context, offering
+     *         the specified interface and having the given persistent ID.
+     */
+    public static ServiceReference getServiceReferenceByPID(
+            ServiceContext serviceContext, String itf, String pid) {
+        String filter = "(" + "service.pid" + "=" + pid + ")";
+        ServiceReference[] refs = getServiceReferences(serviceContext, itf,
+                filter);
+        if (refs == null) {
+            return null;
+        } else if (refs.length == 1) {
+            return refs[0];
+        } else {
+            throw new IllegalStateException(
+                    "A service lookup by PID returned several providers ("
+                            + refs.length + ")" + " for " + itf + " with pid="
+                            + pid);
+        }
+    }
+
+    /**
+     * Returns the service reference of all the services registered in the
+     * specified service context, offering the specified interface and matching
+     * the given filter.
+     * 
+     * @param serviceContext the service context in which services are searched.
+     * @param itf the interface provided by the searched services.
+     * @param filter an additional filter (can be {@code null}).
+     * @return all the service references registered in the specified service
+     *         context, offering the specified interface and matching the given
+     *         filter. If no service matches, an empty array is returned.
+     */
+    public static ServiceReference[] getServiceReferences(
+            ServiceContext serviceContext, String itf, String filter) {
+        ServiceReference[] refs = null;
+        try {
+            // Get all the service references
+            refs = serviceContext.getServiceReferences(itf, filter);
+        } catch (InvalidSyntaxException e) {
+            throw new IllegalArgumentException(
+                    "Cannot get service references: " + e.getMessage());
+        }
+        if (refs == null) {
+            return new ServiceReference[0];
+        } else {
+            return refs;
+        }
+    }
+
+    /**
+     * Returns the service reference of a service registered in the specified
+     * service context, offering the specified interface and having the given
+     * name.
+     * 
+     * @param serviceContext the service context in which services are searched.
+     * @param itf the interface provided by the searched service.
+     * @param name the name of the searched service.
+     * @return a service registered in the specified service context, offering
+     *         the specified interface and having the given name.
+     */
+    public static ServiceReference getServiceReferenceByName(
+            ServiceContext serviceContext, String itf, String name) {
+        String filter = null;
+        if (itf.equals(Factory.class.getName())
+                || itf.equals(ManagedServiceFactory.class.getName())) {
+            filter = "(" + "factory.name" + "=" + name + ")";
+        } else if (itf.equals(Architecture.class.getName())) {
+            filter = "(" + "architecture.instance" + "=" + name + ")";
+        } else {
+            filter = "(" + "instance.name" + "=" + name + ")";
+        }
+        return getServiceReference(serviceContext, itf, filter);
+    }
+
+    /**
+     * Checks the availability of a service inside the given service context.
+     * @param sc the service context
+     * @param itf the service interface to found
+     * @return <code>true</code> if the service is available in the service
+     *         context, <code>false</code> otherwise.
+     */
+    public static boolean isServiceAvailable(ServiceContext sc, String itf) {
+        ServiceReference ref = getServiceReference(sc, itf, null);
+        return ref != null;
+    }
+
+    /**
+     * Checks the availability of a service inside the given service context.
+     * @param sc the service context
+     * @param itf the service interface to found
+     * @param name the service provider name
+     * @return <code>true</code> if the service is available in the service
+     *         context, <code>false</code> otherwise.
+     */
+    public static boolean isServiceAvailableByName(ServiceContext sc,
+            String itf, String name) {
+        ServiceReference ref = getServiceReferenceByName(sc, itf, name);
+        return ref != null;
+    }
+
+    /**
+     * Checks the availability of a service inside the given service context.
+     * @param sc the service context
+     * @param itf the service interface to found
+     * @param pid the pid of the service
+     * @return <code>true</code> if the service is available in the service
+     *         context, <code>false</code> otherwise.
+     */
+    public static boolean isServiceAvailableByPID(ServiceContext sc,
+            String itf, String pid) {
+        ServiceReference ref = getServiceReferenceByPID(sc, itf, pid);
+        return ref != null;
+    }
+
+    /**
+     * Returns the service reference of a service provided by the specified
+     * bundle, offering the specified interface and having the given name.
+     * 
+     * @param bundle the bundle from which the service is searched.
+     * @param itf the interface provided by the searched service.
+     * @param name the name of the searched service.
+     * @return a service provided by the specified bundle, offering the
+     *         specified interface and having the given name.
+     */
+    public static ServiceReference getServiceReferenceByName(Bundle bundle,
+            String itf, String name) {
+        String filter = null;
+        if (itf.equals(Factory.class.getName())
+                || itf.equals(ManagedServiceFactory.class.getName())) {
+            filter = "(" + "factory.name" + "=" + name + ")";
+        } else if (itf.equals(Architecture.class.getName())) {
+            filter = "(" + "architecture.instance" + "=" + name + ")";
+        } else {
+            filter = "(" + "instance.name" + "=" + name + ")";
+        }
+        return OSGiHelper.getServiceReference(bundle, itf, filter);
+    }
+
+    /**
+     * Returns the service reference of a service provided by the local bundle,
+     * offering the specified interface and having the given name.
+     * 
+     * @param itf the interface provided by the searched service.
+     * @param name the name of the searched service.
+     * @return a service provided by the specified bundle, offering the
+     *         specified interface and having the given name.
+     */
+    public ServiceReference getServiceReferenceByName(String itf, String name) {
+        return getServiceReferenceByName(m_context.getBundle(), itf, name);
+    }
+
+    /**
+     * Checks if the service is available.
+     * @param itf the service interface
+     * @param name the service provider name
+     * @return <code>true</code> if the service is available, <code>false</code>
+     *         otherwise.
+     */
+    public boolean isServiceAvailableByName(String itf, String name) {
+        ServiceReference ref = getServiceReferenceByName(itf, name);
+        return ref != null;
+    }
+
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/OSGiHelper.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/OSGiHelper.java
new file mode 100644
index 0000000..604ee18
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/OSGiHelper.java
@@ -0,0 +1,456 @@
+package org.apache.felix.ipojo.transaction.test;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+import static org.junit.Assert.fail;
+
+
+public class OSGiHelper {
+    
+    /**
+     * The bundle context.
+     */
+    private BundleContext context;
+    
+    /**
+     * List of get references.
+     */
+    private List<ServiceReference> m_references = new ArrayList<ServiceReference>();
+    
+    public OSGiHelper(BundleContext context) {
+        this.context = context;
+    }
+    
+    public void dispose() {
+        // Unget services
+        for (int i = 0; i < m_references.size(); i++) {
+            context.ungetService((ServiceReference) m_references.get(i));
+        }
+        m_references.clear();
+    }
+    
+    /**
+     * Gets the Bundle Context.
+     * @return the bundle context.
+     */
+    public BundleContext getContext() {
+        return context;
+    }
+    
+    /**
+     * Returns the service object of a service provided by the specified bundle,
+     * offering the specified interface and matching the given filter.
+     * 
+     * @param bundle the bundle from which the service is searched.
+     * @param itf the interface provided by the searched service.
+     * @param filter an additional filter (can be {@code null}).
+     * @return the service object provided by the specified bundle, offering the
+     *         specified interface and matching the given filter.
+     */
+    public static Object getServiceObject(Bundle bundle, String itf,
+            String filter) {
+        ServiceReference ref = getServiceReference(bundle, itf, filter);
+        if (ref != null) {
+            return bundle.getBundleContext().getService(ref);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the service objects of the services provided by the specified
+     * bundle, offering the specified interface and matching the given filter.
+     * 
+     * @param bundle the bundle from which services are searched.
+     * @param itf the interface provided by the searched services.
+     * @param filter an additional filter (can be {@code null}).
+     * @return the service objects provided by the specified bundle, offering
+     *         the specified interface and matching the given filter.
+     */
+    public static Object[] getServiceObjects(Bundle bundle, String itf,
+            String filter) {
+        ServiceReference[] refs = getServiceReferences(bundle, itf, filter);
+        if (refs != null) {
+            Object[] list = new Object[refs.length];
+            for (int i = 0; i < refs.length; i++) {
+                list[i] = bundle.getBundleContext().getService(refs[i]);
+            }
+            return list;
+        } else {
+            return new Object[0];
+        }
+    }
+
+    /**
+     * Returns the service reference of a service provided by the specified
+     * bundle, offering the specified interface and matching the given filter.
+     * 
+     * @param bundle the bundle from which the service is searched.
+     * @param itf the interface provided by the searched service.
+     * @param filter an additional filter (can be {@code null}).
+     * @return a service reference provided by the specified bundle, offering
+     *         the specified interface and matching the given filter. If no
+     *         service is found, {@code null} is returned.
+     */
+    public static ServiceReference getServiceReference(Bundle bundle,
+            String itf, String filter) {
+        ServiceReference[] refs = getServiceReferences(bundle, itf, filter);
+        if (refs.length != 0) {
+            return refs[0];
+        } else {
+            // No service found
+            return null;
+        }
+    }
+
+    /**
+     * Checks if the service is available.
+     * @param itf the service interface
+     * @return <code>true</code> if the service is available, <code>false</code>
+     *         otherwise.
+     */
+    public boolean isServiceAvailable(String itf) {
+        ServiceReference ref = getServiceReference(itf, null);
+        return ref != null;
+    }
+
+    /**
+     * Checks if the service is available.
+     * @param itf the service interface
+     * @param pid the service pid
+     * @return <code>true</code> if the service is available, <code>false</code>
+     *         otherwise.
+     */
+    public boolean isServiceAvailableByPID(String itf, String pid) {
+        ServiceReference ref = getServiceReferenceByPID(itf, pid);
+        return ref != null;
+    }
+
+    /**
+     * Returns the service reference of the service provided by the specified
+     * bundle, offering the specified interface and having the given persistent
+     * ID.
+     * 
+     * @param bundle the bundle from which the service is searched.
+     * @param itf the interface provided by the searched service.
+     * @param pid the persistent ID of the searched service.
+     * @return a service provided by the specified bundle, offering the
+     *         specified interface and having the given persistent ID.
+     */
+    public static ServiceReference getServiceReferenceByPID(Bundle bundle,
+            String itf, String pid) {
+        String filter = "(" + "service.pid" + "=" + pid + ")";
+        ServiceReference[] refs = getServiceReferences(bundle, itf, filter);
+        if (refs == null) {
+            return null;
+        } else if (refs.length == 1) {
+            return refs[0];
+        } else {
+            throw new IllegalStateException(
+                    "A service lookup by PID returned several providers ("
+                            + refs.length + ")" + " for " + itf + " with pid="
+                            + pid);
+        }
+    }
+
+    /**
+     * Returns the service reference of all the services provided in the
+     * specified bundle, offering the specified interface and matching the given
+     * filter.
+     * 
+     * @param bundle the bundle from which services are searched.
+     * @param itf the interface provided by the searched services.
+     * @param filter an additional filter (can be {@code null}).
+     * @return all the service references provided in the specified bundle,
+     *         offering the specified interface and matching the given filter.
+     *         If no service matches, an empty array is returned.
+     */
+    public static ServiceReference[] getServiceReferences(Bundle bundle,
+            String itf, String filter) {
+        ServiceReference[] refs = null;
+        try {
+            // Get all the service references
+            refs = bundle.getBundleContext().getServiceReferences(itf, filter);
+        } catch (InvalidSyntaxException e) {
+            throw new IllegalArgumentException(
+                    "Cannot get service references: " + e.getMessage());
+        }
+        if (refs == null) {
+            return new ServiceReference[0];
+        } else {
+            return refs;
+        }
+    }
+
+    /**
+     * Returns the service object of a service provided by the local bundle,
+     * offering the specified interface and matching the given filter.
+     * 
+     * @param itf the interface provided by the searched service.
+     * @param filter an additional filter (can be {@code null}).
+     * @return the service object provided by the local bundle, offering the
+     *         specified interface and matching the given filter.
+     */
+    public Object getServiceObject(String itf, String filter) {
+        ServiceReference ref = getServiceReference(itf, filter);
+        if (ref != null) {
+            m_references.add(ref);
+            return context.getService(ref);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the service object associated with this service reference.
+     * 
+     * @param ref service reference
+     * @return the service object.
+     */
+    public Object getServiceObject(ServiceReference ref) {
+        if (ref != null) {
+            m_references.add(ref);
+            return context.getService(ref);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the service objects of the services provided by the local bundle,
+     * offering the specified interface and matching the given filter.
+     * 
+     * @param itf the interface provided by the searched services.
+     * @param filter an additional filter (can be {@code null}).
+     * @return the service objects provided by the local bundle, offering the
+     *         specified interface and matching the given filter.
+     */
+    public Object[] getServiceObjects(String itf, String filter) {
+        ServiceReference[] refs = getServiceReferences(itf, filter);
+        if (refs != null) {
+            Object[] list = new Object[refs.length];
+            for (int i = 0; i < refs.length; i++) {
+                m_references.add(refs[i]);
+                list[i] = context.getService(refs[i]);
+            }
+            return list;
+        } else {
+            return new Object[0];
+        }
+    }
+
+    /**
+     * Returns the service reference of a service provided by the local bundle,
+     * offering the specified interface and matching the given filter.
+     * 
+     * @param itf the interface provided by the searched service.
+     * @param filter an additional filter (can be {@code null}).
+     * @return a service reference provided by the local bundle, offering the
+     *         specified interface and matching the given filter. If no service
+     *         is found, {@code null} is returned.
+     */
+    public ServiceReference getServiceReference(String itf, String filter) {
+        return getServiceReference(context.getBundle(), itf, filter);
+    }
+
+    /**
+     * Returns the service reference of a service provided offering the
+     * specified interface.
+     * 
+     * @param itf the interface provided by the searched service.
+     * @return a service reference provided by the local bundle, offering the
+     *         specified interface and matching the given filter. If no service
+     *         is found, {@code null} is returned.
+     */
+    public ServiceReference getServiceReference(String itf) {
+        return getServiceReference(context.getBundle(), itf, null);
+    }
+
+    /**
+     * Returns the service reference of the service provided by the local
+     * bundle, offering the specified interface and having the given persistent
+     * ID.
+     * 
+     * @param itf the interface provided by the searched service.
+     * @param pid the persistent ID of the searched service.
+     * @return a service provided by the local bundle, offering the specified
+     *         interface and having the given persistent ID.
+     */
+    public ServiceReference getServiceReferenceByPID(String itf, String pid) {
+        return getServiceReferenceByPID(context.getBundle(), itf, pid);
+    }
+
+    /**
+     * Returns the service reference of all the services provided in the local
+     * bundle, offering the specified interface and matching the given filter.
+     * 
+     * @param itf the interface provided by the searched services.
+     * @param filter an additional filter (can be {@code null}).
+     * @return all the service references provided in the local bundle, offering
+     *         the specified interface and matching the given filter. If no
+     *         service matches, an empty array is returned.
+     */
+    public ServiceReference[] getServiceReferences(String itf, String filter) {
+        return getServiceReferences(context.getBundle(), itf, filter);
+    }
+    
+    /**
+     * Gets the package admin exposed by the framework.
+     * Fails if the package admin is not available. 
+     * @return the package admin service.
+     */
+    public PackageAdmin getPackageAdmin() {
+        PackageAdmin pa = (PackageAdmin) getServiceObject(PackageAdmin.class.getName(), null);
+        if (pa == null) {
+            fail("No package admin available");
+        }
+        return pa;
+    }
+    
+    /**
+     * Refresh the packages.
+     * Fails if the package admin service is not available.
+     */
+    public void refresh() {
+        getPackageAdmin().refreshPackages(null);
+    }
+    
+    /**
+     * Waits for a service. Fails on timeout.
+     * If timeout is set to 0, it sets the timeout to 10s.
+     * @param itf the service interface
+     * @param filter  the filter
+     * @param timeout the timeout
+     */
+    public void waitForService(String itf, String filter, long timeout) {
+        if (timeout == 0) {
+            timeout = 10000; // Default 10 secondes.
+        }
+        ServiceReference[] refs = getServiceReferences(itf, filter);
+        long begin = System.currentTimeMillis();
+        if (refs.length != 0) {
+            return;
+        } else {
+            while(refs.length == 0) {
+                try {
+                    Thread.sleep(5);
+                } catch (InterruptedException e) {
+                    // Interrupted
+                }
+                long now = System.currentTimeMillis();
+                
+                if ((now - begin) > timeout) {
+                    fail("Timeout ... no services matching with the request after " + timeout + "ms");
+                }
+                refs = getServiceReferences(itf, filter);
+            }
+        }
+    }
+    
+    
+    /**
+     * Installs a bundle.
+     * Fails if the bundle cannot be installed.
+     * Be aware that you have to uninstall the bundle yourself.
+     * @param url bundle url
+     * @return the installed bundle
+     */
+    public Bundle installBundle(String url) {
+        try {
+            return context.installBundle(url);
+        } catch (BundleException e) {
+            fail("Cannot install the bundle " + url + " : " + e.getMessage());
+        }
+        return null; // Can not happen
+    }
+    
+    /**
+     * Installs a bundle.
+     * Fails if the bundle cannot be installed.
+     * Be aware that you have to uninstall the bundle yourself.
+     * @param url bundle url
+     * @param stream input stream containing the bundle
+     * @return the installed bundle
+     */
+    public Bundle installBundle(String url, InputStream stream) {
+        try {
+            return context.installBundle(url, stream);
+        } catch (BundleException e) {
+            fail("Cannot install the bundle " + url + " : " + e.getMessage());
+        }
+        return null; // Can not happen
+    }
+    
+    /**
+     * Installs and starts a bundle.
+     * Fails if the bundle cannot be installed or an error occurs
+     * during startup. Be aware that you have to uninstall the bundle
+     * yourself.
+     * @param url the bundle url
+     * @return the Bundle object.
+     */
+    public Bundle installAndStart(String url) {
+        Bundle bundle = installBundle(url);
+        try {
+            bundle.start();
+        } catch (BundleException e) {
+           fail("Cannot start the bundle " + url + " : " + e.getMessage());
+        }
+        return bundle;
+    }
+    
+    /**
+     * Installs and starts a bundle.
+     * Fails if the bundle cannot be installed or an error occurs
+     * during startup. Be aware that you have to uninstall the bundle
+     * yourself.
+     * @param url the bundle url
+     * @param stream input stream containing the bundle
+     * @return the Bundle object.
+     */
+    public Bundle installAndStart(String url, InputStream stream) {
+        Bundle bundle = installBundle(url, stream);
+        try {
+            bundle.start();
+        } catch (BundleException e) {
+           fail("Cannot start the bundle " + url + " : " + e.getMessage());
+        }
+        return bundle;
+    }
+    
+    /**
+     * Get the bundle by its id.
+     * @param bundleId the bundle id.
+     * @return the bundle with the given id.
+     */
+    public Bundle getBundle(long bundleId) {
+        return context.getBundle(bundleId);
+    }
+    
+    /**
+     * Gets a bundle by its symbolic name.
+     * Fails if no bundle matches.
+     * @param name the symbolic name of the bundle
+     * @return the bundle object.
+     */
+    public Bundle getBundle(String name) {
+        Bundle[] bundles = context.getBundles();
+        for (int i = 0; i < bundles.length; i++) {
+            if (name.equals(bundles[i].getSymbolicName())) {
+                return bundles[i];
+            }
+        }
+        fail("No bundles with the given symbolic name " + name);
+        return null; // should not happen
+    }
+
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestInstallation.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestInstallation.java
new file mode 100644
index 0000000..0803abd
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestInstallation.java
@@ -0,0 +1,157 @@
+package org.apache.felix.ipojo.transaction.test;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.with;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.HandlerFactory;
+import org.apache.felix.ipojo.pax.exam.target.BundleAsiPOJO;
+import org.apache.felix.ipojo.transaction.test.component.FooDelegator;
+import org.apache.felix.ipojo.transaction.test.component.FooImpl;
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@RunWith( JUnit4TestRunner.class )
+public class TestInstallation {
+    
+    @Inject
+    private BundleContext context;
+    
+    private OSGiHelper osgi;
+    
+    private IPOJOHelper ipojo;
+    
+    public static final File ROOT = new File("target/tmp");
+    public static final File TEST = new File("src/test/resources");
+
+    
+    @Before
+    public void init() {
+        osgi = new OSGiHelper(context);
+        ipojo = new IPOJOHelper(context);
+    }
+    
+    @After
+    public void stop() {
+        ipojo.dispose();
+        osgi.dispose();
+    }
+    
+    @Configuration
+    public static Option[] configure() {    
+        ROOT.mkdirs();
+
+        URL service = TinyBundles.newBundle()
+            .addClass(CheckService.class)
+            .addClass(Foo.class)
+           .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Service")
+                .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                )
+            .build( TinyBundles.asURL());
+            
+        String fooimpl = TinyBundles.newBundle()
+            .addClass(FooImpl.class)
+            .prepare( 
+                    with()
+                    .set(Constants.BUNDLE_SYMBOLICNAME,"Foo Provider")
+                    .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                )
+                .build( new BundleAsiPOJO(new File(ROOT, "FooImpl.jar"), new File(TEST, "foo.xml"))  ).toExternalForm();
+        
+        String test = TinyBundles.newBundle()
+        .addClass(FooDelegator.class)
+        .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Required Transaction Propgatation")
+                .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service, javax.transaction")
+            )
+            .build( new BundleAsiPOJO(new File(ROOT, "requires.jar"), new File(TEST, "requires.xml"))  ).toExternalForm();
+    
+        
+        Option[] opt =  options(
+ 
+                provision(
+                        mavenBundle().groupId("org.ops4j.pax.logging").artifactId("pax-logging-api").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo.transaction").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.transaction").version(asInProject()),
+                        mavenBundle()
+                        .groupId( "org.ops4j.pax.tinybundles" )
+                        .artifactId( "pax-tinybundles-core" )
+                        .version( "0.5.0-SNAPSHOT" ),
+                        bundle(service.toExternalForm()),
+                        bundle(fooimpl),
+                        bundle(test)
+                    )
+                )
+
+                ;
+        return opt;
+    }
+    
+    @Test
+    public void install() throws NotSupportedException, SystemException, IllegalStateException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        Bundle[] bundles = context.getBundles();
+        for (Bundle b : bundles) {
+            Assert.assertTrue(b.getSymbolicName(), b.getState() == Bundle.ACTIVE);
+        }
+        
+        // Transaction Service available
+        osgi.isServiceAvailable(TransactionManager.class.getName());
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Assert.assertNotNull(tm.getTransaction());
+        tm.commit();
+        
+        tm.begin();
+        Assert.assertNotNull(tm.getTransaction());
+        tm.rollback();
+        
+        // Handler exposed
+        ServiceReference ref = osgi.getServiceReference(HandlerFactory.class.getName(), "(&(handler.name=transaction)(handler.namespace=org.apache.felix.ipojo.transaction))");
+        Assert.assertNotNull(ref);
+        
+        // Create an install of the components
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingGood();
+    }
+
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestInvalidation.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestInvalidation.java
new file mode 100644
index 0000000..a57a2a8
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestInvalidation.java
@@ -0,0 +1,166 @@
+package org.apache.felix.ipojo.transaction.test;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.with;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.pax.exam.target.BundleAsiPOJO;
+import org.apache.felix.ipojo.transaction.test.component.FooDelegator;
+import org.apache.felix.ipojo.transaction.test.component.FooImpl;
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@RunWith( JUnit4TestRunner.class )
+public class TestInvalidation {
+    
+    @Inject
+    private BundleContext context;
+    
+    private OSGiHelper osgi;
+    
+    private IPOJOHelper ipojo;
+    
+    public static final File ROOT = new File("target/tmp");
+    public static final File TEST = new File("src/test/resources");
+
+    
+    @Before
+    public void init() {
+        osgi = new OSGiHelper(context);
+        ipojo = new IPOJOHelper(context);
+    }
+    
+    @After
+    public void stop() {
+        ipojo.dispose();
+        osgi.dispose();
+    }
+    
+    @Configuration
+    public static Option[] configure() {    
+        ROOT.mkdirs();
+
+        
+        URL service = TinyBundles.newBundle()
+            .addClass(CheckService.class)
+            .addClass(Foo.class)
+           .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Service")
+                .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                .set(Constants.IMPORT_PACKAGE, "javax.transaction")
+                )
+            .build( TinyBundles.asURL());
+            
+        String fooimpl = TinyBundles.newBundle()
+            .addClass(FooImpl.class)
+            .prepare( 
+                    with()
+                    .set(Constants.BUNDLE_SYMBOLICNAME,"Foo Provider")
+                    .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                )
+                .build( new BundleAsiPOJO(new File(ROOT, "FooImpl.jar"), new File(TEST, "foo.xml"))  ).toExternalForm();
+        
+        String test = TinyBundles.newBundle()
+        .addClass(FooDelegator.class)
+        .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Required Transaction Propgatation")
+                .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service, javax.transaction")
+            )
+            .build( new BundleAsiPOJO(new File(ROOT, "requires.jar"), new File(TEST, "requires.xml"))  ).toExternalForm();
+    
+        
+        Option[] opt =  options(
+ 
+                provision(
+                        mavenBundle().groupId("org.ops4j.pax.logging").artifactId("pax-logging-api").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo.transaction").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.transaction").version(asInProject()),
+                        mavenBundle()
+                        .groupId( "org.ops4j.pax.tinybundles" )
+                        .artifactId( "pax-tinybundles-core" )
+                        .version( "0.5.0-SNAPSHOT" ),
+                        bundle(service.toExternalForm()),
+                        bundle(fooimpl),
+                        bundle(test)
+                    )
+                )
+
+                ;
+        return opt;
+    }
+    
+    
+    
+    
+    @Test
+    public void testInvalidation() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        final ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        
+        Thread thread = new Thread (new Runnable() {
+           public void run() {
+               try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+               prov.dispose();
+           }
+        });
+        
+        thread.start();
+        
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        cs.doSomethingLong(); // 5s, so prov should be disposed during this time and under becomes invalid
+        
+        Assert.assertEquals(ComponentInstance.INVALID, under.getState());
+        
+        Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+        
+        t.rollback();
+    }
+    
+   
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestMandatory.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestMandatory.java
new file mode 100644
index 0000000..66772e2
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestMandatory.java
@@ -0,0 +1,430 @@
+package org.apache.felix.ipojo.transaction.test;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.with;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.pax.exam.target.BundleAsiPOJO;
+import org.apache.felix.ipojo.transaction.test.component.FooDelegator;
+import org.apache.felix.ipojo.transaction.test.component.FooImpl;
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@RunWith( JUnit4TestRunner.class )
+public class TestMandatory {
+    
+    @Inject
+    private BundleContext context;
+    
+    private OSGiHelper osgi;
+    
+    private IPOJOHelper ipojo;
+    
+    public static final File ROOT = new File("target/tmp");
+    public static final File TEST = new File("src/test/resources");
+
+    
+    @Before
+    public void init() {
+        osgi = new OSGiHelper(context);
+        ipojo = new IPOJOHelper(context);
+    }
+    
+    @After
+    public void stop() {
+        ipojo.dispose();
+        osgi.dispose();
+    }
+    
+    @Configuration
+    public static Option[] configure() {    
+        ROOT.mkdirs();
+
+        URL service = TinyBundles.newBundle()
+            .addClass(CheckService.class)
+            .addClass(Foo.class)
+           .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Service")
+                .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                .set(Constants.IMPORT_PACKAGE, "javax.transaction")
+                )
+            .build( TinyBundles.asURL());
+            
+        String fooimpl = TinyBundles.newBundle()
+            .addClass(FooImpl.class)
+            .prepare( 
+                    with()
+                    .set(Constants.BUNDLE_SYMBOLICNAME,"Foo Provider")
+                    .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                )
+                .build( new BundleAsiPOJO(new File(ROOT, "FooImpl.jar"), new File(TEST, "foo.xml"))  ).toExternalForm();
+        
+        String test = TinyBundles.newBundle()
+        .addClass(FooDelegator.class)
+        .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Mandatory Transaction Propgatation")
+                .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service, javax.transaction")
+            )
+            .build( new BundleAsiPOJO(new File(ROOT, "mandatory.jar"), new File(TEST, "mandatory.xml"))  ).toExternalForm();
+    
+        
+        Option[] opt =  options(
+ 
+                provision(
+                        mavenBundle().groupId("org.ops4j.pax.logging").artifactId("pax-logging-api").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo.transaction").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.transaction").version(asInProject()),
+                        mavenBundle()
+                        .groupId( "org.ops4j.pax.tinybundles" )
+                        .artifactId( "pax-tinybundles-core" )
+                        .version( "0.5.0-SNAPSHOT" ),
+                        bundle(service.toExternalForm()),
+                        bundle(fooimpl),
+                        bundle(test)
+                    )
+                )
+
+                ;
+        return opt;
+    }
+    
+    
+    @Test(expected=RuntimeException.class)
+    public void testOkOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingGood(); // Fail !
+    }
+    
+    @Test
+    public void testOkInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        cs.doSomethingGood();
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        t.commit();
+    }
+    
+    @Test(expected=RuntimeException.class)
+    public void testExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad(); // Fail, RTE thrown before the other exception
+    }
+    
+    @Test(expected=RollbackException.class)
+    public void testExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+        
+        t.commit(); // Throws a rollback exception.
+    }
+    
+    @Test
+    public void testExceptionInsideTransactionRB() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+        
+        t.rollback();
+    }
+    
+    @Test(expected=RuntimeException.class)
+    public void testExpectedExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad2(); // Throws a RTE
+    }
+    
+    @Test
+    public void testExpectedExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad2();
+            Assert.fail("UnsupportedOperationException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof UnsupportedOperationException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.commit();
+    }
+    
+    @Test(expected=RuntimeException.class)
+    public void testOkOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingGood(); // Throws a RTE.
+        
+    }
+    
+    @Test
+    public void testOkInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        cs.doSomethingGood();
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        t.commit();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNotNull(cs.getLastCommitted());
+        Assert.assertEquals(1, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+        
+        Assert.assertSame(t, cs.getLastCommitted());
+    }
+    
+    @Test(expected=RuntimeException.class)
+    public void testExceptionOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingBad(); // Thows a RTE.
+       
+    }
+    
+    @Test
+    public void testExceptionInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+        
+        try {
+            t.commit(); // Throw a rollback exception.
+        } catch (RollbackException e) {
+            // Expected
+        } catch (Throwable e) {
+            Assert.fail(e.getMessage()); // Unexpected
+        }
+        
+        Assert.assertNotNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(1, cs.getNumberOfRollback());
+        
+        Assert.assertSame(t, cs.getLastRolledBack());
+    }
+    
+    @Test(expected=RuntimeException.class)
+    public void testExpectedExceptionOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingBad2();
+        
+      
+    }
+    
+    @Test
+    public void testExpectedExceptionInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("mandatory-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad2();
+            Assert.fail("UnsupportedOperationException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof UnsupportedOperationException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.commit();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNotNull(cs.getLastCommitted());
+        Assert.assertEquals(1, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+        
+        Assert.assertSame(t, cs.getLastCommitted());
+    }
+    
+
+    
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestNever.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestNever.java
new file mode 100644
index 0000000..21d6369
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestNever.java
@@ -0,0 +1,210 @@
+package org.apache.felix.ipojo.transaction.test;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.with;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.pax.exam.target.BundleAsiPOJO;
+import org.apache.felix.ipojo.transaction.test.component.FooDelegator;
+import org.apache.felix.ipojo.transaction.test.component.FooImpl;
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@RunWith( JUnit4TestRunner.class )
+public class TestNever {
+    
+    @Inject
+    private BundleContext context;
+    
+    private OSGiHelper osgi;
+    
+    private IPOJOHelper ipojo;
+    public static final File ROOT = new File("target/tmp");
+    public static final File TEST = new File("src/test/resources");
+
+    
+    @Before
+    public void init() {
+        osgi = new OSGiHelper(context);
+        ipojo = new IPOJOHelper(context);
+    }
+    
+    @After
+    public void stop() {
+        ipojo.dispose();
+        osgi.dispose();
+    }
+    
+    @Configuration
+    public static Option[] configure() {    
+        ROOT.mkdirs();
+
+        URL service = TinyBundles.newBundle()
+            .addClass(CheckService.class)
+            .addClass(Foo.class)
+           .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Service")
+                .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                .set(Constants.IMPORT_PACKAGE, "javax.transaction")
+                )
+            .build( TinyBundles.asURL());
+            
+        String fooimpl = TinyBundles.newBundle()
+            .addClass(FooImpl.class)
+            .prepare( 
+                    with()
+                    .set(Constants.BUNDLE_SYMBOLICNAME,"Foo Provider")
+                    .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                )
+                .build( new BundleAsiPOJO(new File(ROOT,"FooImpl.jar"), new File(TEST, "foo.xml"))  ).toExternalForm();
+        
+        String test = TinyBundles.newBundle()
+        .addClass(FooDelegator.class)
+        .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Mandatory Transaction Propgatation")
+                .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service, javax.transaction")
+            )
+            .build( new BundleAsiPOJO(new File(ROOT, "never.jar"), new File(TEST, "never.xml"))  ).toExternalForm();
+    
+        
+        Option[] opt =  options(
+ 
+                provision(
+                        mavenBundle().groupId("org.ops4j.pax.logging").artifactId("pax-logging-api").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo.transaction").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.transaction").version(asInProject()),
+                        mavenBundle()
+                        .groupId( "org.ops4j.pax.tinybundles" )
+                        .artifactId( "pax-tinybundles-core" )
+                        .version( "0.5.0-SNAPSHOT" ),
+                        bundle(service.toExternalForm()),
+                        bundle(fooimpl),
+                        bundle(test)
+                    )
+                )
+
+                ;
+        return opt;
+    }
+    
+    
+    @Test
+    public void testOkOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("never-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingGood();
+    }
+    
+    @Test(expected=RuntimeException.class)
+    public void testOkInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("never-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        cs.doSomethingGood(); // Fail
+    }
+    
+    @Test(expected=NullPointerException.class)
+    public void testExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("never-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad(); // Throws an NPE 
+    }
+    
+    @Test
+    public void testExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("never-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad(); // Fail
+            Assert.fail("RuntimeException expected");
+        } catch(RuntimeException e) {
+            Assert.assertTrue(e instanceof RuntimeException);
+        }
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.rollback(); 
+    }
+    
+    @Test(expected=UnsupportedOperationException.class)
+    public void testExpectedExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("never-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad2(); 
+    }
+    
+   
+    
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestNotSupported.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestNotSupported.java
new file mode 100644
index 0000000..bd866fc
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestNotSupported.java
@@ -0,0 +1,436 @@
+package org.apache.felix.ipojo.transaction.test;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.with;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.pax.exam.target.BundleAsiPOJO;
+import org.apache.felix.ipojo.transaction.test.component.FooDelegator;
+import org.apache.felix.ipojo.transaction.test.component.FooImpl;
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@RunWith( JUnit4TestRunner.class )
+public class TestNotSupported {
+    
+    @Inject
+    private BundleContext context;
+    
+    private OSGiHelper osgi;
+    
+    private IPOJOHelper ipojo;
+    public static final File ROOT = new File("target/tmp");
+    public static final File TEST = new File("src/test/resources");
+
+    
+    @Before
+    public void init() {
+        osgi = new OSGiHelper(context);
+        ipojo = new IPOJOHelper(context);
+    }
+    
+    @After
+    public void stop() {
+        ipojo.dispose();
+        osgi.dispose();
+    }
+    
+    @Configuration
+    public static Option[] configure() {    
+        ROOT.mkdirs();
+
+        URL service = TinyBundles.newBundle()
+            .addClass(CheckService.class)
+            .addClass(Foo.class)
+           .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Service")
+                .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                .set(Constants.IMPORT_PACKAGE, "javax.transaction")
+                )
+            .build( TinyBundles.asURL());
+            
+        String fooimpl = TinyBundles.newBundle()
+            .addClass(FooImpl.class)
+            .prepare( 
+                    with()
+                    .set(Constants.BUNDLE_SYMBOLICNAME,"Foo Provider")
+                    .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                )
+                .build( new BundleAsiPOJO(new File(ROOT, "FooImpl.jar"), new File(TEST, "foo.xml"))  ).toExternalForm();
+        
+        String test = TinyBundles.newBundle()
+        .addClass(FooDelegator.class)
+        .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Required Transaction Propgatation")
+                .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service, javax.transaction")
+            )
+            .build( new BundleAsiPOJO(new File(ROOT, "notsupported.jar"), new File(TEST, "notsupported.xml"))  ).toExternalForm();
+    
+        
+        Option[] opt =  options(
+ 
+                provision(
+                        mavenBundle().groupId("org.ops4j.pax.logging").artifactId("pax-logging-api").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo.transaction").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.transaction").version(asInProject()),
+                        mavenBundle()
+                        .groupId( "org.ops4j.pax.tinybundles" )
+                        .artifactId( "pax-tinybundles-core" )
+                        .version( "0.5.0-SNAPSHOT" ),
+                        bundle(service.toExternalForm()),
+                        bundle(fooimpl),
+                        bundle(test)
+                    )
+                )
+
+                ;
+        return opt;
+    }
+    
+    
+    @Test
+    public void testOkOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = ((CheckService) osgi.getServiceObject(ref));
+        cs.doSomethingGood();
+        // No transaction.
+    }
+    
+    @Test
+    public void testOkInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        cs.doSomethingGood();
+        Transaction t2 = cs.getCurrentTransaction(); // Is executed in the transaction despite it's not supported.
+        Assert.assertSame(t2, t);
+        t.commit();
+    }
+    
+    @Test(expected=NullPointerException.class)
+    public void testExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad();
+    }
+    
+    @Test
+    public void testExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus()); // No impact on the transaction.
+        
+        t.commit(); // Ok.
+    }
+    
+    @Test
+    public void testExceptionInsideTransactionRB() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus()); // No impact on the transaction.
+        
+        t.rollback(); // Ok.
+    }
+    
+    @Test(expected=UnsupportedOperationException.class)
+    public void testExpectedExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad2();
+    }
+    
+    @Test
+    public void testExpectedExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad2();
+            Assert.fail("UnsupportedOperationException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof UnsupportedOperationException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.commit();
+    }
+    
+    @Test
+    public void testOkOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingGood();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+    @Test
+    public void testOkInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        cs.doSomethingGood();
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        t.commit();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+    @Test(expected=NullPointerException.class)
+    public void testExceptionOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingBad();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+    @Test
+    public void testExceptionInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus()); // No effect on the transaction
+        
+        try {
+            t.commit(); // Throw a rollback exception.
+        } catch (RollbackException e) {
+            // Expected
+        } catch (Throwable e) {
+            Assert.fail(e.getMessage()); // Unexpected
+        }
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+    @Test(expected=UnsupportedOperationException.class)
+    public void testExpectedExceptionOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingBad2();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+    @Test
+    public void testExpectedExceptionInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("notsupported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad2();
+            Assert.fail("UnsupportedOperationException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof UnsupportedOperationException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.commit();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+
+    
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestRequires.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestRequires.java
new file mode 100644
index 0000000..75839a3
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestRequires.java
@@ -0,0 +1,441 @@
+package org.apache.felix.ipojo.transaction.test;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.with;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.pax.exam.target.BundleAsiPOJO;
+import org.apache.felix.ipojo.transaction.test.component.FooDelegator;
+import org.apache.felix.ipojo.transaction.test.component.FooImpl;
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@RunWith( JUnit4TestRunner.class )
+public class TestRequires {
+    
+    @Inject
+    private BundleContext context;
+    
+    private OSGiHelper osgi;
+    
+    private IPOJOHelper ipojo;
+    
+    public static final File ROOT = new File("target/tmp");
+    public static final File TEST = new File("src/test/resources");
+
+    
+    @Before
+    public void init() {
+        osgi = new OSGiHelper(context);
+        ipojo = new IPOJOHelper(context);
+    }
+    
+    @After
+    public void stop() {
+        ipojo.dispose();
+        osgi.dispose();
+    }
+    
+    @Configuration
+    public static Option[] configure() {    
+        ROOT.mkdirs();
+
+        URL service = TinyBundles.newBundle()
+            .addClass(CheckService.class)
+            .addClass(Foo.class)
+           .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Service")
+                .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                .set(Constants.IMPORT_PACKAGE, "javax.transaction")
+                )
+            .build( TinyBundles.asURL());
+            
+        String fooimpl = TinyBundles.newBundle()
+            .addClass(FooImpl.class)
+            .prepare( 
+                    with()
+                    .set(Constants.BUNDLE_SYMBOLICNAME,"Foo Provider")
+                    .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                )
+                .build( new BundleAsiPOJO(new File(ROOT, "FooImpl.jar"), new File(TEST, "foo.xml"))  ).toExternalForm();
+        
+        String test = TinyBundles.newBundle()
+        .addClass(FooDelegator.class)
+        .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Required Transaction Propgatation")
+                .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service, javax.transaction")
+            )
+            .build( new BundleAsiPOJO(new File(ROOT, "requires.jar"), new File(TEST, "requires.xml"))  ).toExternalForm();
+    
+        
+        Option[] opt =  options(
+ 
+                provision(
+                        mavenBundle().groupId("org.ops4j.pax.logging").artifactId("pax-logging-api").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo.transaction").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.transaction").version(asInProject()),
+                        mavenBundle()
+                        .groupId( "org.ops4j.pax.tinybundles" )
+                        .artifactId( "pax-tinybundles-core" )
+                        .version( "0.5.0-SNAPSHOT" ),
+                        bundle(service.toExternalForm()),
+                        bundle(fooimpl),
+                        bundle(test)
+                    )
+                )
+
+                ;
+        return opt;
+    }
+    
+    
+    @Test
+    public void testOkOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingGood();
+    }
+    
+    @Test
+    public void testOkInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        cs.doSomethingGood();
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        t.commit();
+    }
+    
+    @Test(expected=NullPointerException.class)
+    public void testExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad();
+    }
+    
+    @Test(expected=RollbackException.class)
+    public void testExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+        
+        t.commit(); // Throw a rollback exception.
+    }
+    
+    @Test
+    public void testExceptionInsideTransactionRB() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+        
+        t.rollback();
+    }
+    
+    @Test(expected=UnsupportedOperationException.class)
+    public void testExpectedExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad2();
+    }
+    
+    @Test
+    public void testExpectedExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad2();
+            Assert.fail("UnsupportedOperationException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof UnsupportedOperationException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.commit();
+    }
+    
+    @Test
+    public void testOkOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingGood();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNotNull(cs.getLastCommitted());
+        Assert.assertEquals(1, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+    @Test
+    public void testOkInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        cs.doSomethingGood();
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        t.commit();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNotNull(cs.getLastCommitted());
+        Assert.assertEquals(1, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+        
+        Assert.assertSame(t, cs.getLastCommitted());
+    }
+    
+    @Test(expected=NullPointerException.class)
+    public void testExceptionOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingBad();
+        
+        Assert.assertNotNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(1, cs.getNumberOfRollback());
+    }
+    
+    @Test
+    public void testExceptionInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+        
+        try {
+            t.commit(); // Throw a rollback exception.
+        } catch (RollbackException e) {
+            // Expected
+        } catch (Throwable e) {
+            Assert.fail(e.getMessage()); // Unexpected
+        }
+        
+        Assert.assertNotNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(1, cs.getNumberOfRollback());
+        
+        Assert.assertSame(t, cs.getLastRolledBack());
+    }
+    
+    @Test(expected=UnsupportedOperationException.class)
+    public void testExpectedExceptionOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingBad2();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNotNull(cs.getLastCommitted());
+        Assert.assertEquals(1, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+    @Test
+    public void testExpectedExceptionInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requires-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad2();
+            Assert.fail("UnsupportedOperationException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof UnsupportedOperationException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.commit();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNotNull(cs.getLastCommitted());
+        Assert.assertEquals(1, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+        
+        Assert.assertSame(t, cs.getLastCommitted());
+    }
+    
+
+    
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestRequiresNew.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestRequiresNew.java
new file mode 100644
index 0000000..974fca9
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestRequiresNew.java
@@ -0,0 +1,254 @@
+package org.apache.felix.ipojo.transaction.test;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.with;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.pax.exam.target.BundleAsiPOJO;
+import org.apache.felix.ipojo.transaction.test.component.FooDelegator;
+import org.apache.felix.ipojo.transaction.test.component.FooImpl;
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@RunWith( JUnit4TestRunner.class )
+public class TestRequiresNew {
+    
+    @Inject
+    private BundleContext context;
+    
+    private OSGiHelper osgi;
+    
+    private IPOJOHelper ipojo;
+    
+    public static final File ROOT = new File("target/tmp");
+    public static final File TEST = new File("src/test/resources");
+
+    
+    @Before
+    public void init() {
+        osgi = new OSGiHelper(context);
+        ipojo = new IPOJOHelper(context);
+    }
+    
+    @After
+    public void stop() {
+        ipojo.dispose();
+        osgi.dispose();
+    }
+    
+    @Configuration
+    public static Option[] configure() {    
+        ROOT.mkdirs();
+
+        URL service = TinyBundles.newBundle()
+            .addClass(CheckService.class)
+            .addClass(Foo.class)
+           .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Service")
+                .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                .set(Constants.IMPORT_PACKAGE, "javax.transaction")
+                )
+            .build( TinyBundles.asURL());
+            
+        String fooimpl = TinyBundles.newBundle()
+            .addClass(FooImpl.class)
+            .prepare( 
+                    with()
+                    .set(Constants.BUNDLE_SYMBOLICNAME,"Foo Provider")
+                    .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                )
+                .build( new BundleAsiPOJO(new File(ROOT, "FooImpl.jar"), new File(TEST, "foo.xml"))  ).toExternalForm();
+        
+        String test = TinyBundles.newBundle()
+        .addClass(FooDelegator.class)
+        .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Required Transaction Propgatation")
+                .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service, javax.transaction")
+            )
+            .build( new BundleAsiPOJO(new File(ROOT, "requiresnew.jar"), new File(TEST, "requiresnew.xml"))  ).toExternalForm();
+    
+        
+        Option[] opt =  options(
+ 
+                provision(
+                        mavenBundle().groupId("org.ops4j.pax.logging").artifactId("pax-logging-api").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo.transaction").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.transaction").version(asInProject()),
+                        mavenBundle()
+                        .groupId( "org.ops4j.pax.tinybundles" )
+                        .artifactId( "pax-tinybundles-core" )
+                        .version( "0.5.0-SNAPSHOT" ),
+                        bundle(service.toExternalForm()),
+                        bundle(fooimpl),
+                        bundle(test)
+                    )
+                )
+
+                ;
+        return opt;
+    }
+    
+    
+    @Test
+    public void testOkOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requiresnew-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingGood(); // Ok
+    }
+    
+    @Test
+    public void testOkInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requiresnew-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        cs.doSomethingGood();
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertNotSame(t2, t); // Two different transactions
+        // Check that t2 is commited => no transaction
+        Assert.assertEquals(Status.STATUS_NO_TRANSACTION, t2.getStatus());
+        t.commit();
+    }
+    
+    @Test
+    public void testExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requiresnew-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        try {
+            ((CheckService) osgi.getServiceObject(ref)).doSomethingBad(); // throws an exception on rollback
+            Assert.fail("Exception expected on rollback");
+        } catch (IllegalStateException e) {
+            // Ok.
+        } catch (Exception  e) {
+            Assert.fail("IllegalStateException expected on rollback");
+        }
+    }
+    
+    @Test
+    public void testExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requiresnew-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("IllegalStateException expected");  // throws an exception on rollback
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof IllegalStateException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertNotSame(t2, t);
+        // Check that t2 is rolledback
+        Assert.assertEquals(Status.STATUS_NO_TRANSACTION, t2.getStatus());
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.commit();
+    }
+    
+    @Test(expected=UnsupportedOperationException.class)
+    public void testExpectedExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requiresnew-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad2();
+    }
+    
+    @Test
+    public void testExpectedExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("requiresnew-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad2();
+            Assert.fail("UnsupportedOperationException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof UnsupportedOperationException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertNotSame(t2, t);
+        Assert.assertEquals(Status.STATUS_NO_TRANSACTION, t2.getStatus());
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.commit();
+    }
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestSupported.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestSupported.java
new file mode 100644
index 0000000..962ab17
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/TestSupported.java
@@ -0,0 +1,442 @@
+package org.apache.felix.ipojo.transaction.test;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.MavenUtils.asInProject;
+import static org.ops4j.pax.tinybundles.core.TinyBundles.with;
+
+import java.io.File;
+import java.net.URL;
+
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.apache.felix.ipojo.ComponentInstance;
+import org.apache.felix.ipojo.pax.exam.target.BundleAsiPOJO;
+import org.apache.felix.ipojo.transaction.test.component.FooDelegator;
+import org.apache.felix.ipojo.transaction.test.component.FooImpl;
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Inject;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.Configuration;
+import org.ops4j.pax.exam.junit.JUnit4TestRunner;
+import org.ops4j.pax.tinybundles.core.TinyBundles;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+
+@RunWith( JUnit4TestRunner.class )
+public class TestSupported {
+    
+    @Inject
+    private BundleContext context;
+    
+    private OSGiHelper osgi;
+    
+    private IPOJOHelper ipojo;
+    public static final File ROOT = new File("target/tmp");
+    public static final File TEST = new File("src/test/resources");
+
+    
+    @Before
+    public void init() {
+        osgi = new OSGiHelper(context);
+        ipojo = new IPOJOHelper(context);
+    }
+    
+    @After
+    public void stop() {
+        ipojo.dispose();
+        osgi.dispose();
+    }
+    
+    @Configuration
+    public static Option[] configure() {    
+        ROOT.mkdirs();
+
+        URL service = TinyBundles.newBundle()
+            .addClass(CheckService.class)
+            .addClass(Foo.class)
+           .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Service")
+                .set(Constants.EXPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                .set(Constants.IMPORT_PACKAGE, "javax.transaction")
+                )
+            .build( TinyBundles.asURL());
+            
+        String fooimpl = TinyBundles.newBundle()
+            .addClass(FooImpl.class)
+            .prepare( 
+                    with()
+                    .set(Constants.BUNDLE_SYMBOLICNAME,"Foo Provider")
+                    .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service")
+                )
+                .build( new BundleAsiPOJO(new File(ROOT, "FooImpl.jar"), new File(TEST, "foo.xml"))  ).toExternalForm();
+        
+        String test = TinyBundles.newBundle()
+        .addClass(FooDelegator.class)
+        .prepare( 
+                with()
+                .set(Constants.BUNDLE_SYMBOLICNAME,"Required Transaction Propgatation")
+                .set(Constants.IMPORT_PACKAGE, "org.apache.felix.ipojo.transaction.test.service, javax.transaction")
+            )
+            .build( new BundleAsiPOJO(new File(ROOT, "supported.jar"), new File(TEST, "supported.xml"))  ).toExternalForm();
+    
+        
+        Option[] opt =  options(
+ 
+                provision(
+                        mavenBundle().groupId("org.ops4j.pax.logging").artifactId("pax-logging-api").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.ipojo.transaction").version(asInProject()),
+                        mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.transaction").version(asInProject()),
+                        mavenBundle()
+                        .groupId( "org.ops4j.pax.tinybundles" )
+                        .artifactId( "pax-tinybundles-core" )
+                        .version( "0.5.0-SNAPSHOT" ),
+                        bundle(service.toExternalForm()),
+                        bundle(fooimpl),
+                        bundle(test)
+                    )
+                )
+
+                ;
+        return opt;
+    }
+    
+    
+    @Test
+    public void testOkOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = ((CheckService) osgi.getServiceObject(ref));
+        cs.doSomethingGood();
+        // No transaction.
+    }
+    
+    @Test
+    public void testOkInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        cs.doSomethingGood();
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        t.commit();
+    }
+    
+    @Test(expected=NullPointerException.class)
+    public void testExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad();
+    }
+    
+    @Test(expected=RollbackException.class)
+    public void testExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+        
+        t.commit(); // Throw a rollback exception.
+    }
+    
+    @Test
+    public void testExceptionInsideTransactionRB() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+        
+        t.rollback();
+    }
+    
+    @Test(expected=UnsupportedOperationException.class)
+    public void testExpectedExceptionOutsideTransaction() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        ((CheckService) osgi.getServiceObject(ref)).doSomethingBad2();
+    }
+    
+    @Test
+    public void testExpectedExceptionInsideTransaction() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-ok");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad2();
+            Assert.fail("UnsupportedOperationException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof UnsupportedOperationException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.commit();
+    }
+    
+    @Test
+    public void testOkOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingGood();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+    @Test
+    public void testOkInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        cs.doSomethingGood();
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        t.commit();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNotNull(cs.getLastCommitted());
+        Assert.assertEquals(1, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+        
+        Assert.assertSame(t, cs.getLastCommitted());
+    }
+    
+    @Test(expected=NullPointerException.class)
+    public void testExceptionOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingBad();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+    @Test
+    public void testExceptionInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad();
+            Assert.fail("NullPointerException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof NullPointerException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_MARKED_ROLLBACK, t.getStatus());
+        
+        try {
+            t.commit(); // Throw a rollback exception.
+        } catch (RollbackException e) {
+            // Expected
+        } catch (Throwable e) {
+            Assert.fail(e.getMessage()); // Unexpected
+        }
+        
+        Assert.assertNotNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(1, cs.getNumberOfRollback());
+        
+        Assert.assertSame(t, cs.getLastRolledBack());
+    }
+    
+    @Test(expected=UnsupportedOperationException.class)
+    public void testExpectedExceptionOutsideTransactionWithCallback() {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+
+        cs.doSomethingBad2();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNull(cs.getLastCommitted());
+        Assert.assertEquals(0, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+    }
+    
+    @Test
+    public void testExpectedExceptionInsideTransactionWithCallback() throws NotSupportedException, SystemException, SecurityException, HeuristicMixedException, HeuristicRollbackException, RollbackException {
+        ComponentInstance prov = ipojo.createComponentInstance("org.apache.felix.ipojo.transaction.test.component.FooImpl");
+        ComponentInstance under = ipojo.createComponentInstance("supported-cb");
+        
+        Assert.assertEquals(ComponentInstance.VALID, prov.getState());
+        Assert.assertEquals(ComponentInstance.VALID, under.getState());
+        
+        ServiceReference ref = ipojo.getServiceReferenceByName(CheckService.class.getName(), under.getInstanceName());
+        Assert.assertNotNull(ref);
+        
+        CheckService cs = (CheckService) osgi.getServiceObject(ref);
+        TransactionManager tm = (TransactionManager) osgi.getServiceObject(TransactionManager.class.getName(), null);
+        tm.begin();
+        Transaction t = tm.getTransaction();
+        try {
+            cs.doSomethingBad2();
+            Assert.fail("UnsupportedOperationException expected");
+        } catch(Exception e) {
+            Assert.assertTrue(e instanceof UnsupportedOperationException);
+        }
+        Transaction t2 = cs.getCurrentTransaction();
+        Assert.assertSame(t2, t);
+        Assert.assertEquals(Status.STATUS_ACTIVE, t.getStatus());
+        
+        t.commit();
+        
+        Assert.assertNull(cs.getLastRolledBack());
+        Assert.assertNotNull(cs.getLastCommitted());
+        Assert.assertEquals(1, cs.getNumberOfCommit());
+        Assert.assertEquals(0, cs.getNumberOfRollback());
+        
+        Assert.assertSame(t, cs.getLastCommitted());
+    }
+    
+
+    
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooDelegator.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooDelegator.java
new file mode 100644
index 0000000..7f8665b
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooDelegator.java
@@ -0,0 +1,85 @@
+package org.apache.felix.ipojo.transaction.test.component;
+
+import javax.transaction.Transaction;
+
+import org.apache.felix.ipojo.transaction.test.service.CheckService;
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+
+public class FooDelegator implements CheckService {
+    
+    private Foo foo;
+    
+    private int commit;
+    
+    private int rollback;
+    
+    Transaction transaction;
+    
+    Transaction lastCommitted;
+    
+    Transaction lastRolledback;
+    
+    Transaction current;
+
+    
+    public void onCommit(String method) {
+        commit ++;
+    }
+    
+    public void onRollback(String method, Exception e) {
+        rollback ++;
+    }
+
+    public void doSomethingBad() throws NullPointerException {
+        current = transaction;
+        foo.doSomethingBad();
+    }
+
+    public void doSomethingBad2() throws UnsupportedOperationException {
+       current = transaction;
+       foo.doSomethingBad2();
+
+    }
+
+    public void doSomethingGood() {
+        current = transaction;
+        foo.doSomethingGood();
+    }
+
+    public void doSomethingLong() {
+       current = transaction;
+       foo.doSomethingLong();
+    }
+
+    public Transaction getCurrentTransaction() {
+       return current;
+    }
+
+    public int getNumberOfCommit() {
+       return commit;
+    }
+
+    public int getNumberOfRollback() {
+       return rollback;
+    }
+    
+    public Transaction getLastRolledBack() {
+        return lastRolledback;
+    }
+    
+    public Transaction getLastCommitted() {
+        return lastCommitted;
+    }
+    
+    public void onRollback(Transaction t) {
+        lastRolledback = t;
+        rollback ++;
+    }
+    
+
+    public void onCommit(Transaction t) {
+        lastCommitted = t;
+        commit ++;
+    }
+
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooImpl.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooImpl.java
new file mode 100644
index 0000000..addb9f3
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/component/FooImpl.java
@@ -0,0 +1,28 @@
+package org.apache.felix.ipojo.transaction.test.component;
+
+import org.apache.felix.ipojo.transaction.test.service.Foo;
+
+public class FooImpl implements Foo {
+
+    public void doSomethingBad() throws NullPointerException {
+       throw new NullPointerException("NULL");
+    }
+
+    public void doSomethingBad2() throws UnsupportedOperationException {
+        throw new UnsupportedOperationException("Expected exception");
+
+    }
+
+    public void doSomethingGood() {
+       // Good...
+    }
+
+    public void doSomethingLong() {
+        try {
+            Thread.sleep(5000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/service/CheckService.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/service/CheckService.java
new file mode 100644
index 0000000..bb95994
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/service/CheckService.java
@@ -0,0 +1,25 @@
+package org.apache.felix.ipojo.transaction.test.service;
+
+import javax.transaction.Transaction;
+
+public interface CheckService {
+    
+    public void doSomethingGood();
+    
+    public void doSomethingBad() throws NullPointerException;
+    
+    public void doSomethingBad2() throws UnsupportedOperationException;
+    
+    public void doSomethingLong();
+    
+    public int getNumberOfCommit();
+    
+    public int getNumberOfRollback();
+    
+    public Transaction getCurrentTransaction();
+    
+    public Transaction getLastRolledBack();
+    
+    public Transaction getLastCommitted();
+
+}
diff --git a/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/service/Foo.java b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/service/Foo.java
new file mode 100644
index 0000000..b1ba75a
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/java/org/apache/felix/ipojo/transaction/test/service/Foo.java
@@ -0,0 +1,13 @@
+package org.apache.felix.ipojo.transaction.test.service;
+
+public interface Foo {
+    
+    public void doSomethingGood();
+    
+    public void doSomethingBad() throws NullPointerException;
+    
+    public void doSomethingBad2() throws UnsupportedOperationException;
+    
+    public void doSomethingLong();
+
+}
diff --git a/ipojo/tests/handler/transaction/src/test/resources/foo.xml b/ipojo/tests/handler/transaction/src/test/resources/foo.xml
new file mode 100644
index 0000000..19f1ed8
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/resources/foo.xml
@@ -0,0 +1,5 @@
+<ipojo>
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooImpl">
+		<provides/>
+	</component>
+</ipojo>
\ No newline at end of file
diff --git a/ipojo/tests/handler/transaction/src/test/resources/mandatory.xml b/ipojo/tests/handler/transaction/src/test/resources/mandatory.xml
new file mode 100644
index 0000000..bb977ba
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/resources/mandatory.xml
@@ -0,0 +1,25 @@
+<ipojo xmlns:tr="org.apache.felix.ipojo.transaction">
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="mandatory-ok">
+		<provides/>
+		<requires field="foo"/>
+		<tr:transaction field="transaction">
+			<transactionnal method="doSomethingGood" propagation="mandatory"/>
+			<transactionnal method="getCurrentTransaction" propagation="mandatory"/>
+			<transactionnal method="doSomethingBad" propagation="mandatory"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="mandatory"/>
+			<transactionnal method="doSomethingLong" propagation="mandatory"/>
+		</tr:transaction>
+	</component>
+	
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="mandatory-cb">
+		<provides/>
+		<requires field="foo" />
+		<tr:transaction field="transaction" onCommit="onCommit" onRollback="onRollback">
+			<transactionnal method="doSomethingGood" propagation="mandatory"/>
+			<transactionnal method="getCurrentTransaction" propagation="mandatory"/>
+			<transactionnal method="doSomethingBad" propagation="mandatory"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="mandatory"/>
+			<transactionnal method="doSomethingLong" propagation="mandatory"/>
+		</tr:transaction>
+	</component>
+</ipojo>
\ No newline at end of file
diff --git a/ipojo/tests/handler/transaction/src/test/resources/never.xml b/ipojo/tests/handler/transaction/src/test/resources/never.xml
new file mode 100644
index 0000000..0a58abc
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/resources/never.xml
@@ -0,0 +1,25 @@
+<ipojo xmlns:tr="org.apache.felix.ipojo.transaction">
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="never-ok">
+		<provides/>
+		<requires field="foo"/>
+		<tr:transaction field="transaction">
+			<transactionnal method="doSomethingGood" propagation="never"/>
+			<transactionnal method="getCurrentTransaction" propagation="never"/>
+			<transactionnal method="doSomethingBad" propagation="never"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="never"/>
+			<transactionnal method="doSomethingLong" propagation="never"/>
+		</tr:transaction>
+	</component>
+	
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="never-cb">
+		<provides/>
+		<requires field="foo" />
+		<tr:transaction field="transaction" onCommit="onCommit" onRollback="onRollback">
+			<transactionnal method="doSomethingGood" propagation="never"/>
+			<transactionnal method="getCurrentTransaction" propagation="never"/>
+			<transactionnal method="doSomethingBad" propagation="never"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="never"/>
+			<transactionnal method="doSomethingLong" propagation="never"/>
+		</tr:transaction>
+	</component>
+</ipojo>
\ No newline at end of file
diff --git a/ipojo/tests/handler/transaction/src/test/resources/notsupported.xml b/ipojo/tests/handler/transaction/src/test/resources/notsupported.xml
new file mode 100644
index 0000000..fb44c93
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/resources/notsupported.xml
@@ -0,0 +1,25 @@
+<ipojo xmlns:tr="org.apache.felix.ipojo.transaction">
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="notsupported-ok">
+		<provides/>
+		<requires field="foo"/>
+		<tr:transaction field="transaction">
+			<transactionnal method="doSomethingGood" propagation="notsupported"/>
+			<transactionnal method="getCurrentTransaction" propagation="notsupported"/>
+			<transactionnal method="doSomethingBad" propagation="notsupported"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="notsupported"/>
+			<transactionnal method="doSomethingLong" propagation="notsupported"/>
+		</tr:transaction>
+	</component>
+	
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="notsupported-cb">
+		<provides/>
+		<requires field="foo" />
+		<tr:transaction field="transaction" onCommit="onCommit" onRollback="onRollback">
+			<transactionnal method="doSomethingGood" propagation="notsupported"/>
+			<transactionnal method="getCurrentTransaction" propagation="notsupported"/>
+			<transactionnal method="doSomethingBad" propagation="notsupported"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="notsupported"/>
+			<transactionnal method="doSomethingLong" propagation="notsupported"/>
+		</tr:transaction>
+	</component>
+</ipojo>
\ No newline at end of file
diff --git a/ipojo/tests/handler/transaction/src/test/resources/requires.xml b/ipojo/tests/handler/transaction/src/test/resources/requires.xml
new file mode 100644
index 0000000..ccd3221
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/resources/requires.xml
@@ -0,0 +1,25 @@
+<ipojo xmlns:tr="org.apache.felix.ipojo.transaction">
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="requires-ok">
+		<provides/>
+		<requires field="foo"/>
+		<tr:transaction field="transaction">
+			<transactionnal method="doSomethingGood"/>
+			<transactionnal method="getCurrentTransaction"/>
+			<transactionnal method="doSomethingBad"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException"/>
+			<transactionnal method="doSomethingLong"/>
+		</tr:transaction>
+	</component>
+	
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="requires-cb">
+		<provides/>
+		<requires field="foo" />
+		<tr:transaction field="transaction" onCommit="onCommit" onRollback="onRollback">
+			<transactionnal method="doSomethingGood"/>
+			<transactionnal method="getCurrentTransaction"/>
+			<transactionnal method="doSomethingBad"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException"/>
+			<transactionnal method="doSomethingLong"/>
+		</tr:transaction>
+	</component>
+</ipojo>
\ No newline at end of file
diff --git a/ipojo/tests/handler/transaction/src/test/resources/requiresnew.xml b/ipojo/tests/handler/transaction/src/test/resources/requiresnew.xml
new file mode 100644
index 0000000..d91aa58
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/resources/requiresnew.xml
@@ -0,0 +1,25 @@
+<ipojo xmlns:tr="org.apache.felix.ipojo.transaction">
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="requiresnew-ok">
+		<provides/>
+		<requires field="foo"/>
+		<tr:transaction field="transaction">
+			<transactionnal method="doSomethingGood" propagation="requiresnew"/>
+			<transactionnal method="getCurrentTransaction" propagation="requiresnew"/>
+			<transactionnal method="doSomethingBad" propagation="requiresnew" exceptiononrollback="true"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="requiresnew"/>
+			<transactionnal method="doSomethingLong" propagation="requiresnew"/>
+		</tr:transaction>
+	</component>
+	
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="requiresnew-cb">
+		<provides/>
+		<requires field="foo" />
+		<tr:transaction field="transaction" onCommit="onCommit" onRollback="onRollback">
+			<transactionnal method="doSomethingGood" propagation="requiresnew"/>
+			<transactionnal method="getCurrentTransaction" propagation="requiresnew"/>
+			<transactionnal method="doSomethingBad" propagation="requiresnew"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="requiresnew"/>
+			<transactionnal method="doSomethingLong" propagation="requiresnew"/>
+		</tr:transaction>
+	</component>
+</ipojo>
\ No newline at end of file
diff --git a/ipojo/tests/handler/transaction/src/test/resources/supported.xml b/ipojo/tests/handler/transaction/src/test/resources/supported.xml
new file mode 100644
index 0000000..d4fc6b5
--- /dev/null
+++ b/ipojo/tests/handler/transaction/src/test/resources/supported.xml
@@ -0,0 +1,25 @@
+<ipojo xmlns:tr="org.apache.felix.ipojo.transaction">
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="supported-ok">
+		<provides/>
+		<requires field="foo"/>
+		<tr:transaction field="transaction">
+			<transactionnal method="doSomethingGood" propagation="supported"/>
+			<transactionnal method="getCurrentTransaction" propagation="supported"/>
+			<transactionnal method="doSomethingBad" propagation="supported"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="supported"/>
+			<transactionnal method="doSomethingLong" propagation="supported"/>
+		</tr:transaction>
+	</component>
+	
+	<component classname="org.apache.felix.ipojo.transaction.test.component.FooDelegator" name="supported-cb">
+		<provides/>
+		<requires field="foo" />
+		<tr:transaction field="transaction" onCommit="onCommit" onRollback="onRollback">
+			<transactionnal method="doSomethingGood" propagation="supported"/>
+			<transactionnal method="getCurrentTransaction" propagation="supported"/>
+			<transactionnal method="doSomethingBad" propagation="supported"/>
+			<transactionnal method="doSomethingBad2" norollbackfor="java.lang.UnsupportedOperationException" propagation="supported"/>
+			<transactionnal method="doSomethingLong" propagation="supported"/>
+		</tr:transaction>
+	</component>
+</ipojo>
\ No newline at end of file