diff --git a/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/Clazz.java b/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/Clazz.java
new file mode 100644
index 0000000..8bd5f4f
--- /dev/null
+++ b/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/Clazz.java
@@ -0,0 +1,190 @@
+package org.apache.felix.tools.maven.plugin;
+
+import java.io.*;
+import java.util.*;
+
+public class Clazz {
+	static byte	SkipTable[]	= {0, // 0 non existent
+		-1, // 1 CONSTANT_utf8 UTF 8, handled in
+		// method
+		-1, // 2
+		4, // 3 CONSTANT_Integer
+		4, // 4 CONSTANT_Float
+		8, // 5 CONSTANT_Long (index +=2!)
+		8, // 6 CONSTANT_Double (index +=2!)
+		-1, // 7 CONSTANT_Class
+		2, // 8 CONSTANT_String
+		4, // 9 CONSTANT_FieldRef
+		4, // 10 CONSTANT_MethodRef
+		4, // 11 CONSTANT_InterfaceMethodRef
+		4, // 12 CONSTANT_NameAndType
+						};
+
+	Set			imports = new HashSet();
+	String		path;
+	Jar			jar;
+	
+	public Clazz(Jar jar, String path, InputStream in) throws IOException {
+		this.path = path;
+		this.jar = jar;
+		DataInputStream din = new DataInputStream(in);
+		parseClassFile(din);
+	}
+
+
+	void parseClassFile(DataInputStream in)
+			throws IOException {
+		Set classes = new HashSet();
+		Set descriptors = new HashSet();
+		Hashtable pool = new Hashtable();
+		try {
+			int magic = in.readInt();
+			if (magic != 0xCAFEBABE)
+				throw new IOException(
+						"Not a valid class file (no CAFEBABE header)");
+			in.readShort(); // minor version
+			in.readShort(); // major version
+			int count = in.readUnsignedShort();
+			process: for (int i = 1; i < count; i++) {
+				byte tag = in.readByte();
+				switch (tag) {
+					case 0 :
+						break process;
+					case 1 :
+						// CONSTANT_Utf8
+						String name = in.readUTF();
+						pool.put(new Integer(i), name);
+						break;
+					// A Class constant is just a short reference in
+					// the constant pool
+					case 7 :
+						// CONSTANT_Class
+						Integer index = new Integer(in.readShort());
+						classes.add(index);
+						break;
+					// For some insane optimization reason are
+					// the long and the double two entries in the
+					// constant pool. See 4.4.5
+					case 5 :
+						// CONSTANT_Long
+					case 6 :
+						// CONSTANT_Double
+						in.skipBytes(8);
+						i++;
+						break;
+
+					// Interface Method Ref
+					case 12 :
+						in.readShort(); // Name index
+						int descriptorIndex = in.readShort();
+						descriptors.add(new Integer(descriptorIndex));
+						break;
+
+					// We get the skip count for each record type
+					// from the SkipTable. This will also automatically
+					// abort when
+					default :
+						if (tag == 2)
+							throw new IOException("Invalid tag " + tag);
+						in.skipBytes(SkipTable[tag]);
+						break;
+				}
+			}
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+			return;
+		}
+		//
+		// Now iterate over all classes we found and
+		// parse those as well. We skip duplicates
+		//
+
+		for (Iterator e = classes.iterator(); e.hasNext();) {
+			Integer n = (Integer) e.next();
+			String next = (String) pool.get(n);
+			if (next != null) {
+				String normalized = normalize(next);
+				if (normalized != null) {
+                    // For purposes of trying to guess the activator class, we assume
+                    // that any class that references the BundleActivator interface
+                    // must be a BundleActivator implementation.
+					if ( normalized.startsWith("org/osgi/framework/BundleActivator")) {
+						String cname = path.replace('/', '.');
+						cname = cname.substring(0,cname.length()-".class" .length());
+						jar.addActivator(cname);
+					}
+					String pack = getPackage(normalized);
+					if (!pack.startsWith("java."))
+						imports.add(pack);
+				}
+			}
+			else
+				throw new IllegalArgumentException("Invalid class, parent=");
+		}
+		for (Iterator e = descriptors.iterator(); e.hasNext();) {
+			Integer n = (Integer) e.next();
+			String prototype = (String) pool.get(n);
+			if (prototype != null)
+				parseDescriptor(prototype);
+		}
+	}
+
+	void parseDescriptor(String prototype) {
+		addReference(prototype);
+		StringTokenizer st = new StringTokenizer(prototype, "(;)", true);
+		while (st.hasMoreTokens()) {
+			if (st.nextToken().equals("(")) {
+				String token = st.nextToken();
+				while (!token.equals(")")) {
+					addReference(token);
+					token = st.nextToken();
+				}
+				token = st.nextToken();
+				addReference(token);
+			}
+		}
+	}
+
+	private void addReference(String token) {
+		if (token.startsWith("L")) {
+			String clazz = normalize(token.substring(1));
+			if (clazz.startsWith("java/"))
+				return;
+			String pack = getPackage(clazz);
+			imports.add(pack);
+		}
+	}
+
+	static String normalize(String s) {
+		if (s.startsWith("[L"))
+			return normalize(s.substring(2));
+		if (s.startsWith("["))
+			if (s.length() == 2)
+				return null;
+			else
+				return normalize(s.substring(1));
+		if (s.endsWith(";"))
+			return normalize(s.substring(0, s.length() - 1));
+		return s + ".class";
+	}
+
+	static String getPackage(String clazz) {
+		int n = clazz.lastIndexOf('/');
+		if (n < 0)
+			return ".";
+		return clazz.substring(0, n).replace('/', '.');
+	}
+
+
+	public Collection getReferred() {
+		return imports;
+	}
+
+
+	public Object getPath() {
+		return path;
+	}
+
+
+}
diff --git a/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/Jar.java b/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/Jar.java
new file mode 100644
index 0000000..8cd28e7
--- /dev/null
+++ b/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/Jar.java
@@ -0,0 +1,176 @@
+package org.apache.felix.tools.maven.plugin;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.zip.*;
+
+public class Jar {
+	Map			resources	= new TreeMap();
+	Map			imports		= new HashMap();
+	Map			exports		= new HashMap();
+	Manifest	manifest;
+	boolean		manifestFirst;
+	String		name;
+	Jar			parent;
+	List		activators	= new ArrayList();
+
+	public Jar(Jar parent, String name, InputStream in) throws IOException {
+		this.name = name;
+		this.parent = parent;
+		ZipInputStream jar = new ZipInputStream(in);
+		ZipEntry entry = jar.getNextEntry();
+		boolean first = true;
+		while (entry != null) {
+			String path = entry.getName();
+
+			if (path.endsWith(".class")) {
+				Clazz clazz = new Clazz(this, path, jar);
+				resources.put(path, clazz);
+			}
+			else if (path.endsWith(".jar")) {
+				Jar pool = new Jar(this, path, jar);
+				resources.put(path, pool);
+			}
+			else if (path.endsWith("/packageinfo")
+					&& !path.startsWith("OSGI-OPT")) {
+				String version = parsePackageInfo(jar, exports);
+				resources.put(path, version);
+			}
+			else if (path.equals("META-INF/MANIFEST.MF")) {
+				manifestFirst = first;
+				manifest = new Manifest(jar);
+			}
+			else
+				resources.put(path, null);
+
+			entry = jar.getNextEntry();
+			if (!path.endsWith("/"))
+				first = false;
+		}
+	}
+
+	public Jar(Jar parent, String name, File rootDir) throws IOException {
+		this.name = name;
+		this.parent = parent;
+		traverse(rootDir.getAbsolutePath().length(), rootDir, rootDir.list());
+	}
+
+	void traverse(int root, File dir, String list[]) throws IOException {
+		for (int i = 0; i < list.length; i++) {
+			File sub = new File(dir, list[i]);
+			if (sub.isDirectory())
+				traverse(root, sub, sub.list());
+			else {
+				String path = sub.getAbsolutePath().substring(root + 1)
+						.replace(File.separatorChar, '/');
+				FileInputStream in = new FileInputStream(sub);
+
+				if (path.endsWith(".class")) {
+					Clazz clazz = new Clazz(this, path, in);
+					resources.put(path, clazz);
+				}
+				else if (path.endsWith(".jar")) {
+					Jar pool = new Jar(this, path, in);
+					resources.put(path, pool);
+				}
+				else if (path.endsWith("/packageinfo")
+						&& !path.startsWith("OSGI-OPT")) {
+					String version = parsePackageInfo(in, exports);
+					resources.put(path, version);
+				}
+				else if (path.endsWith("META-INF/MANIFEST.MF")) {
+					manifest = new Manifest(in);
+				}
+				else
+					resources.put(path, null);
+			}
+		}
+	}
+
+	private static String parsePackageInfo(InputStream jar, Map exports)
+			throws IOException {
+		try {
+			byte[] buf = collect(jar, 0);
+			String line = new String(buf);
+			StringTokenizer qt = new StringTokenizer(line, " \r\n\t");
+			if (qt.hasMoreElements()) {
+				qt.nextToken();
+				if (qt.hasMoreElements()) {
+					String version = qt.nextToken();
+					return version;
+				}
+			}
+		}
+		catch (Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	/**
+	 * Convenience method to turn an inputstream into a byte array. The method
+	 * uses a recursive algorithm to minimize memory usage.
+	 * 
+	 * @param in stream with data
+	 * @param offset where we are in the stream
+	 * @returns byte array filled with data
+	 */
+	private static byte[] collect(InputStream in, int offset)
+			throws IOException {
+		byte[] result;
+		byte[] buffer = new byte[10000];
+		int size = in.read(buffer);
+		if (size <= 0)
+			return new byte[offset];
+		else
+			result = collect(in, offset + size);
+		System.arraycopy(buffer, 0, result, offset, size);
+		return result;
+	}
+
+	public Manifest getManifest() {
+		return manifest;
+	}
+
+	public Object getEntry(String resource) {
+		return resources.get(resource);
+	}
+
+	public boolean exists(String jarOrDir) {
+		return resources.keySet().contains(jarOrDir);
+	}
+
+	public Set getEntryPaths(String prefix) {
+		Set result = new TreeSet();
+		for (Iterator i = resources.keySet().iterator(); i.hasNext();) {
+			String path = (String) i.next();
+			if (path.startsWith(prefix))
+				result.add(path);
+		}
+		return result;
+	}
+
+	String getName() {
+		return name;
+	}
+
+	public String toString() {
+		return getName();
+	}
+
+	public void addActivator(String path) {
+		if (parent != null)
+			parent.addActivator(path);
+		else {
+			activators.add(path);
+		}
+
+	}
+
+    public boolean containsActivator(String path) {
+        if (parent != null)
+            return parent.containsActivator(path);
+        return activators.contains(path);
+    }
+}
diff --git a/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/OsgiJarMojo.java b/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/OsgiJarMojo.java
index dfafd75..324d793 100644
--- a/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/OsgiJarMojo.java
+++ b/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/OsgiJarMojo.java
@@ -17,24 +17,15 @@
 
 package org.apache.felix.tools.maven.plugin;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.io.*;
+import java.util.*;
 
-import org.apache.maven.archiver.MavenArchiveConfiguration;
-import org.apache.maven.archiver.MavenArchiver;
-import org.apache.maven.artifact.Artifact;
-import org.apache.maven.artifact.DependencyResolutionRequiredException;
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.archiver.*;
+import org.apache.maven.artifact.*;
+import org.apache.maven.plugin.*;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.archiver.ArchiverException;
-import org.codehaus.plexus.archiver.jar.JarArchiver;
-import org.codehaus.plexus.archiver.jar.ManifestException;
+import org.codehaus.plexus.archiver.jar.*;
 import org.codehaus.plexus.util.FileUtils;
 
 /**
@@ -47,262 +38,609 @@
  * @requiresDependencyResolution runtime
  * @description build an OSGi bundle jar
  */
-public class OsgiJarMojo extends AbstractMojo
-{
-    private static final String[] EMPTY_STRING_ARRAY = {};
+public class OsgiJarMojo extends AbstractMojo {
+	private static final String[]		EMPTY_STRING_ARRAY		= {};
 
-    /**
-     * The Maven project.
-     * @parameter expression="${project}"
-     * @required
-     * @readonly
-     */
-    private MavenProject project;
+	int									bundleManifestVersion	= 1;
 
-    /**
-     * The directory for the generated JAR.
-     *
-     * @parameter expression="${project.build.directory}"
-     * @required
-     */
-    private String buildDirectory;
+	/**
+	 * The Maven project.
+	 * 
+	 * @parameter expression="${project}"
+	 * @required
+	 * @readonly
+	 */
+	private MavenProject				project;
 
-    /**
-     * The directory containing generated classes.
-     *
-     * @parameter expression="${project.build.outputDirectory}"
-     * @required
-     * @readonly
-     */
-    private File outputDirectory;
+	/**
+	 * The directory for the generated JAR.
+	 * 
+	 * @parameter expression="${project.build.directory}"
+	 * @required
+	 */
+	private String						buildDirectory;
 
-    /**
-     * The name of the generated JAR file.
-     * 
-     * @parameter alias="jarName" expression="${project.build.finalName}"
-     * @required
-     */
-    private String jarName;
+	/**
+	 * The directory containing generated classes.
+	 * 
+	 * @parameter expression="${project.build.outputDirectory}"
+	 * @required
+	 * @readonly
+	 */
+	private File						outputDirectory;
 
-    /**
-     * The Jar archiver.
-     *
-     * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#jar}"
-     * @required
-     */
-    private JarArchiver jarArchiver;
+	/**
+	 * The name of the generated JAR file.
+	 * 
+	 * @parameter alias="jarName" expression="${project.build.finalName}"
+	 * @required
+	 */
+	private String						jarName;
 
-    /**
-     * The maven archive configuration to use.
-     */
-    private MavenArchiveConfiguration archiveConfig = new MavenArchiveConfiguration();
+	/**
+	 * The Jar archiver.
+	 * 
+	 * @parameter expression="${component.org.codehaus.plexus.archiver.Archiver#jar}"
+	 * @required
+	 */
+	private JarArchiver					jarArchiver;
 
-    /**
-     * The comma separated list of tokens to include in the JAR.
-     * Default is '**'.
-     *
-     * @parameter alias="includes"
-     */
-    private String jarSourceIncludes = "**";
+	/**
+	 * The maven archive configuration to use.
+	 */
+	private MavenArchiveConfiguration	archiveConfig			= new MavenArchiveConfiguration();
 
-    /**
-     * The comma separated list of tokens to exclude from the JAR.
-     *
-     * @parameter alias="excludes"
-     */
-    private String jarSourceExcludes;
+	/**
+	 * The comma separated list of tokens to include in the JAR. Default is
+	 * '**'.
+	 * 
+	 * @parameter alias="includes"
+	 */
+	private String						jarSourceIncludes		= "**";
 
-    /**
-     * @parameter
-     */
-    private String manifestFile;
+	/**
+	 * The comma separated list of tokens to exclude from the JAR.
+	 * 
+	 * @parameter alias="excludes"
+	 */
+	private String						jarSourceExcludes;
 
-    /**
-     * @parameter expression="${org.apache.felix.tools.maven.plugin.OsgiManifest}"
-     */
-    private OsgiManifest osgiManifest;
+	/**
+	 * @parameter
+	 */
+	private String						manifestFile;
 
-    /**
-     * Execute this Mojo
-     * 
-     * @throws MojoExecutionException
-     */
-    public void execute() throws MojoExecutionException
-    {
-        File jarFile = new File( buildDirectory, jarName + ".jar" );
+	/**
+	 * @parameter expression="${org.apache.felix.tools.maven.plugin.OsgiManifest}"
+	 */
+	private OsgiManifest				osgiManifest;
 
-        try
-        {
-            performPackaging( jarFile );
-        }
-        catch ( Exception e )
-        {
-            throw new MojoExecutionException( "Error assembling JAR bundle", e );
-        }
-    }
+	/**
+	 * Execute this Mojo
+	 * 
+	 * @throws MojoExecutionException
+	 */
+	public void execute() throws MojoExecutionException {
+		File jarFile = new File(buildDirectory, jarName + ".jar");
 
-    /**
-     * Generates the JAR bundle file.
-     *
-     * @param  jarFile the target JAR file
-     * @throws IOException
-     * @throws ArchiverException
-     * @throws ManifestException
-     * @throws DependencyResolutionRequiredException
-     */
-    private void performPackaging( File jarFile ) throws IOException, ArchiverException, ManifestException,
-            DependencyResolutionRequiredException, MojoExecutionException
-    {
-        getLog().info( "Generating JAR bundle " + jarFile.getAbsolutePath() );
+		try {
+			performPackaging(jarFile);
+		}
+		catch (Exception e) {
+			throw new MojoExecutionException("Error assembling JAR bundle", e);
+		}
+	}
 
-        MavenArchiver archiver = new MavenArchiver();
+	/**
+	 * Generates the JAR bundle file.
+	 * 
+	 * @param jarFile the target JAR file
+	 * @throws IOException
+	 * @throws ArchiverException
+	 * @throws ManifestException
+	 * @throws DependencyResolutionRequiredException
+	 */
+	private void performPackaging(File jarFile) throws IOException,
+			ArchiverException, ManifestException,
+			DependencyResolutionRequiredException, MojoExecutionException {
 
-        archiver.setArchiver( jarArchiver );
-        archiver.setOutputFile( jarFile );
+		verifyDeclaredBundleManifestVersion();
 
-        addManifestFile();
-        addManifestEntries();
+		getLog().info("Generating JAR bundle " + jarFile.getAbsolutePath());
 
-        addBundleClasspath();
-        addBundleVersion();
+		MavenArchiver archiver = new MavenArchiver();
 
-        jarArchiver.addDirectory( outputDirectory, getIncludes(), getExcludes() );
+		archiver.setArchiver(jarArchiver);
+		archiver.setOutputFile(jarFile);
 
-        archiver.createArchive( project, archiveConfig );
+		addManifestFile();
+		addManifestEntries();
 
-        project.getArtifact().setFile( jarFile );
-    }
+		// Add the JARs that were specified in the POM
+		// as "not" provided
+		addEmbeddedJars();
+		addBundleVersion();
 
-    /**
-     * TODO: Decide if we accept merging of entire manifest.mf files
-     * Here's a big question to make a final decision at some point: Do accept
-     * merging of manifest entries located in some file somewhere in the project
-     * directory?  If so, do we allow both file and configuration based entries
-     * to be specified simultaneously and how do we merge these?
-     */
-    private void addManifestFile()
-    {
-        if ( manifestFile != null )
-        {
-            File file = new File( project.getBasedir().getAbsolutePath(), manifestFile );
-            getLog().info( "Manifest file: " + file.getAbsolutePath() + " will be used" );
-            archiveConfig.setManifestFile( file );
-        }
-        else
-        {
-            getLog().info( "No manifest file specified. Default will be used." );
-        }
-    }
+		jarArchiver.addDirectory(outputDirectory, getIncludes(), getExcludes());
 
-    /**
-     * Look for any OSGi specified manifest entries in the maven-osgi-plugin configuration
-     * section of the POM.  If we find some, then add them to the target artifact's manifest.
-     */
-    private void addManifestEntries()
-    {
-        if ( osgiManifest != null && osgiManifest.getEntries().size() > 0 )
-        {
-            Map entries = osgiManifest.getEntries();
+		// Parse the output directory as if it was a JAR file.
+		// This creates special entries for classes, packageinfo
+		// and embedded JAR files (which are parsed as well).
+		Jar mainJar = new Jar(null, jarName, outputDirectory);
 
-            getLog().info( "Bundle manifest will be modified with the following entries: " + entries.toString() );
-            archiveConfig.addManifestEntries( entries );
-        }
-        else
-        {
-            getLog().info( "No OSGi bundle manifest entries have been specified in the POM." );
-        }
-    }
+		// Calculate the Bundle Classpath from the embedded
+		// JAR files. We hardcode the bcp as ., <embedded jars>
+		// TODO we add all the found JARs to the Bcp, maybe we
+		// should look if they are needed by traversing the imports.
+		List bundleClassPath = getBundleClassPath(mainJar);
+		bundleClassPath.add(0, ".");
+		createBundleClasspathHeader(bundleClassPath);
 
-    /**
-     * We are going to iterate through the POM's specified JAR dependencies.  If a dependency
-     * has a scope of either RUNTIME or COMPILE, then we'll JAR them up inside the
-     * OSGi bundle artifact.  We will then add the Bundle-Classpath manifest entry.
-     */
-    private void addBundleClasspath() throws MojoExecutionException
-    {
-        StringBuffer bundleClasspath = new StringBuffer();
-        Set artifacts = project.getArtifacts();
+		// Calculate the exports (contained) and imports (referred)
+		// The bundleClassPath contains the JARs in the right order
+		Set contained = new HashSet(); // package name
+		Set referred = new HashSet(); // package name
+		Map uses = new HashMap(); // package name => Set of package name
 
-        for ( Iterator it = artifacts.iterator(); it.hasNext(); )
-        {
-            Artifact artifact = (Artifact) it.next();
-            if ( !Artifact.SCOPE_PROVIDED.equals( artifact.getScope() )
-                    && !Artifact.SCOPE_TEST.equals( artifact.getScope() ) )
-            {
-                String type = artifact.getType();
+		// Iterate over the bundle class path and calculate the contained
+		// and referred packages as well as the uses.
+		for (Iterator i = bundleClassPath.iterator(); i.hasNext();) {
+			String path = (String) i.next();
+			Jar jar = path.equals(".") ? mainJar : (Jar) mainJar.resources
+					.get(path);
+			analyzeJar(jar, contained, referred, uses);
+		}
 
-                if ( "jar".equals( type ) )
-                {
-                    File depFile = artifact.getFile();
+		referred.removeAll(contained);
 
-                    try
-                    {
-                        FileUtils.copyFileToDirectory( depFile, outputDirectory );
+		Map exports = parseHeader(osgiManifest.getExportPackage());
+		Map imports = parseHeader(osgiManifest.getImportPackage());
+		Map dynamicImports = parseHeader(osgiManifest.getDynamicImportPackage());
 
-                        if ( bundleClasspath.length() == 0 )
-                        {
-                            bundleClasspath.append( "." );
-                        }
+		if (dynamicImports != null) {
+			// Remove any dynamic imports from the referred set.
+			referred = new HashSet(referred);
+			referred.removeAll(dynamicImports.keySet());
+		}
 
-                        bundleClasspath.append( "," + artifact.getFile().getName() );
-                    }
-                    catch ( Exception e )
-                    {
-                        String errmsg = "Error copying " + depFile.getAbsolutePath() + " to "
-                                + outputDirectory.getAbsolutePath();
-                        throw new MojoExecutionException( errmsg, e );
-                    }
-                }
-            }
-        }
+		if (exports != null) {
+			verifyDeclaredExports(exports, contained);
+			createExportHeader(exports, uses);
+		}
 
-        String finalPath = bundleClasspath.toString();
+		// If the POM file contains an import declaration,
+		// we verify its validity. Otherwise, we generate the
+		// import package header from the referred. Exports
+		// are added to automatically imports for R4 bundles.
+		if (imports == null) {
+			createImportHeader(referred, exports == null ? new HashSet()
+					: exports.keySet());
+		}
+		else {
+			verifyDeclaredImports(referred, imports);
+		}
 
-        if ( finalPath.length() != 0 )
-        {
-            archiveConfig.addManifestEntry( "Bundle-Classpath", finalPath );
-        }
-    }
+		verifyBundleActivator(mainJar);
+		
+		archiver.createArchive(project, archiveConfig);
+		project.getArtifact().setFile(jarFile);
+	}
 
-    /**
-     * Auto-set the bundle version.
-     */
-    private void addBundleVersion()
-    {
-        // Maven uses a '-' to separate the version qualifier,
-        // while OSGi uses a '.', so we need to convert to a '.'
-        StringBuffer sb = new StringBuffer(project.getVersion());
-        if (sb.indexOf("-") >= 0)
-        {
-            sb.setCharAt(sb.indexOf("-"), '.');
-        }
-        archiveConfig.addManifestEntry( "Bundle-Version", sb.toString() );
-    }
+	private void verifyBundleActivator(Jar mainJar) {
+		String ba = osgiManifest.getBundleActivator();
+		if (ba == null || ba.trim().length() == 0) {
+			switch ( mainJar.activators.size() ) {
+				case 0: break;
+				case 1: archiveConfig.addManifestEntry("Bundle-Activator", mainJar.activators.get(0));
+				break;
+				default:
+					getLog().info("[OSGi] No Bundle-Activator specified and multiple found" );
+				break;
+			}
+		}
+		else {
+			if( ! mainJar.activators.contains(ba))
+				getLog().warn("[OSGi] UNABLE TO VERIFY BUNDLE ACTIVATOR: " + ba);
+		}
+	}
 
-    /**
-     * Returns a string array of the includes to be used when assembling/copying the war.
-     *
-     * @return an array of tokens to include
-     */
-    private String[] getIncludes()
-    {
-        return new String[] { jarSourceIncludes };
-    }
+	private void createBundleClasspathHeader(List bundleClassPath) {
+		StringBuffer sb = new StringBuffer();
+		String del = ".,";
+		for (Iterator i = bundleClassPath.iterator(); i.hasNext();) {
+			sb.append(del);
+			sb.append(i.next());
+			del = ",";
+		}
+		if (sb.length() > 0)
+			archiveConfig.addManifestEntry("Bundle-Classpath", sb.toString());
+	}
 
-    /**
-     * Returns a string array of the excludes to be used when assembling/copying the jar.
-     *
-     * @return an array of tokens to exclude
-     */
-    private String[] getExcludes()
-    {
-        List excludeList = new ArrayList( FileUtils.getDefaultExcludesAsList() );
+	/**
+	 * Iterate over the declared exports from the POM, verify that they are
+	 * present, add the uses clause if necessary and finally add the manifest
+	 * entry.
+	 * 
+	 * @param contained Set of contained packages
+	 * @param exports Map with the export clauses from the POM
+	 * @param uses Map with use clauses
+	 * @throws MojoExecutionException
+	 */
+	void verifyDeclaredExports(Map exports, Set contained)
+			throws MojoExecutionException {
+		Set declaredExports = exports.keySet();
+		for (Iterator i = declaredExports.iterator(); i.hasNext();) {
+			String pack = (String) i.next();
+			if (!contained.contains(pack)) {
+				getLog()
+						.error("[OSGi] EXPORTED PACKAGE NOT IN BUNDLE: " + pack);
+				throw new MojoExecutionException(
+						"Exported Package not found in bundle or JARs on bundle class path "
+								+ pack);
+			}
 
-        if ( jarSourceExcludes != null && !"".equals( jarSourceExcludes ) )
-        {
-            excludeList.add( jarSourceExcludes );
-        }
+		}
+	}
 
-        return (String[]) excludeList.toArray( EMPTY_STRING_ARRAY );
-    }
+	/**
+	 * Print out the export headers after adding the uses clause.
+	 * 
+	 * @param exports
+	 * @param uses
+	 * @throws MojoExecutionException
+	 */
+	void createExportHeader(Map exports, Map uses)
+			throws MojoExecutionException {
+		if (exports.size() > 0) {
+			Set declaredExports = exports.keySet();
+			for (Iterator i = declaredExports.iterator(); i.hasNext();) {
+				String pack = (String) i.next();
+				Map clause = (Map) exports.get(pack);
+
+				if (bundleManifestVersion >= 2) {
+					Set t = (Set) uses.get(pack);
+					if (t != null && !t.isEmpty()) {
+						StringBuffer sb = new StringBuffer();
+						String del = "\"";
+						for (Iterator u = t.iterator(); u.hasNext();) {
+							String usedPackage = (String) u.next();
+							if (!usedPackage.equals(pack)) {
+								sb.append(del);
+								sb.append(usedPackage);
+								del = ",";
+							}
+						}
+						sb.append("\"");
+						clause.put("uses:", sb.toString());
+					}
+				}
+			}
+			archiveConfig.addManifestEntry(
+					"Export-Package",
+					printClauses(exports));
+		}
+	}
+
+	/**
+	 * Verify that the declared imports match the referred packages.
+	 * 
+	 * @param referred referred package
+	 * @param imports imported packages from POM
+	 * @throws MojoExecutionException
+	 */
+	void verifyDeclaredImports(Set referred, Map imports)
+			throws MojoExecutionException {
+		Set declaredImports = imports.keySet();
+		Set test = new HashSet(referred);
+		test.removeAll(declaredImports);
+		for (Iterator m = test.iterator(); m.hasNext();) {
+			Object o = m.next();
+			getLog().error("[OSGi] MISSING IMPORT: " + o);
+			throw new MojoExecutionException("Missing Import " + o);
+		}
+
+		test = new HashSet(declaredImports);
+		test.removeAll(referred);
+		for (Iterator m = test.iterator(); m.hasNext();) {
+			getLog().warn("[OSGi] SUPERFLUOUS IMPORT: " + m.next());
+			getLog()
+					.warn(
+							"[OSGi] Removing the POM Import-Package element will automatically generate the import clauses");
+		}
+	}
+
+	/**
+	 * Standard OSGi header parser. This parser can handle the format clauses
+	 * ::= clause ( ',' clause ) + clause ::= name ( ';' name ) (';' key '='
+	 * value )
+	 * 
+	 * This is mapped to a Map { name => Map { attr|directive => value } }
+	 * 
+	 * @param value
+	 * @return
+	 * @throws MojoExecutionException
+	 */
+	static Map parseHeader(String value) throws MojoExecutionException {
+		if (value == null || value.trim().length() == 0)
+			return null;
+
+		Map result = new HashMap();
+		QuotedTokenizer qt = new QuotedTokenizer(value, ";=,");
+		char del;
+		do {
+			boolean hadAttribute = false;
+			Map clause = new HashMap();
+			List aliases = new ArrayList();
+			aliases.add(qt.nextToken());
+			del = qt.getSeparator();
+			while (del == ';') {
+				String adname = qt.nextToken();
+				if (qt.getSeparator() != '=') {
+					if (hadAttribute)
+						throw new MojoExecutionException(
+								"Header contains name field after attribute or directive: "
+										+ adname + " from " + value);
+					aliases.add(adname);
+				}
+				else {
+					String advalue = qt.nextToken();
+					clause.put(adname, advalue);
+					del = qt.getSeparator();
+					hadAttribute = true;
+				}
+			}
+			for (Iterator i = aliases.iterator(); i.hasNext();) {
+				result.put(i.next(), clause);
+			}
+		} while (del == ',');
+		return result;
+	}
+
+	/**
+	 * Create the import header, taking into account R4 automatic import clauses
+	 * for the exports.
+	 * 
+	 * @param referred
+	 * @param contained
+	 */
+	void createImportHeader(Set referred, Set contained) {
+		if (referred.isEmpty())
+			return;
+
+		referred = new TreeSet(referred);
+
+		if (bundleManifestVersion > 1) {
+			referred.addAll(contained);
+		}
+
+		StringBuffer sb = new StringBuffer();
+		String del = "";
+
+		for (Iterator i = referred.iterator(); i.hasNext();) {
+			sb.append(del);
+			sb.append(i.next());
+			del = ", ";
+		}
+		archiveConfig.addManifestEntry("Import-Package", sb.toString());
+	}
+
+	/**
+	 * Calculate the bundle class path based on the list of JARs in our bundle.
+	 * This list includes outselves. We also calculate the Bundle-Classpath
+	 * header (a bit clumsy) This is a bit cheap, so maybe this needs to be
+	 * changed TODO
+	 * 
+	 * @param mainJar
+	 * @param sb
+	 * @return
+	 */
+	List getBundleClassPath(Jar mainJar) {
+		List result = new ArrayList();
+		for (Iterator i = mainJar.resources.keySet().iterator(); i.hasNext();) {
+			String path = (String) i.next();
+			Object resource = mainJar.resources.get(path);
+			if (resource instanceof Jar) {
+				result.add(path);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * We traverse through al the classes that we can find and calculate the
+	 * contained and referred set and uses.
+	 * 
+	 * @param jar
+	 * @param contained
+	 * @param referred
+	 * @param uses
+	 */
+	void analyzeJar(Jar jar, Set contained, Set referred, Map uses) {
+		String prefix = "";
+		Set set = jar.getEntryPaths(prefix);
+		for (Iterator r = set.iterator(); r.hasNext();) {
+			String path = (String) r.next();
+			Object resource = jar.getEntry(path);
+			if (resource instanceof Clazz) {
+				Clazz clazz = (Clazz) resource;
+				String pathOfClass = path.substring(prefix.length());
+				String pack = Clazz.getPackage(pathOfClass);
+				contained.add(pack);
+				referred.addAll(clazz.getReferred());
+
+				// Add all the used packages
+				// to this package
+				Set t = (Set) uses.get(pack);
+				if (t == null)
+					uses.put(pack, t = new HashSet());
+				t.addAll(clazz.getReferred());
+				t.remove(pack);
+			}
+		}
+	}
+
+	/**
+	 * Print a standard Map based OSGi header.
+	 * 
+	 * @param exports map { name => Map { attribute|directive => value } }
+	 * @return the clauses
+	 */
+
+	String printClauses(Map exports) {
+		StringBuffer sb = new StringBuffer();
+		String del = "";
+		for (Iterator i = exports.keySet().iterator(); i.hasNext();) {
+			String name = (String) i.next();
+			Map map = (Map) exports.get(name);
+			sb.append(del);
+			sb.append(name);
+
+			for (Iterator j = map.keySet().iterator(); j.hasNext();) {
+				String key = (String) j.next();
+				String value = (String) map.get(key);
+				sb.append(";");
+				sb.append(key);
+				sb.append("=");
+				sb.append(value);
+			}
+			del = ", ";
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Check if the BundleManifest version is set correctly, base the manifest
+	 * version on it.
+	 * 
+	 * @throws MojoExecutionException
+	 */
+	void verifyDeclaredBundleManifestVersion() throws MojoExecutionException {
+		String mfv = osgiManifest.getBundleManifestVersion();
+		if (mfv != null && mfv.trim().length() != 0) {
+			try {
+				bundleManifestVersion = Integer.parseInt(mfv);
+				if (bundleManifestVersion != 2)
+					throw new MojoExecutionException(
+							"Bundle-ManifestVersion must be 2, it is " + mfv);
+			}
+			catch (Exception e) {
+				throw new MojoExecutionException(
+						"Bundle-ManifestVersion must be an integer: " + mfv);
+			}
+		}
+	}
+
+	/**
+	 * TODO: Decide if we accept merging of entire manifest.mf files Here's a
+	 * big question to make a final decision at some point: Do accept merging of
+	 * manifest entries located in some file somewhere in the project directory?
+	 * If so, do we allow both file and configuration based entries to be
+	 * specified simultaneously and how do we merge these?
+	 */
+	private void addManifestFile() {
+		if (manifestFile != null) {
+			File file = new File(project.getBasedir().getAbsolutePath(),
+					manifestFile);
+			getLog().info(
+					"Manifest file: " + file.getAbsolutePath()
+							+ " will be used");
+			archiveConfig.setManifestFile(file);
+		}
+		else {
+			getLog().info("No manifest file specified. Default will be used.");
+		}
+	}
+
+	/**
+	 * Look for any OSGi specified manifest entries in the maven-osgi-plugin
+	 * configuration section of the POM. If we find some, then add them to the
+	 * target artifact's manifest.
+	 */
+	private void addManifestEntries() {
+		if (osgiManifest != null && osgiManifest.getEntries().size() > 0) {
+			Map entries = osgiManifest.getEntries();
+
+			getLog().info(
+					"Bundle manifest will be modified with the following entries: "
+							+ entries.toString());
+			archiveConfig.addManifestEntries(entries);
+		}
+		else {
+			getLog()
+					.info(
+							"No OSGi bundle manifest entries have been specified in the POM.");
+		}
+	}
+
+	/**
+	 * We are going to iterate through the POM's specified JAR dependencies. If
+	 * a dependency has a scope of either RUNTIME or COMPILE, then we'll JAR
+	 * them up inside the OSGi bundle artifact. We will then add the
+	 * Bundle-Classpath manifest entry.
+	 */
+	private void addEmbeddedJars() throws MojoExecutionException {
+		Set artifacts = project.getArtifacts();
+
+		for (Iterator it = artifacts.iterator(); it.hasNext();) {
+			Artifact artifact = (Artifact) it.next();
+			if (!Artifact.SCOPE_PROVIDED.equals(artifact.getScope())
+					&& !Artifact.SCOPE_TEST.equals(artifact.getScope())) {
+				String type = artifact.getType();
+
+				if ("jar".equals(type)) {
+					File depFile = artifact.getFile();
+
+					try {
+						FileUtils.copyFileToDirectory(depFile, outputDirectory);
+
+					}
+					catch (Exception e) {
+						String errmsg = "Error copying "
+								+ depFile.getAbsolutePath() + " to "
+								+ outputDirectory.getAbsolutePath();
+						throw new MojoExecutionException(errmsg, e);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Auto-set the bundle version.
+	 */
+	private void addBundleVersion() {
+		// Maven uses a '-' to separate the version qualifier,
+		// while OSGi uses a '.', so we need to convert to a '.'
+		StringBuffer sb = new StringBuffer(project.getVersion());
+		if (sb.indexOf("-") >= 0) {
+			sb.setCharAt(sb.indexOf("-"), '.');
+		}
+		archiveConfig.addManifestEntry("Bundle-Version", sb.toString());
+	}
+
+	/**
+	 * Returns a string array of the includes to be used when assembling/copying
+	 * the war.
+	 * 
+	 * @return an array of tokens to include
+	 */
+	private String[] getIncludes() {
+		return new String[] {jarSourceIncludes};
+	}
+
+	/**
+	 * Returns a string array of the excludes to be used when assembling/copying
+	 * the jar.
+	 * 
+	 * @return an array of tokens to exclude
+	 */
+	private String[] getExcludes() {
+		List excludeList = new ArrayList(FileUtils.getDefaultExcludesAsList());
+
+		if (jarSourceExcludes != null && !"".equals(jarSourceExcludes)) {
+			excludeList.add(jarSourceExcludes);
+		}
+
+		return (String[]) excludeList.toArray(EMPTY_STRING_ARRAY);
+	}
 }
diff --git a/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/QuotedTokenizer.java b/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/QuotedTokenizer.java
new file mode 100644
index 0000000..f9aa49b
--- /dev/null
+++ b/tools/maven2/maven-osgi-plugin/src/main/java/org/apache/felix/tools/maven/plugin/QuotedTokenizer.java
@@ -0,0 +1,114 @@
+package org.apache.felix.tools.maven.plugin;
+
+import java.util.*;
+
+public class QuotedTokenizer {
+	String	string;
+	int		index				= 0;
+	String	separators;
+	boolean	returnTokens;
+	boolean	ignoreWhiteSpace	= true;
+	String	peek;
+	char	separator;
+
+	public QuotedTokenizer(String string, String separators, boolean returnTokens ) {
+		if ( string == null )
+			throw new IllegalArgumentException("string argument must be not null");
+		this.string = string;
+		this.separators = separators;
+		this.returnTokens = returnTokens;
+	}
+	public QuotedTokenizer(String string, String separators) {
+		this(string,separators,false);
+	}
+
+	public String nextToken(String separators) {
+		separator = 0;
+		if ( peek != null ) {
+			String tmp = peek;
+			peek = null;
+			return tmp;
+		}
+		
+		if ( index == string.length())
+			return null;
+		
+		StringBuffer sb = new StringBuffer();
+
+		while (index < string.length()) {
+			char c = string.charAt(index++);
+
+			if ( Character.isWhitespace(c)) {
+				if ( index == string.length())
+					break;
+				else
+					continue;
+			}
+			
+			if (separators.indexOf(c) >= 0) {
+				if (returnTokens)
+					peek = Character.toString(c);
+				else
+					separator = c;
+				break;
+			}
+
+			switch (c) {
+				case '"' :
+				case '\'' :
+					quotedString(sb, c);
+					break;
+
+				default :
+					sb.append(c);
+			}
+		}
+		String result = sb.toString().trim();
+		if ( result.length()==0 && index==string.length())
+			return null;
+		return result;
+	}
+
+	public String nextToken() {
+		return nextToken(separators);
+	}
+
+	private void quotedString(StringBuffer sb, char c) {
+		char quote = c;
+		while (index < string.length()) {
+			c = string.charAt(index++);
+			if (c == quote)
+				break;
+			if (c == '\\' && index < string.length()
+					&& string.charAt(index + 1) == quote)
+				c = string.charAt(index++);
+			sb.append(c);
+		}
+	}
+
+	public String[] getTokens() {
+		return getTokens(0);
+	}
+
+	private String [] getTokens(int cnt){
+		String token = nextToken();
+		if ( token == null ) 
+			return new String[cnt];
+		
+		String result[] = getTokens(cnt+1);
+		result[cnt]=token;
+		return result;
+	}
+
+	public char getSeparator() { return separator; }
+	
+	public List getTokenSet() {
+		List list = new ArrayList();
+		String token = nextToken();
+		while ( token != null ) {
+			list.add(token);
+			token = nextToken();
+		}
+		return list;
+	}
+}
