Fixed FELIX-3078 and FELIX-3079

The new manipulation process is now easily embeddable and the process can be extended.

Thanks to Guillaume Sauthier for this hard work.


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1159173 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/PojoizationTest.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/PojoizationTest.java
index 68d4b5e..387dfca 100644
--- a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/PojoizationTest.java
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulation/PojoizationTest.java
@@ -11,6 +11,7 @@
 
 	public void testJarManipulation() {
 		Pojoization pojoization = new Pojoization();
+        pojoization.setUseLocalXSD();
 		File in = new File("target/test-classes/tests.manipulation-no-annotations.jar");
 		File out = new File("target/test-classes/tests.manipulation-no-annotations-manipulated.jar");
 		out.delete();
@@ -22,6 +23,7 @@
 
 	public void testManipulationWithAnnotations() {
 		Pojoization pojoization = new Pojoization();
+        pojoization.setUseLocalXSD();
 		File in = new File("target/test-classes/tests.manipulator-annotations.jar");
 		File out = new File("target/test-classes/tests.manipulation-annotations-manipulated.jar");
 		out.delete();
@@ -32,6 +34,7 @@
 
 	public void testJarManipulationJava5() {
 		Pojoization pojoization = new Pojoization();
+        pojoization.setUseLocalXSD();
 		File in = new File("target/test-classes/tests.manipulation.java5.jar");
 		File out = new File("target/test-classes/tests.manipulation.java5-manipulated.jar");
 		out.delete();
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/ManipulationEngineTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/ManipulationEngineTestCase.java
new file mode 100644
index 0000000..b282b11
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/ManipulationEngineTestCase.java
@@ -0,0 +1,112 @@
+/*
+ * 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.manipulator;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.util.Streams;
+import org.apache.felix.ipojo.manipulator.util.Strings;
+import org.apache.felix.ipojo.metadata.Element;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import test.ClusterDaemon;
+import test.PojoWithInner;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ManipulationEngineTestCase extends TestCase {
+
+    @Mock
+    private Reporter reporter;
+
+    @Mock
+    private ResourceStore store;
+
+    @Mock
+    private ManipulationVisitor visitor;
+
+    @Mock
+    private ManipulationResultVisitor result;
+
+    @InjectMocks
+    private ManipulationEngine engine = new ManipulationEngine();
+
+
+    @Override
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    public void testManipulationOfSimpleClass() throws Exception {
+
+        when(store.read(anyString())).thenReturn(from(ClusterDaemon.class));
+        when(visitor.visitManipulationResult(any(Element.class))).thenReturn(result);
+
+        String path = Strings.asResourcePath(ClusterDaemon.class.getName());
+        Element metadata = new Element("", "");
+        ManipulationUnit info = new ManipulationUnit(path, metadata);
+        engine.addManipulationUnit(info);
+
+        engine.generate();
+
+        verify(visitor).visitManipulationResult(eq(metadata));
+        verify(result).visitClassStructure(any(Element.class));
+        verify(result).visitManipulatedResource(eq(path), any(byte[].class));
+        verify(result).visitEnd();
+
+    }
+
+    public void testManipulationOfInnerClass() throws Exception {
+
+        when(visitor.visitManipulationResult(any(Element.class))).thenReturn(result);
+
+        String innerPath = Strings.asResourcePath(PojoWithInner.MyInner.class.getName());
+        when(store.read(innerPath)).thenReturn(from(PojoWithInner.MyInner.class));
+
+        String path = Strings.asResourcePath(PojoWithInner.class.getName());
+        when(store.read(path)).thenReturn(from(PojoWithInner.class));
+
+        Element metadata = new Element("", "");
+        ManipulationUnit info = new ManipulationUnit(path, metadata);
+        engine.addManipulationUnit(info);
+
+        engine.generate();
+
+        verify(visitor).visitManipulationResult(eq(metadata));
+        verify(result).visitClassStructure(any(Element.class));
+        verify(result).visitManipulatedResource(eq(path), any(byte[].class));
+        verify(result).visitManipulatedResource(eq(innerPath), any(byte[].class));
+        verify(result).visitEnd();
+
+    }
+
+    private byte[] from(Class<?> type) throws IOException {
+        ClassLoader loader = type.getClassLoader();
+        InputStream is = loader.getResourceAsStream(Strings.asResourcePath(type.getName()));
+        return Streams.readBytes(is);
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/manifest/DirectManifestProviderTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/manifest/DirectManifestProviderTestCase.java
new file mode 100644
index 0000000..46cf8ae
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/manifest/DirectManifestProviderTestCase.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.manipulator.manifest;
+
+import junit.framework.TestCase;
+
+import java.util.jar.Manifest;
+
+public class DirectManifestProviderTestCase extends TestCase {
+    public void testGetManifest() throws Exception {
+        Manifest origin = new Manifest();
+        DirectManifestProvider provider = new DirectManifestProvider(origin);
+
+        assertSame(origin, provider.getManifest());
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/manifest/FileManifestProviderTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/manifest/FileManifestProviderTestCase.java
new file mode 100644
index 0000000..dc8abcc
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/manifest/FileManifestProviderTestCase.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.manipulator.manifest;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.util.jar.Manifest;
+
+public class FileManifestProviderTestCase extends TestCase {
+    public void testGetManifest() throws Exception {
+        File manifestFile = new File(new File("target", "test-classes"), "MANIFEST.MF");
+        FileManifestProvider provider = new FileManifestProvider(manifestFile);
+
+        Manifest manifest = provider.getManifest();
+
+        assertNotNull(manifest);
+        assertEquals("tests.manipulation.java5", manifest.getMainAttributes().getValue("Bundle-SymbolicName"));
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProviderTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProviderTestCase.java
new file mode 100644
index 0000000..3d9e287
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/AnnotationMetadataProviderTestCase.java
@@ -0,0 +1,87 @@
+/**
+ * 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.manipulator.metadata;
+
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.ResourceStore;
+import org.apache.felix.ipojo.manipulator.ResourceVisitor;
+import org.apache.felix.ipojo.manipulator.util.Streams;
+import org.apache.felix.ipojo.manipulator.util.Strings;
+import org.apache.felix.ipojo.metadata.Element;
+import test.AnnotatedComponent;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.mockito.Mockito.mock;
+
+public class AnnotationMetadataProviderTestCase extends TestCase {
+    public void testGetMetadatas() throws Exception {
+        MiniStore store = new MiniStore(AnnotatedComponent.class);
+        Reporter reporter = mock(Reporter.class);
+        AnnotationMetadataProvider provider = new AnnotationMetadataProvider(store, reporter);
+
+        List<Element> meta = provider.getMetadatas();
+        assertEquals(1, meta.size());
+
+
+    }
+
+    private class MiniStore implements ResourceStore {
+
+        private Map<String, byte[]> resources;
+
+        public MiniStore(Class<?>... classes) throws IOException {
+            this.resources = new HashMap<String, byte[]>();
+            for (Class<?> type : classes) {
+                resources.put(Strings.asResourcePath(type.getName()), from(type));
+            }
+        }
+
+        public byte[] read(String path) throws IOException {
+            return resources.get(path);
+        }
+
+        public void accept(ResourceVisitor visitor) {
+            for (Map.Entry<String, byte[]> entry : resources.entrySet()) {
+                visitor.visit(entry.getKey());
+            }
+        }
+
+        public void open() throws IOException {}
+
+        public void writeMetadata(Element metadata) {}
+
+        public void write(String resourcePath, byte[] resource) throws IOException {}
+
+        public void close() throws IOException {}
+    }
+
+    private byte[] from(Class<?> type) throws IOException {
+        ClassLoader loader = type.getClassLoader();
+        InputStream is = loader.getResourceAsStream(Strings.asResourcePath(type.getName()));
+        return Streams.readBytes(is);
+    }
+
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/CacheableMetadataProviderTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/CacheableMetadataProviderTestCase.java
new file mode 100644
index 0000000..5c29fb9
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/CacheableMetadataProviderTestCase.java
@@ -0,0 +1,46 @@
+/**
+ * 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.manipulator.metadata;
+
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.MetadataProvider;
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.util.Collections;
+
+import static org.mockito.Mockito.*;
+
+public class CacheableMetadataProviderTestCase extends TestCase {
+    public void testGetMetadatas() throws Exception {
+        MetadataProvider delegate = mock(MetadataProvider.class);
+        CacheableMetadataProvider provider = new CacheableMetadataProvider(delegate);
+
+        Element returned = new Element("test", null);
+        when(delegate.getMetadatas()).thenReturn(Collections.singletonList(returned));
+
+        provider.getMetadatas();
+        provider.getMetadatas();
+        provider.getMetadatas();
+        provider.getMetadatas();
+
+        verify(delegate, atMost(1)).getMetadatas();
+
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/CompositeMetadataProviderTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/CompositeMetadataProviderTestCase.java
new file mode 100644
index 0000000..bdd8338
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/CompositeMetadataProviderTestCase.java
@@ -0,0 +1,112 @@
+/**
+ * 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.manipulator.metadata;
+
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.MetadataProvider;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.mockito.Mockito.*;
+
+public class CompositeMetadataProviderTestCase extends TestCase {
+
+    @Mock
+    private MetadataProvider delegate1;
+
+    @Mock
+    private MetadataProvider delegate2;
+
+    @Mock
+    private Reporter reporter;
+
+
+    @Override
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    public void testGetMetadatas() throws Exception {
+        CompositeMetadataProvider provider = new CompositeMetadataProvider(reporter);
+        provider.addMetadataProvider(delegate1);
+        provider.addMetadataProvider(delegate2);
+
+        Element returned = newComponentElement("type1");
+        when(delegate1.getMetadatas()).thenReturn(Collections.singletonList(returned));
+
+        Element returned2 = newComponentElement("type2");
+        when(delegate2.getMetadatas()).thenReturn(Collections.singletonList(returned2));
+
+        List<Element> meta = provider.getMetadatas();
+        assertEquals(2, meta.size());
+    }
+
+    public void testGetMetadatasWithDuplicate() throws Exception {
+        CompositeMetadataProvider provider = new CompositeMetadataProvider(reporter);
+        provider.addMetadataProvider(delegate1);
+        provider.addMetadataProvider(delegate2);
+
+        Element returned = newComponentElement("type1");
+        when(delegate1.getMetadatas()).thenReturn(Collections.singletonList(returned));
+
+        Element returned2 = newComponentElement("type1");
+        when(delegate2.getMetadatas()).thenReturn(Collections.singletonList(returned2));
+
+        List<Element> meta = provider.getMetadatas();
+        assertEquals(1, meta.size());
+
+        verify(reporter).warn(anyString());
+    }
+
+    public void testGetMetadatasWithInstances() throws Exception {
+        CompositeMetadataProvider provider = new CompositeMetadataProvider(reporter);
+        provider.addMetadataProvider(delegate1);
+        provider.addMetadataProvider(delegate2);
+
+        Element returned = newInstanceElement("type1", "name1");
+        when(delegate1.getMetadatas()).thenReturn(Collections.singletonList(returned));
+
+        // Try with a duplicate instance name
+        Element returned2 = newInstanceElement("type1", "name2");
+        when(delegate2.getMetadatas()).thenReturn(Collections.singletonList(returned2));
+
+        List<Element> meta = provider.getMetadatas();
+        assertEquals(2, meta.size());
+    }
+
+    private Element newComponentElement(String type) {
+        Element main = new Element("component", null);
+        main.addAttribute(new Attribute("name", type));
+        return main;
+    }
+
+    private Element newInstanceElement(String type, String name) {
+        Element main = new Element("instance", null);
+        main.addAttribute(new Attribute("component", type));
+        main.addAttribute(new Attribute("name", name));
+        return main;
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/EmptyMetadataProviderTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/EmptyMetadataProviderTestCase.java
new file mode 100644
index 0000000..2698a67
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/EmptyMetadataProviderTestCase.java
@@ -0,0 +1,29 @@
+/**
+ * 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.manipulator.metadata;
+
+import junit.framework.TestCase;
+
+public class EmptyMetadataProviderTestCase extends TestCase {
+    public void testGetMetadatas() throws Exception {
+        EmptyMetadataProvider provider = new EmptyMetadataProvider();
+        assertTrue(provider.getMetadatas().isEmpty());
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/FileMetadataProviderTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/FileMetadataProviderTestCase.java
new file mode 100644
index 0000000..db851c8
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/FileMetadataProviderTestCase.java
@@ -0,0 +1,51 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.manipulator.metadata;
+
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.io.File;
+import java.util.List;
+
+import static org.mockito.Mockito.mock;
+
+public class FileMetadataProviderTestCase extends TestCase {
+    public void testGetMetadatasFromFile() throws Exception {
+        File metadata = new File(new File("target", "test-classes"), "metadata.xml");
+        Reporter reporter = mock(Reporter.class);
+        FileMetadataProvider provider = new FileMetadataProvider(metadata, reporter);
+        provider.setValidateUsingLocalSchemas(true);
+
+        List<Element> meta = provider.getMetadatas();
+        assertEquals(3, meta.size());
+    }
+
+    public void testGetMetadatasFromDirectory() throws Exception {
+        File metadata = new File("target", "test-classes");
+        Reporter reporter = mock(Reporter.class);
+        FileMetadataProvider provider = new FileMetadataProvider(metadata, reporter);
+        provider.setValidateUsingLocalSchemas(true);
+
+        List<Element> meta = provider.getMetadatas();
+        assertEquals(3, meta.size());
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/StreamMetadataProviderTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/StreamMetadataProviderTestCase.java
new file mode 100644
index 0000000..9fa4f45
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/metadata/StreamMetadataProviderTestCase.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.manipulator.metadata;
+
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.metadata.Element;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.List;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class StreamMetadataProviderTestCase extends TestCase {
+
+    public void testGetMetadatas() throws Exception {
+        File metadata = new File(new File("target", "test-classes"), "metadata.xml");
+        FileInputStream fis = new FileInputStream(metadata);
+        Reporter reporter = mock(Reporter.class);
+
+        StreamMetadataProvider provider = new StreamMetadataProvider(fis, reporter);
+        provider.setValidateUsingLocalSchemas(true);
+
+        List<Element> meta = provider.getMetadatas();
+        assertEquals(3, meta.size());
+    }
+
+    public void testWithEmptyMetadataXml() throws Exception {
+        File metadata = new File(new File("target", "test-classes"), "empty-metadata.xml");
+        FileInputStream fis = new FileInputStream(metadata);
+        Reporter reporter = mock(Reporter.class);
+
+        StreamMetadataProvider provider = new StreamMetadataProvider(fis, reporter);
+        provider.setValidateUsingLocalSchemas(true);
+
+        List<Element> meta = provider.getMetadatas();
+        assertEquals(0, meta.size());
+        verify(reporter).warn(anyString());
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/render/ManipulatedMetadataFilterTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/render/ManipulatedMetadataFilterTestCase.java
new file mode 100644
index 0000000..7f8bbf6
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/render/ManipulatedMetadataFilterTestCase.java
@@ -0,0 +1,65 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.manipulator.render;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.InstanceManager;
+import org.apache.felix.ipojo.manipulation.MethodCreator;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+public class ManipulatedMetadataFilterTestCase extends TestCase {
+
+    private ManipulatedMetadataFilter filter;
+
+    @Override
+    public void setUp() throws Exception {
+        filter = new ManipulatedMetadataFilter();
+    }
+
+    public void testFilterPrefixedMethod() throws Exception {
+        Element main = new Element("test", null);
+        main.addAttribute(new Attribute("name", MethodCreator.PREFIX + "PropertyName"));
+
+        Assert.assertTrue(filter.accept(main));
+    }
+
+    public void testFilterInstanceManagerValue() throws Exception {
+        Element main = new Element("test", null);
+        main.addAttribute(new Attribute("name", InstanceManager.class.getName()));
+
+        Assert.assertTrue(filter.accept(main));
+    }
+
+    public void testFilterInstanceManagerSetter() throws Exception {
+        Element main = new Element("test", null);
+        main.addAttribute(new Attribute("name", "_setInstanceManager"));
+
+        Assert.assertTrue(filter.accept(main));
+    }
+
+    public void testDoNotFilterOthers() throws Exception {
+        Element main = new Element("test", null);
+        main.addAttribute(new Attribute("name", "setPropertyName"));
+
+        Assert.assertFalse(filter.accept(main));
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/render/MetadataRendererTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/render/MetadataRendererTestCase.java
new file mode 100644
index 0000000..a9b0e2c
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/render/MetadataRendererTestCase.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.manipulator.render;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+
+public class MetadataRendererTestCase extends TestCase {
+
+    private MetadataRenderer renderer;
+
+    @Override
+    public void setUp() throws Exception {
+        renderer = new MetadataRenderer();
+    }
+
+    public void testAddMetadataFilter() throws Exception {
+
+        // Auto remove all elements with a namespace
+        renderer.addMetadataFilter(new MetadataFilter() {
+            public boolean accept(Element element) {
+                return element.getNameSpace() != null;
+            }
+        });
+
+        Element main = new Element("test", null);
+        Element child = new Element("child", "uri");
+        main.addElement(child);
+        String rendered = renderer.render(main);
+        Assert.assertEquals("test { }", rendered);
+
+    }
+
+    public void testRenderElementWithNoNamespace() throws Exception {
+        Element main = new Element("test", null);
+        String rendered = renderer.render(main);
+        Assert.assertEquals("test { }", rendered);
+    }
+
+    public void testRenderElementWithEmptyNamespace() throws Exception {
+        Element main = new Element("test", "");
+        String rendered = renderer.render(main);
+        Assert.assertEquals("test { }", rendered);
+    }
+
+    public void testRenderElementWithDefaultNamespace() throws Exception {
+        // TODO Do we need to strip off default namespace ?
+        Element main = new Element("test", "org.apache.felix.ipojo");
+        String rendered = renderer.render(main);
+        Assert.assertEquals("org.apache.felix.ipojo:test { }", rendered);
+    }
+
+    public void testRenderElementWithNamespace() throws Exception {
+        Element main = new Element("test", "http://felix.apache.org/ipojo/testing");
+        String rendered = renderer.render(main);
+        Assert.assertEquals("http://felix.apache.org/ipojo/testing:test { }", rendered);
+    }
+
+    public void testRenderElementWithNoNamespaceAttribute() throws Exception {
+        Element main = new Element("test", null);
+        main.addAttribute(new Attribute("name", "attribute"));
+        String rendered = renderer.render(main);
+        Assert.assertEquals("test { $name=\"attribute\" }", rendered);
+    }
+
+    public void testRenderElementWithNamespaceAttribute() throws Exception {
+        Element main = new Element("test", null);
+        main.addAttribute(new Attribute("name", "ns-uri", "attribute"));
+        String rendered = renderer.render(main);
+        Assert.assertEquals("test { $ns-uri:name=\"attribute\" }", rendered);
+    }
+
+    public void testRenderElementWithChildren() throws Exception {
+        Element main = new Element("test", null);
+        Element child = new Element("child", null);
+        main.addElement(child);
+        String rendered = renderer.render(main);
+        Assert.assertEquals("test { child { }}", rendered);
+    }
+
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/DirectoryResourceStoreTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/DirectoryResourceStoreTestCase.java
new file mode 100644
index 0000000..1179700
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/DirectoryResourceStoreTestCase.java
@@ -0,0 +1,87 @@
+/*
+ * 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.manipulator.store;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.Pojoization;
+import org.apache.felix.ipojo.manipulator.ResourceVisitor;
+import org.apache.felix.ipojo.manipulator.util.Streams;
+import org.apache.felix.ipojo.manipulator.util.Strings;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+/**
+ * A {@code DirectoryBytecodeStoreTestCase} is ...
+ *
+ */
+public class DirectoryResourceStoreTestCase extends TestCase {
+
+    private DirectoryResourceStore store;
+    private File classes;
+    private File out;
+
+    public void setUp() throws Exception {
+        classes = new File("target", "classes");
+        out = new File(classes, "test.txt");
+        store = new DirectoryResourceStore(classes);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        out.delete();
+    }
+
+    public void testAccessibleResources() throws Exception {
+        byte[] data = store.read(Streams.class.getName().replace('.', '/').concat(".class"));
+        assertNotNull("Data cannot be null", data);
+    }
+
+    public void testInaccessibleResources() throws Exception {
+        try {
+            store.read("something/that/do/not/exists.txt");
+            fail();
+        } catch (IOException ioe) {
+            // Expected
+        }
+    }
+
+    public void testResourceWriting() throws Exception {
+        store.write("test.txt", "Hello World".getBytes());
+        Assert.assertTrue(out.isFile());
+    }
+
+    public void testResourceVisitor() throws Exception {
+
+        // final String expectedPath = Strings.asResourcePath(Pojoization.class.getName());
+        ResourceVisitor visitor = mock(ResourceVisitor.class);
+        store.accept(visitor);
+
+        verify(visitor, atLeastOnce()).visit(anyString());
+
+        // TODO try to check that Pojoization class resource was called
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStoreTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStoreTestCase.java
new file mode 100644
index 0000000..ed74c75
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/JarFileResourceStoreTestCase.java
@@ -0,0 +1,82 @@
+/**
+ * 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.manipulator.store;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.ResourceVisitor;
+import org.apache.felix.ipojo.manipulator.util.Streams;
+
+import java.io.File;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.*;
+
+public class JarFileResourceStoreTestCase extends TestCase {
+    public static final String RESOURCE_PATH = "org/apache/felix/ipojo/test/scenarios/component/Annotation.class";
+    private JarFileResourceStore store;
+    private File out;
+
+    public void setUp() throws Exception {
+        File classes = new File("target", "test-classes");
+        out = new File(classes, "test-store.jar");
+        JarFile jar = new JarFile(new File(classes, "tests.manipulation.java5.jar"));
+        store = new JarFileResourceStore(jar, out);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        out.delete();
+    }
+
+    public void testRead() throws Exception {
+        byte[] bytes = store.read(RESOURCE_PATH);
+        Assert.assertNotNull(bytes);
+    }
+
+    public void testAccept() throws Exception {
+        ResourceVisitor visitor = mock(ResourceVisitor.class);
+        store.accept(visitor);
+
+        verify(visitor, atLeastOnce()).visit(anyString());
+
+    }
+
+    public void testWrite() throws Exception {
+
+        ManifestBuilder builder = mock(ManifestBuilder.class);
+        Manifest manifest = new Manifest();
+        when(builder.build(any(Manifest.class))).thenReturn(manifest);
+        store.setManifestBuilder(builder);
+
+        store.write(RESOURCE_PATH, "Hello World".getBytes());
+
+        store.close();
+
+        JarFile outJar = new JarFile(out);
+        Assert.assertNotNull(outJar.getEntry(RESOURCE_PATH));
+        byte[] bytes = Streams.readBytes(outJar.getInputStream(outJar.getEntry(RESOURCE_PATH)));
+
+        Assert.assertEquals("Hello World", new String(bytes));
+
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/builder/DefaultManifestBuilderTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/builder/DefaultManifestBuilderTestCase.java
new file mode 100644
index 0000000..1687468
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/builder/DefaultManifestBuilderTestCase.java
@@ -0,0 +1,97 @@
+/*
+ * 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.manipulator.store.builder;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.Pojoization;
+import org.apache.felix.ipojo.manipulator.store.ManifestBuilder;
+import org.apache.felix.ipojo.manipulator.store.builder.DefaultManifestBuilder;
+
+public class DefaultManifestBuilderTestCase extends TestCase {
+
+    private static final String ORG_OSGI_FRAMEWORK_VERSION_1_5 = "org.osgi.framework;version=1.5";
+    private Manifest manifest;
+    private ManifestBuilder builder;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        manifest = new Manifest();
+        Attributes attributes = manifest.getMainAttributes();
+        attributes.putValue("Import-Package", ORG_OSGI_FRAMEWORK_VERSION_1_5);
+        attributes.putValue("Created-By", "TestCase");
+
+        builder = new DefaultManifestBuilder();
+        builder.addReferredPackage(Collections.singleton("org.osgi.service.http"));
+    }
+
+    public void testManifestIsModified() throws Exception {
+        Manifest modified = builder.build(manifest);
+
+        // Created by header was properly modified
+        Assert.assertEquals("TestCase & iPOJO " + Pojoization.IPOJO_PACKAGE_VERSION,
+                            modified.getMainAttributes().getValue("Created-By"));
+
+        // As there was no metadata provided, no iPOJO-Components header should be present
+        Assert.assertNull(modified.getMainAttributes().getValue("iPOJO-Components"));
+
+        // Check that default manipulation introduced packages are present
+        String imported = modified.getMainAttributes().getValue("Import-Package");
+        Assert.assertTrue(imported.contains(ORG_OSGI_FRAMEWORK_VERSION_1_5));
+        Assert.assertTrue(imported.contains("org.apache.felix.ipojo"));
+        Assert.assertTrue(imported.contains("org.apache.felix.ipojo.architecture"));
+        Assert.assertTrue(imported.contains("org.osgi.service.cm"));
+        Assert.assertTrue(imported.contains("org.osgi.service.log"));
+    }
+
+
+    public void testCreatedByHeaderDoesNotContainIPojoTwice() throws Exception {
+
+        manifest.getMainAttributes().putValue("Created-By", "TestCase for iPOJO");
+
+        Manifest modified = builder.build(manifest);
+
+        // Created by header was properly not changed
+        Assert.assertEquals("TestCase for iPOJO",
+                            modified.getMainAttributes().getValue("Created-By"));
+    }
+
+    public void testReferredPackagesAreProperlyAdded() throws Exception {
+
+        List<String> p = Arrays.asList("org.apache.felix.ipojo.test", "org.apache.felix.ipojo.log");
+        builder.addReferredPackage(new HashSet<String>(p));
+
+        Manifest modified = builder.build(manifest);
+
+        // Check that referred packages are present
+        String imported = modified.getMainAttributes().getValue("Import-Package");
+        Assert.assertTrue(imported.contains("org.apache.felix.ipojo.test"));
+        Assert.assertTrue(imported.contains("org.apache.felix.ipojo.log"));
+    }
+
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/mapper/FileSystemResourceMapperTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/mapper/FileSystemResourceMapperTestCase.java
new file mode 100644
index 0000000..dac3802
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/mapper/FileSystemResourceMapperTestCase.java
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.manipulator.store.mapper;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.store.ResourceMapper;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class FileSystemResourceMapperTestCase extends TestCase {
+
+    public void testUnixInternalize() throws Exception {
+
+        ResourceMapper delegate = mock(ResourceMapper.class);
+        FileSystemResourceMapper mapper = new FileSystemResourceMapper(delegate);
+
+        String path = "this/is/a/unix/like/path.extension";
+        when(delegate.internalize(eq(path))).thenReturn(path);
+
+        String result = mapper.internalize(path);
+
+        Assert.assertEquals(path, result);
+
+    }
+
+    public void testUnixExternalize() throws Exception {
+
+        ResourceMapper delegate = mock(ResourceMapper.class);
+        FileSystemResourceMapper mapper = new FileSystemResourceMapper(delegate);
+
+        String path = "this/is/a/unix/like/path.extension";
+        when(delegate.externalize(eq(path))).thenReturn(path);
+
+        String result = mapper.externalize(path);
+
+        // unix path is already normalized
+        Assert.assertEquals(path, result);
+    }
+
+    public void ignoreWindowsExternalize() throws Exception {
+        // As Java doesn't like '\' alone in Strings I have to replace them on the fly :'(
+        // Grrr doesn't work as expected
+        ResourceMapper delegate = mock(ResourceMapper.class);
+        FileSystemResourceMapper mapper = new FileSystemResourceMapper(delegate);
+
+        String path = "c:\\this\\is\\a\\windows\\like\\path.extension";
+        when(delegate.externalize(eq(path))).thenReturn(path);
+
+        String expected = "c:/this/is/a/windows/like/path.extension";
+        String result = mapper.externalize(path);
+
+        // unix path is already normalized
+        Assert.assertEquals(expected, result);
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/mapper/IdentityResourceMapperTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/mapper/IdentityResourceMapperTestCase.java
new file mode 100644
index 0000000..fc4f645
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/mapper/IdentityResourceMapperTestCase.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.manipulator.store.mapper;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class IdentityResourceMapperTestCase extends TestCase {
+    public void testInternalize() throws Exception {
+        IdentityResourceMapper mapper = new IdentityResourceMapper();
+        String path = "must/not/change";
+        Assert.assertEquals(path, mapper.internalize(path));
+    }
+
+    public void testExternalize() throws Exception {
+        IdentityResourceMapper mapper = new IdentityResourceMapper();
+        String path = "must/not/change";
+        Assert.assertEquals(path, mapper.externalize(path));
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/mapper/WABResourceMapperTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/mapper/WABResourceMapperTestCase.java
new file mode 100644
index 0000000..d15f8ac
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/store/mapper/WABResourceMapperTestCase.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.manipulator.store.mapper;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.store.ResourceMapper;
+
+public class WABResourceMapperTestCase extends TestCase {
+    public void testSimpleInternalize() throws Exception {
+        ResourceMapper mapper = new WABResourceMapper();
+        String path = "jndi.properties";
+        Assert.assertEquals("WEB-INF/classes/" + path, mapper.internalize(path));
+    }
+
+    public void testSimpleExternalize() throws Exception {
+        ResourceMapper mapper = new WABResourceMapper();
+        String path = "WEB-INF/classes/jndi.properties";
+        Assert.assertEquals("jndi.properties", mapper.externalize(path));
+    }
+
+    public void testExternalizeError() throws Exception {
+        ResourceMapper mapper = new WABResourceMapper();
+        String path = "jndi.properties";
+
+        try {
+            mapper.externalize(path);
+            fail("Should have thrown an IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // ok
+        }
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/util/StreamsTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/util/StreamsTestCase.java
new file mode 100644
index 0000000..b3f2902
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/util/StreamsTestCase.java
@@ -0,0 +1,59 @@
+/**
+ * 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.manipulator.util;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class StreamsTestCase extends TestCase {
+    public void testSimpleClose() throws Exception {
+        Closeable closeable = mock(Closeable.class);
+        Streams.close(closeable);
+        verify(closeable).close();
+    }
+
+    public void testCloseWithNullParameter() throws Exception {
+        Closeable closeable = mock(Closeable.class);
+        Streams.close(closeable, null);
+        verify(closeable).close();
+    }
+
+    public void testTransfer() throws Exception {
+        String toBeRead = "Tadam";
+        ByteArrayInputStream bais = new ByteArrayInputStream(toBeRead.getBytes());
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        Streams.transfer(bais, baos);
+        Assert.assertEquals(toBeRead, new String(baos.toByteArray()));
+    }
+
+    public void testReadBytes() throws Exception {
+        String toBeRead = "Tadam";
+        ByteArrayInputStream bais = new ByteArrayInputStream(toBeRead.getBytes());
+        byte[] bytes = Streams.readBytes(bais);
+        Assert.assertEquals(toBeRead, new String(bytes));
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/util/StringsTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/util/StringsTestCase.java
new file mode 100644
index 0000000..44c7dd4
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/util/StringsTestCase.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.ipojo.manipulator.util;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+
+public class StringsTestCase extends TestCase {
+
+    private static final String CLASSNAME = StringsTestCase.class.getName();
+    private static final String PATH = "org/apache/felix/ipojo/manipulator/util/StringsTestCase.class";
+
+    public void testClassnameIsTransformedIntoNormalizedResourcePath() throws Exception {
+        Assert.assertEquals(PATH, Strings.asResourcePath(CLASSNAME));
+    }
+
+    public void testNormalizedResourcePathIsTransformedIntoClassname() throws Exception {
+        Assert.assertEquals(CLASSNAME, Strings.asClassName(PATH));
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyResultVisitorTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyResultVisitorTestCase.java
new file mode 100644
index 0000000..8539c60
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/visitor/check/CheckFieldConsistencyResultVisitorTestCase.java
@@ -0,0 +1,91 @@
+/**
+ * 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.manipulator.visitor.check;
+
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.ManipulationResultVisitor;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.metadata.Attribute;
+import org.apache.felix.ipojo.metadata.Element;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static org.mockito.Mockito.*;
+
+
+public class CheckFieldConsistencyResultVisitorTestCase extends TestCase {
+
+    @Mock
+    private Reporter reporter;
+
+    @Mock
+    private ManipulationResultVisitor delegate;
+
+    @Override
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    public void testVisitClassStructureOK() throws Exception {
+        Element component = newComponentElement();
+        CheckFieldConsistencyResultVisitor visitor = new CheckFieldConsistencyResultVisitor(delegate);
+        visitor.setReporter(reporter);
+        visitor.setMetadata(component);
+
+        Element manipulation = newManipulationElement(true);
+        visitor.visitClassStructure(manipulation);
+
+        verifyZeroInteractions(reporter);
+
+    }
+
+    public void testVisitClassStructureWithMissingFields() throws Exception {
+        Element component = newComponentElement();
+        CheckFieldConsistencyResultVisitor visitor = new CheckFieldConsistencyResultVisitor(delegate);
+        visitor.setReporter(reporter);
+        visitor.setMetadata(component);
+
+        Element manipulation = newManipulationElement(false);
+        visitor.visitClassStructure(manipulation);
+
+        verify(reporter).error(anyString());
+
+    }
+
+    private Element newManipulationElement(boolean complete) {
+        Element manipulation = new Element("manipulation", null);
+        if (complete) {
+            Element field = new Element("field", null);
+            field.addAttribute(new Attribute("name", "property"));
+            manipulation.addElement(field);
+        }
+
+        return manipulation;
+    }
+
+    private Element newComponentElement() {
+        Element component = new Element("component", null);
+        Element requires = new Element("requires", null);
+        requires.addAttribute(new Attribute("field", "property"));
+        component.addElement(requires);
+
+        return component;
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/visitor/writer/ManipulatedResourcesWriterTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/visitor/writer/ManipulatedResourcesWriterTestCase.java
new file mode 100644
index 0000000..3bb4206
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/visitor/writer/ManipulatedResourcesWriterTestCase.java
@@ -0,0 +1,64 @@
+/**
+ * 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.manipulator.visitor.writer;
+
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.manipulator.Reporter;
+import org.apache.felix.ipojo.manipulator.ResourceStore;
+import org.apache.felix.ipojo.metadata.Element;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static org.mockito.Mockito.*;
+
+
+public class ManipulatedResourcesWriterTestCase extends TestCase {
+
+    @Mock
+    private Reporter reporter;
+
+    @Mock
+    private ResourceStore store;
+
+    @Override
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    public void testVisitManipulationResult() throws Exception {
+        ManipulatedResourcesWriter writer = new ManipulatedResourcesWriter();
+        writer.setReporter(reporter);
+        writer.setResourceStore(store);
+
+        Element component = new Element("component", null);
+        assertNotNull(writer.visitManipulationResult(component));
+        verify(store).writeMetadata(same(component));
+    }
+
+    public void testVisitMetadata() throws Exception {
+        ManipulatedResourcesWriter writer = new ManipulatedResourcesWriter();
+        writer.setReporter(reporter);
+        writer.setResourceStore(store);
+
+        Element instance = new Element("instance", null);
+        writer.visitMetadata(instance);
+        verify(store).writeMetadata(same(instance));
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/visitor/writer/ManipulatedResultWriterTestCase.java b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/visitor/writer/ManipulatedResultWriterTestCase.java
new file mode 100644
index 0000000..8b5d149
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/org/apache/felix/ipojo/manipulator/visitor/writer/ManipulatedResultWriterTestCase.java
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.ipojo.manipulator.visitor.writer;
+
+import junit.framework.TestCase;
+import org.apache.felix.ipojo.metadata.Element;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+import static org.mockito.Mockito.*;
+
+
+public class ManipulatedResultWriterTestCase extends TestCase {
+
+    @Spy
+    private Element element = new Element("component", null);
+
+    @Override
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    public void testVisitClassStructure() throws Exception {
+        ManipulatedResultWriter writer = new ManipulatedResultWriter(element);
+
+        Element manipulation = new Element("manipulation", null);
+        writer.visitClassStructure(manipulation);
+        verify(element).addElement(same(manipulation));
+    }
+
+    public void testVisitManipulatedResource() throws Exception {
+        ManipulatedResultWriter writer = new ManipulatedResultWriter(element);
+
+        writer.visitManipulatedResource("test.class", "Hello".getBytes());
+
+        assertNotNull(writer.getResources().get("test.class"));
+        assertEquals("Hello", new String(writer.getResources().get("test.class")));
+    }
+}
diff --git a/ipojo/manipulator/src/test/java/test/AnnotatedComponent.java b/ipojo/manipulator/src/test/java/test/AnnotatedComponent.java
new file mode 100644
index 0000000..186d4bb
--- /dev/null
+++ b/ipojo/manipulator/src/test/java/test/AnnotatedComponent.java
@@ -0,0 +1,18 @@
+package test;
+
+import org.apache.felix.ipojo.annotations.Component;
+import org.apache.felix.ipojo.annotations.Property;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: guillaume
+ * Date: 10/08/11
+ * Time: 21:56
+ * To change this template use File | Settings | File Templates.
+ */
+@Component
+public class AnnotatedComponent {
+
+    @Property
+    private String prop;
+}
diff --git a/ipojo/manipulator/src/test/resources/MANIFEST.MF b/ipojo/manipulator/src/test/resources/MANIFEST.MF
new file mode 100644
index 0000000..8bb4036
--- /dev/null
+++ b/ipojo/manipulator/src/test/resources/MANIFEST.MF
@@ -0,0 +1,19 @@
+Manifest-Version: 1.0
+Export-Package: org.apache.felix.ipojo.test.scenarios.manipulation.ser
+ vice
+Test-Suite: org.apache.felix.ipojo.test.scenarios.manipulation.Manipul
+ ationTestSuite
+Built-By: clement
+Tool: Bnd-0.0.357
+Bundle-Name: iPOJO Manipulation Test Suite For Java 5
+Created-By: Apache Maven Bundle Plugin
+Build-Jdk: 1.6.0_22
+Bundle-Version: 1.5.0.SNAPSHOT
+Bnd-LastModified: 1292008458378
+Bundle-ManifestVersion: 2
+Import-Package: junit.framework,org.apache.felix.ipojo;version="1.6",o
+ rg.apache.felix.ipojo.junit4osgi,org.apache.felix.ipojo.junit4osgi.he
+ lpers,org.apache.felix.ipojo.test.scenarios.manipulation.service,org.
+ osgi.framework;version="1.5"
+Bundle-SymbolicName: tests.manipulation.java5
+
diff --git a/ipojo/manipulator/src/test/resources/empty-metadata.xml b/ipojo/manipulator/src/test/resources/empty-metadata.xml
new file mode 100644
index 0000000..7308bd1
--- /dev/null
+++ b/ipojo/manipulator/src/test/resources/empty-metadata.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<ipojo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xsi:schemaLocation="org.apache.felix.ipojo http://felix.apache.org/ipojo/schemas/SNAPSHOT/core.xsd"
+       xmlns="org.apache.felix.ipojo" />