diff --git a/bundleplugin/pom.xml b/bundleplugin/pom.xml
index f6d6945..607224c 100644
--- a/bundleplugin/pom.xml
+++ b/bundleplugin/pom.xml
@@ -54,11 +54,6 @@
  
  <dependencies>
   <dependency>
-   <groupId>biz.aQute</groupId>
-   <artifactId>bndlib</artifactId>
-   <version>0.0.311</version>
-  </dependency>
-  <dependency>
     <groupId>net.sf.kxml</groupId>
     <artifactId>kxml2</artifactId>
     <version>2.2.2</version>
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/CircularDependencyException.java b/bundleplugin/src/main/java/aQute/bnd/build/CircularDependencyException.java
new file mode 100644
index 0000000..f08255b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/CircularDependencyException.java
@@ -0,0 +1,10 @@
+package aQute.bnd.build;
+
+public class CircularDependencyException extends Exception {
+    public CircularDependencyException(String string) {
+        super(string);
+    }
+
+    private static final long serialVersionUID = 1L;
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Container.java b/bundleplugin/src/main/java/aQute/bnd/build/Container.java
new file mode 100644
index 0000000..97a9eb1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Container.java
@@ -0,0 +1,131 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.util.*;
+
+public class Container {
+    public enum TYPE {
+        REPO, PROJECT, EXTERNAL, LIBRARY, ERROR
+    }
+
+    final File                file;
+    final TYPE                type;
+    final String              bsn;
+    final String              version;
+    final String              error;
+    final Project             project;
+    final Map<String, String> attributes;
+
+    Container(Project project, String bsn, String version, TYPE type,
+            File source, String error, Map<String, String> attributes) {
+        this.bsn = bsn;
+        this.version = version;
+        this.type = type;
+        this.file = source != null ? source : new File("/" + bsn + ":"
+                + version + ":" + type);
+        this.project = project;
+        this.error = error;
+        if (attributes == null || attributes.isEmpty())
+            this.attributes = Collections.emptyMap();
+        else
+            this.attributes = attributes;
+    }
+
+    public Container(Project project, File file) {
+        this(project, file.getName(), "project", TYPE.PROJECT, file, null, null);
+    }
+
+    public Container(File file) {
+        this(null, file.getName(), "project", TYPE.EXTERNAL, file, null, null);
+    }
+
+    public File getFile() {
+        return file;
+    }
+
+    public String getBundleSymbolicName() {
+        return bsn;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public TYPE getType() {
+        return type;
+    }
+
+    public String getError() {
+        return error;
+    }
+
+    public boolean equals(Object other) {
+        if (other instanceof Container)
+            return file.equals(((Container) other).file);
+        else
+            return false;
+    }
+
+    public int hashCode() {
+        return file.hashCode();
+    }
+
+    public Project getProject() {
+        return project;
+    }
+
+    /**
+     * Must show the file name or the error formatted as a file name
+     * 
+     * @return
+     */
+    public String toString() {
+        if (getError() != null)
+            return "/error/" + getError();
+        else
+            return getFile().getAbsolutePath();
+    }
+
+    public Map<String, String> getAttributes() {
+        return attributes;
+    }
+
+    /**
+     * Return the this if this is anything else but a library. If it is a
+     * library, return the members. This could work recursively, e.g., libraries
+     * can point to libraries.
+     * 
+     * @return
+     * @throws Exception
+     */
+    public List<Container> getMembers() throws Exception {
+        List<Container> result = project.newList();
+
+        // Are ww a library? If no, we are the result
+        if (getType() != TYPE.LIBRARY)
+            result.add(this);
+        else {
+            // We are a library, parse the file. This is
+            // basically a specification clause per line.
+            // I.e. you can do bsn; version, bsn2; version. But also
+            // spread it out over lines.
+            InputStream in = new FileInputStream(file);
+            BufferedReader rd = new BufferedReader(new InputStreamReader(in,
+                    "UTF-8"));
+            try {
+                String line;
+                while ((line = rd.readLine()) != null) {
+                    line = line.trim();
+                    if (!line.startsWith("#") && line.length() > 0) {
+                        List<Container> list = project.getBundles(
+                                Workspace.STRATEGY_EXACT, line);
+                        result.addAll(list);
+                    }
+                }
+            } finally {
+                in.close();
+            }
+        }
+        return result;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Project.java b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
new file mode 100644
index 0000000..61c0a27
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
@@ -0,0 +1,1067 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.bnd.help.*;
+import aQute.bnd.service.*;
+import aQute.bnd.service.action.*;
+import aQute.bnd.test.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.eclipse.*;
+import aQute.libg.sed.*;
+import aQute.service.scripting.*;
+
+/**
+ * This class is NOT threadsafe
+ * 
+ * @author aqute
+ * 
+ */
+public class Project extends Processor {
+
+    final static String         DEFAULT_ACTIONS = "build; label='Build', test; label='Test', clean; label='Clean', release; label='Release', refreshAll; label=Refresh";
+    public final static String  BNDFILE         = "bnd.bnd";
+    public final static String  BNDCNF          = "cnf";
+    final Workspace             workspace;
+    long                        time;
+    int                         count;
+    boolean                     preparedPaths;
+    final Collection<Project>   dependson       = new LinkedHashSet<Project>();
+    final Collection<Container> buildpath       = new LinkedHashSet<Container>();
+    final Collection<Container> runpath         = new LinkedHashSet<Container>();
+    final Collection<File>      sourcepath      = new LinkedHashSet<File>();
+    final Collection<File>      allsourcepath   = new LinkedHashSet<File>();
+    final Collection<Container> bootclasspath   = new LinkedHashSet<Container>();
+    final Collection<Container> runbundles      = new LinkedHashSet<Container>();
+    File                        output;
+    File                        target;
+    boolean                     inPrepare;
+
+    public Project(Workspace workspace, File projectDir, File buildFile)
+            throws Exception {
+        super(workspace);
+        this.workspace = workspace;
+        setFileMustExist(false);
+        setProperties(buildFile);
+        assert workspace != null;
+        // For backward compatibility reasons, we also read
+        readBuildProperties();
+    }
+
+    public Project(Workspace workspace, File buildDir) throws Exception {
+        this(workspace, buildDir, new File(buildDir, BNDFILE));
+    }
+
+    private void readBuildProperties() throws Exception {
+        try {
+            File f = getFile("build.properties");
+            if (f.isFile()) {
+                Properties p = loadProperties(f);
+                for (Enumeration<?> e = p.propertyNames(); e.hasMoreElements();) {
+                    String key = (String) e.nextElement();
+                    String newkey = key;
+                    if (key.indexOf('$') >= 0) {
+                        newkey = getReplacer().process(key);
+                    }
+                    setProperty(newkey, p.getProperty(key));
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static Project getUnparented(File propertiesFile) throws Exception {
+        propertiesFile = propertiesFile.getAbsoluteFile();
+        Workspace workspace = new Workspace(propertiesFile.getParentFile());
+        Project project = new Project(workspace, propertiesFile.getParentFile());
+        project.setProperties(propertiesFile);
+        project.setFileMustExist(true);
+        return project;
+    }
+
+    public synchronized boolean isValid() {
+        return getBase().isDirectory() && getPropertiesFile().isFile();
+    }
+
+    /**
+     * Return a new builder that is nicely setup for this project. Please close
+     * this builder after use.
+     * 
+     * @param parent
+     *            The project builder to use as parent, use this project if null
+     * @return
+     * @throws Exception
+     */
+    public synchronized ProjectBuilder getBuilder(ProjectBuilder parent)
+            throws Exception {
+
+        ProjectBuilder builder;
+
+        if (parent == null)
+            builder = new ProjectBuilder(this);
+        else
+            builder = new ProjectBuilder(parent);
+
+        builder.setBase(getBase());
+
+        for (Container file : getBuildpath()) {
+            builder.addClasspath(file.getFile());
+        }
+
+        for (Container file : getBootclasspath()) {
+            builder.addClasspath(file.getFile());
+        }
+
+        for (File file : getAllsourcepath()) {
+            builder.addSourcepath(file);
+        }
+        return builder;
+    }
+
+    public synchronized int getChanged() {
+        return count;
+    }
+
+    public synchronized void setChanged() {
+        // if (refresh()) {
+        preparedPaths = false;
+        count++;
+        // }
+    }
+
+    public Workspace getWorkspace() {
+        return workspace;
+    }
+
+    public String toString() {
+        return getBase().getName();
+    }
+
+    /**
+     * Set up all the paths
+     */
+
+    public synchronized void prepare() throws Exception {
+        if (inPrepare)
+            throw new CircularDependencyException(toString());
+        if (!preparedPaths) {
+            inPrepare = true;
+            try {
+                dependson.clear();
+                buildpath.clear();
+                sourcepath.clear();
+                allsourcepath.clear();
+                bootclasspath.clear();
+                runpath.clear();
+                runbundles.clear();
+
+                // We use a builder to construct all the properties for
+                // use.
+                setProperty("basedir", getBase().getAbsolutePath());
+
+                // If a bnd.bnd file exists, we read it.
+                // Otherwise, we just do the build properties.
+                if (!getPropertiesFile().isFile()
+                        && new File(getBase(), ".classpath").isFile()) {
+                    // Get our Eclipse info, we might depend on other projects
+                    // though ideally this should become empty and void
+                    doEclipseClasspath();
+                }
+
+                // Calculate our source directory
+
+                File src = new File(getBase(), getProperty("src", "src"));
+                if (src.isDirectory()) {
+                    sourcepath.add(src);
+                    allsourcepath.add(src);
+                } else
+                    sourcepath.add(getBase());
+
+                // Set default bin directory
+                output = getFile(getProperty("bin", "bin")).getAbsoluteFile();
+                if (output.isDirectory()) {
+                    if (!buildpath.contains(output))
+                        buildpath.add(new Container(this, output));
+                } else {
+                    if (!output.exists())
+                        output.mkdirs();
+                    if (!output.isDirectory())
+                        error("Can not find output directory: " + output);
+                }
+
+                // Where we store all our generated stuff.
+                target = getFile(getProperty("target", "generated"));
+
+                // We might have some other projects we want build
+                // before we do anything, but these projects are not in
+                // our path. The -dependson allows you to build them before.
+
+                List<Project> dependencies = new ArrayList<Project>();
+
+                String dp = getProperty(Constants.DEPENDSON);
+                Set<String> requiredProjectNames = parseHeader(dp).keySet();
+                for (String p : requiredProjectNames) {
+                    Project required = getWorkspace().getProject(p);
+                    if (required == null)
+                        error("No such project " + required + " on "
+                                + Constants.DEPENDSON);
+                    else {
+                        dependencies.add(required);
+                    }
+
+                }
+
+                // We have two paths that consists of repo files, projects,
+                // or some other stuff. The doPath routine adds them to the
+                // path and extracts the projects so we can build them before.
+
+                doPath(buildpath, dependencies, parseBuildpath(), bootclasspath);
+                doPath(runpath, dependencies, parseTestpath(), bootclasspath);
+                doPath(runbundles, dependencies, parseTestbundles(), null);
+
+                // We now know all dependend projects. But we also depend
+                // on whatever those projects depend on. This creates an
+                // ordered list without any duplicates. This of course assumes
+                // that there is no circularity. However, this is checked
+                // by the inPrepare flag, will throw an exception if we
+                // are circular.
+
+                Set<Project> done = new HashSet<Project>();
+                done.add(this);
+                allsourcepath.addAll(sourcepath);
+
+                for (Project project : dependencies)
+                    project.traverse(dependson, done);
+
+                for (Project project : dependson) {
+                    allsourcepath.addAll(project.getSourcepath());
+                }
+                if (isOk())
+                    preparedPaths = true;
+            } finally {
+                inPrepare = false;
+            }
+        }
+    }
+
+    private void traverse(Collection<Project> dependencies, Set<Project> visited)
+            throws Exception {
+        if (visited.contains(this))
+            return;
+
+        visited.add(this);
+
+        for (Project project : getDependson())
+            project.traverse(dependencies, visited);
+
+        dependencies.add(this);
+    }
+
+    /**
+     * Iterate over the entries and place the projects on the projects list and
+     * all the files of the entries on the resultpath.
+     * 
+     * @param resultpath
+     *            The list that gets all the files
+     * @param projects
+     *            The list that gets any projects that are entries
+     * @param entries
+     *            The input list of classpath entries
+     */
+    private void doPath(Collection<Container> resultpath,
+            Collection<Project> projects, Collection<Container> entries,
+            Collection<Container> bootclasspath) {
+        for (Container cpe : entries) {
+            if (cpe.getError() != null)
+                error(cpe.getError());
+            else {
+                if (cpe.getType() == Container.TYPE.PROJECT) {
+                    projects.add(cpe.getProject());
+                }
+                if (bootclasspath != null
+                        && cpe.getBundleSymbolicName().startsWith("ee.")
+                        || cpe.getAttributes().containsKey("boot"))
+                    bootclasspath.add(cpe);
+                else
+                    resultpath.add(cpe);
+            }
+        }
+    }
+
+    /**
+     * Parse the list of bundles that are a prerequisite to this project.
+     * 
+     * Bundles are listed in repo specific names. So we just let our repo
+     * plugins iterate over the list of bundles and we get the highest version
+     * from them.
+     * 
+     * @return
+     */
+
+    private List<Container> parseBuildpath() throws Exception {
+        return getBundles(Constants.STRATEGY_LOWEST,
+                getProperty(Constants.BUILDPATH));
+    }
+
+    private List<Container> parseTestpath() throws Exception {
+        return getBundles(Constants.STRATEGY_HIGHEST,
+                getProperty(Constants.RUNPATH));
+    }
+
+    private List<Container> parseTestbundles() throws Exception {
+        return getBundles(Constants.STRATEGY_HIGHEST,
+                getProperty(Constants.RUNBUNDLES));
+    }
+
+    /**
+     * Analyze the header and return a list of files that should be on the
+     * build, test or some other path. The list is assumed to be a list of bsns
+     * with a version specification. The special case of version=project
+     * indicates there is a project in the same workspace. The path to the
+     * output directory is calculated. The default directory ${bin} can be
+     * overridden with the output attribute.
+     * 
+     * @param strategy
+     *            STRATEGY_LOWEST or STRATEGY_HIGHEST
+     * @param spec
+     *            The header
+     * @return
+     */
+    public List<Container> getBundles(int strategy, String spec)
+            throws Exception {
+        List<Container> result = new ArrayList<Container>();
+        Map<String, Map<String, String>> bundles = parseHeader(spec);
+
+        try {
+            for (Iterator<Map.Entry<String, Map<String, String>>> i = bundles
+                    .entrySet().iterator(); i.hasNext();) {
+                Map.Entry<String, Map<String, String>> entry = i.next();
+                String bsn = entry.getKey();
+                Map<String, String> attrs = entry.getValue();
+
+                Container found = null;
+
+                String versionRange = attrs.get("version");
+
+                if (versionRange != null && versionRange.equals("project")) {
+                    Project project = getWorkspace().getProject(bsn);
+                    if (project.exists()) {
+                        File f = project.getOutput();
+                        found = new Container(project, bsn, "project",
+                                Container.TYPE.PROJECT, f, null, attrs);
+                    } else {
+                        error(
+                                "Reference to project that does not exist in workspace\n"
+                                        + "  Project       %s\n"
+                                        + "  Specification %s", bsn, spec);
+                        continue;
+                    }
+                } else if (versionRange != null && versionRange.equals("file")) {
+                    File f = getFile(bsn);
+                    String error = null;
+                    if (!f.exists())
+                        error = "File does not exist";
+                    if (f.getName().endsWith(".lib")) {
+                        found = new Container(this, bsn, "file",
+                                Container.TYPE.LIBRARY, f, error, attrs);
+                    } else {
+                        found = new Container(this, bsn, "file",
+                                Container.TYPE.EXTERNAL, f, error, attrs);
+                    }
+                } else {
+                    found = getBundle(bsn, versionRange, strategy, attrs);
+                }
+
+                if (found != null) {
+                    List<Container> libs = found.getMembers();
+                    for (Container cc : libs) {
+                        if (result.contains(cc))
+                            warning("Multiple bundles with the same final URL: "
+                                    + cc);
+
+                        result.add(cc);
+                    }
+                } else {
+                    // Oops, not a bundle in sight :-(
+                    Container x = new Container(this, bsn, versionRange,
+                            Container.TYPE.ERROR, null, bsn + ";version="
+                                    + versionRange + " not found", attrs);
+                    result.add(x);
+                    warning("Can not find URL for bsn " + bsn);
+                }
+            }
+        } catch (Exception e) {
+            error("While tring to get the bundles from " + spec, e);
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    public long getTime() {
+        return time;
+    }
+
+    public Collection<Project> getDependson() throws Exception {
+        prepare();
+        return dependson;
+    }
+
+    public Collection<Container> getBuildpath() throws Exception {
+        prepare();
+        return buildpath;
+    }
+
+    public Collection<Container> getRunpath() throws Exception {
+        prepare();
+        return runpath;
+    }
+
+    public Collection<Container> getRunbundles() throws Exception {
+        prepare();
+        return runbundles;
+    }
+
+    public Collection<File> getSourcepath() throws Exception {
+        prepare();
+        return sourcepath;
+    }
+
+    public Collection<File> getAllsourcepath() throws Exception {
+        prepare();
+        return allsourcepath;
+    }
+
+    public Collection<Container> getBootclasspath() throws Exception {
+        prepare();
+        return bootclasspath;
+    }
+
+    public File getOutput() throws Exception {
+        prepare();
+        return output;
+    }
+
+    private void doEclipseClasspath() throws Exception {
+        EclipseClasspath eclipse = new EclipseClasspath(this, getWorkspace()
+                .getBase(), getBase());
+        eclipse.setRecurse(false);
+
+        // We get the file directories but in this case we need
+        // to tell ant that the project names
+        for (File dependent : eclipse.getDependents()) {
+            Project required = workspace.getProject(dependent.getName());
+            dependson.add(required);
+        }
+        for (File f : eclipse.getClasspath()) {
+            buildpath.add(new Container(f));
+        }
+        for (File f : eclipse.getBootclasspath()) {
+            bootclasspath.add(new Container(f));
+        }
+        sourcepath.addAll(eclipse.getSourcepath());
+        allsourcepath.addAll(eclipse.getAllSources());
+        output = eclipse.getOutput();
+    }
+
+    public String _p_dependson(String args[]) throws Exception {
+        return list(args, toFiles(getDependson()));
+    }
+
+    private Collection<?> toFiles(Collection<Project> projects) {
+        List<File> files = new ArrayList<File>();
+        for (Project p : projects) {
+            files.add(p.getBase());
+        }
+        return files;
+    }
+
+    public String _p_buildpath(String args[]) throws Exception {
+        return list(args, getBuildpath());
+    }
+
+    public String _p_testpath(String args[]) throws Exception {
+        return list(args, getRunpath());
+    }
+
+    public String _p_sourcepath(String args[]) throws Exception {
+        return list(args, getSourcepath());
+    }
+
+    public String _p_allsourcepath(String args[]) throws Exception {
+        return list(args, getAllsourcepath());
+    }
+
+    public String _p_bootclasspath(String args[]) throws Exception {
+        return list(args, getBootclasspath());
+    }
+
+    public String _p_output(String args[]) throws Exception {
+        if (args.length != 1)
+            throw new IllegalArgumentException(
+                    "${output} should not have arguments");
+        return getOutput().getAbsolutePath();
+    }
+
+    private String list(String[] args, Collection<?> list) {
+        if (args.length > 3)
+            throw new IllegalArgumentException(
+                    "${"
+                            + args[0]
+                            + "[;<separator>]} can only take a separator as argument, has "
+                            + Arrays.toString(args));
+
+        String separator = ",";
+        if (args.length == 2) {
+            separator = args[1];
+        }
+
+        return join(list, separator);
+    }
+
+    protected Object[] getMacroDomains() {
+        return new Object[] { workspace };
+    }
+
+    public File release(Jar jar) throws Exception {
+    	String name = getProperty(Constants.RELEASEREPO);
+    	return release(name, jar);
+    }
+
+    /**
+     * Release
+     * @param name The repository name
+     * @param jar
+     * @return
+     * @throws Exception
+     */
+    public File release(String name, Jar jar) throws Exception {
+        List<RepositoryPlugin> plugins = getPlugins(RepositoryPlugin.class);
+        RepositoryPlugin rp = null;
+        for (RepositoryPlugin plugin : plugins) {
+        	if (!plugin.canWrite()) {
+        		continue;
+        	}
+            if (name == null) {
+        		rp = plugin;
+        		break;
+            } else if (name.equals(plugin.getName())){
+        		rp = plugin;
+        		break;
+            }
+        }
+
+        if (rp != null) {
+            try {
+                return rp.put(jar);
+            } catch (Exception e) {
+                error("Deploying " + jar.getName() + " on " + rp.getName(), e);
+            } finally {
+                jar.close();
+            }
+        }
+        return null;
+   	
+    }
+    
+    public void release(boolean test) throws Exception {
+    	String name = getProperty(Constants.RELEASEREPO);
+    	release(name, test);
+    }
+    
+    /**
+     * Release
+     * @param name The respository name
+     * @param test Run testcases
+     * @throws Exception
+     */
+    public void release(String name, boolean test) throws Exception {
+        File[] jars = build(test);
+        // If build fails jars will be null
+        if (jars == null) {
+        	return;
+        }
+        for (File jar : jars) {
+            Jar j = new Jar(jar);
+            release(name, j);
+            j.close();
+        }
+    	
+    }
+    
+    /**
+     * Get a bundle from one of the plugin repositories.
+     * 
+     * @param bsn
+     *            The bundle symbolic name
+     * @param range
+     *            The version range
+     * @param lowest
+     *            set to LOWEST or HIGHEST
+     * @return the file object that points to the bundle or null if not found
+     * @throws Exception
+     *             when something goes wrong
+     */
+    public Container getBundle(String bsn, String range, int strategy,
+            Map<String, String> attrs) throws Exception {
+        List<RepositoryPlugin> plugins = getPlugins(RepositoryPlugin.class);
+
+        // If someone really wants the latest, lets give it to them.
+        // regardless of they asked for a lowest strategy
+        if (range != null && range.equals("latest"))
+            strategy = STRATEGY_HIGHEST;
+
+        for (RepositoryPlugin plugin : plugins) {
+            File[] results = plugin.get(bsn, range);
+            if (results != null && results.length > 0) {
+                File f = results[strategy == STRATEGY_LOWEST ? 0
+                        : results.length - 1];
+
+                if (f.getName().endsWith("lib"))
+                    return new Container(this, bsn, range,
+                            Container.TYPE.LIBRARY, f, null, attrs);
+                else
+                    return new Container(this, bsn, range, Container.TYPE.REPO,
+                            f, null, attrs);
+            }
+        }
+
+        return new Container(this, bsn, range, Container.TYPE.ERROR, null, bsn
+                + ";version=" + range + " Not found in " + plugins, null);
+    }
+
+    /**
+     * Deploy the file (which must be a bundle) into the repository.
+     * 
+     * @param name The repository name
+     * @param file
+     *            bundle
+     */
+    public void deploy(String name, File file) throws Exception {
+        List<RepositoryPlugin> plugins = getPlugins(RepositoryPlugin.class);
+        RepositoryPlugin rp = null;
+        for (RepositoryPlugin plugin : plugins) {
+        	if (!plugin.canWrite()) {
+        		continue;
+        	}
+            if (name == null) {
+        		rp = plugin;
+        		break;
+            } else if (name.equals(plugin.getName())){
+        		rp = plugin;
+        		break;
+            }
+        }
+
+        if (rp != null) {
+            Jar jar = new Jar(file);
+            try {
+                rp.put(jar);
+                return;
+            } catch (Exception e) {
+                error("Deploying " + file + " on " + rp.getName(), e);
+            } finally {
+                jar.close();
+            }
+            return;
+        }
+        trace("No repo found " + file);
+        throw new IllegalArgumentException("No repository found for " + file);
+    }
+
+    /**
+     * Deploy the file (which must be a bundle) into the repository.
+     * 
+     * @param file
+     *            bundle
+     */
+    public void deploy(File file) throws Exception {
+    	String name = getProperty(Constants.DEPLOYREPO);
+    	deploy(name, file);
+    }
+    /**
+     * Macro access to the repository
+     * 
+     * ${repo;<bsn>[;<version>[;<low|high>]]}
+     */
+
+    public String _repo(String args[]) throws Exception {
+        if (args.length < 2)
+            throw new IllegalArgumentException(
+                    "Too few arguments for repo, syntax=: ${repo ';'<bsn> [ ; <version> ]}");
+
+        String bsns = args[1];
+        String version = null;
+        int strategy = Constants.STRATEGY_HIGHEST;
+
+        if (args.length > 2) {
+            version = args[2];
+            if (args.length == 4) {
+                if (args[3].equalsIgnoreCase("HIGHEST"))
+                    strategy = Constants.STRATEGY_HIGHEST;
+                else if (args[3].equalsIgnoreCase("LOWEST"))
+                    strategy = STRATEGY_LOWEST;
+                else
+                    error("${repo;<bsn>;<version>;<'highest'|'lowest'>} macro requires a strategy of 'highest' or 'lowest', and is "
+                            + args[3]);
+            }
+        }
+
+        Collection<String> parts = split(bsns);
+        List<String> paths = new ArrayList<String>();
+
+        for (String bsn : parts) {
+            Container jar = getBundle(bsn, version, strategy, null);
+            if (jar.getError() == null) {
+                paths.add(jar.getFile().getAbsolutePath());
+            } else {
+                error("The ${repo} macro could not find " + bsn
+                        + " in the repo, because " + jar.getError() + "\n"
+                        + "Repositories     : "
+                        + getPlugins(RepositoryPlugin.class) + "\n"
+                        + "Strategy         : " + strategy + "\n"
+                        + "Bsn              : " + bsn + ";version=" + version);
+            }
+        }
+        return join(paths);
+    }
+
+    public File getTarget() throws Exception {
+        prepare();
+        return target;
+    }
+
+    public File[] build(boolean underTest) throws Exception {
+        ProjectBuilder builder = getBuilder(null);
+        if (underTest)
+            builder.setProperty(Constants.UNDERTEST, "true");
+        Jar jars[] = builder.builds();
+        File files[] = new File[jars.length];
+
+        File target = getTarget();
+        target.mkdirs();
+
+        for (int i = 0; i < jars.length; i++) {
+            Jar jar = jars[i];
+            try {
+                String bsn = jar.getName();
+                files[i] = new File(target, bsn + ".jar");
+                String msg = "";
+                if (!files[i].exists()
+                        || files[i].lastModified() < jar.lastModified()) {
+                    reportNewer(files[i].lastModified(), jar);
+                    files[i].delete();
+                    jar.write(files[i]);
+                } else {
+                    msg = "(not modified since "
+                            + new Date(files[i].lastModified()) + ")";
+                }
+                trace(jar.getName() + " (" + files[i].getName() + ") "
+                        + jar.getResources().size() + " " + msg);
+            } finally {
+                jar.close();
+            }
+        }
+        getInfo(builder);
+        builder.close();
+        if (isOk())
+            return files;
+        else
+            return null;
+    }
+
+    private void reportNewer(long lastModified, Jar jar) {
+        if (isTrue(getProperty(Constants.REPORTNEWER))) {
+            StringBuilder sb = new StringBuilder();
+            String del = "Newer than " + new Date(lastModified);
+            for (Map.Entry<String, Resource> entry : jar.getResources()
+                    .entrySet()) {
+                if (entry.getValue().lastModified() > lastModified) {
+                    sb.append(del);
+                    del = ", \n     ";
+                    sb.append(entry.getKey());
+                }
+            }
+            if (sb.length() > 0)
+                warning(sb.toString());
+        }
+    }
+
+    /**
+     * Refresh if we are based on stale data. This also implies our workspace.
+     */
+    public boolean refresh() {
+        boolean changed = false;
+        if (isCnf()) {
+            changed = workspace.refresh();
+        }
+        return super.refresh() || changed;
+    }
+
+    public boolean isCnf() {
+        return getBase().getName().equals(Workspace.CNFDIR);
+    }
+
+    public void propertiesChanged() {
+        super.propertiesChanged();
+        preparedPaths = false;
+    }
+
+    public String getName() {
+        return getBase().getName();
+    }
+
+    public Map<String, Action> getActions() {
+        Map<String, Action> all = newMap();
+        Map<String, Action> actions = newMap();
+        fillActions(all);
+        getWorkspace().fillActions(all);
+
+        for (Map.Entry<String, Action> action : all.entrySet()) {
+            String key = getReplacer().process(action.getKey());
+            if (key != null && key.trim().length() != 0)
+                actions.put(key, action.getValue());
+        }
+        return actions;
+    }
+
+    public void fillActions(Map<String, Action> all) {
+        Map<String, Map<String, String>> actions = parseHeader(getProperty(
+                "-actions", DEFAULT_ACTIONS));
+        for (Map.Entry<String, Map<String, String>> entry : actions.entrySet()) {
+            String key = Processor.removeDuplicateMarker(entry.getKey());
+            Action action;
+
+            if (entry.getValue().get("script") != null) {
+                // TODO check for the type
+                action = new ScriptAction(entry.getValue().get("type"), entry
+                        .getValue().get("script"));
+            } else {
+                action = new ReflectAction(key);
+            }
+            String label = entry.getValue().get("label");
+            all.put(label, action);
+        }
+    }
+
+    public void release() throws Exception {
+        release(false);
+    }
+
+    /**
+     * Release.
+     * @param name The repository name
+     * @throws Exception
+     */
+    public void release(String name) throws Exception {
+        release(name, false);
+    }
+
+    public void clean() throws Exception {
+        File target = getTarget();
+        if (target.isDirectory() && target.getParentFile() != null) {
+            delete(target);
+        }
+    }
+
+    public File[] build() throws Exception {
+        return build(false);
+    }
+
+    public boolean test() throws Exception {
+        boolean ok = true;
+        String testbundles = getProperty(TESTBUNDLES);
+
+        if (testbundles == null) {
+            File jars[] = build(true);
+            for (File jar : jars)
+                ok &= test(jar);
+
+        } else {
+            List<Container> containers = getBundles(STRATEGY_HIGHEST,
+                    testbundles);
+            for (Container container : containers) {
+                if (container.getError() == null) {
+                    File jar = container.getFile();
+                    ok &= test(jar);
+                } else
+                    error(container.getError());
+            }
+        }
+        return ok;
+    }
+
+    public boolean test(File f) throws Exception {
+        ProjectLauncher pl = new ProjectLauncher(this);
+        pl.setReport(getProperty("target") + "/" + f.getName().replace(".jar", ".xml"));
+        int errors = pl.run(f);
+        getInfo(pl);
+        if (errors == 0) {
+            trace("ok");
+            return true;
+        } else {
+            error("Failed: " + normalize(f) + ", " + errors + " test"
+                    + (errors > 1 ? "s" : "") + " failures, see "
+                    + normalize(pl.getTestreport()));
+            return false;
+        }
+    }
+
+    private void delete(File target) {
+        if (target.getParentFile() == null)
+            throw new IllegalArgumentException("Can not delete root!");
+        if (!target.exists())
+            return;
+
+        if (target.isDirectory()) {
+            File sub[] = target.listFiles();
+            for (File s : sub)
+                delete(s);
+        }
+        target.delete();
+    }
+
+    /**
+     * This methods attempts to turn any jar into a valid jar. If this is a
+     * bundle with manifest, a manifest is added based on defaults. If it is a
+     * bundle, but not r4, we try to add the r4 headers.
+     * 
+     * @param name
+     * @param in
+     * @return
+     * @throws Exception
+     */
+    public Jar getValidJar(File f) throws Exception {
+        Jar jar = new Jar(f);
+        Manifest manifest = jar.getManifest();
+        if (manifest == null) {
+            trace("Wrapping with all defaults");
+            Builder b = new Builder(this);
+            b.addClasspath(jar);
+            b.setProperty("Bnd-Message", "Wrapped from " + f.getAbsolutePath()
+                    + "because lacked manifest");
+            b.setProperty(Constants.EXPORT_PACKAGE, "*");
+            b.setProperty(Constants.IMPORT_PACKAGE, "*;resolution:=optional");
+            jar = b.build();
+        } else if (manifest.getMainAttributes().getValue(
+                Constants.BUNDLE_MANIFESTVERSION) == null) {
+            trace("Not a release 4 bundle, wrapping with manifest as source");
+            Builder b = new Builder(this);
+            b.addClasspath(jar);
+            b.setProperty(Constants.PRIVATE_PACKAGE, "*");
+            b.mergeManifest(manifest);
+            String imprts = manifest.getMainAttributes().getValue(
+                    Constants.IMPORT_PACKAGE);
+            if (imprts == null)
+                imprts = "";
+            else
+                imprts += ",";
+            imprts += "*;resolution=optional";
+
+            b.setProperty(Constants.IMPORT_PACKAGE, imprts);
+            b.setProperty("Bnd-Message", "Wrapped from " + f.getAbsolutePath()
+                    + "because had incomplete manifest");
+            jar = b.build();
+        }
+        return jar;
+    }
+
+    public String _project(String args[]) {
+        return getBase().getAbsolutePath();
+    }
+
+    public void bump(String mask) throws IOException {
+        Sed sed = new Sed(getReplacer(), getPropertiesFile());
+        sed
+                .replace(
+                        "(Bundle-Version\\s*(:|=)\\s*)(([0-9]+(\\.[0-9]+(\\.[0-9]+)?)?))",
+                        "$1${version;" + mask + ";$3}");
+        sed.doIt();
+        refresh();
+    }
+
+    public void bump() throws IOException {
+        bump(getProperty(BUMPPOLICY, "=+0"));
+    }
+
+    public void action(String command) throws Exception {
+        Action a = new ReflectAction(command);
+        a.execute(this, command);
+    }
+
+    public String _findfile(String args[]) {
+        File f = getFile(args[1]);
+        List<String> files = new ArrayList<String>();
+        tree(files, f, "", Instruction.getPattern(args[2]));
+        return join(files);
+    }
+
+    void tree(List<String> list, File current, String path, Instruction instr) {
+        if (path.length() > 0)
+            path = path + "/";
+
+        String subs[] = current.list();
+        for (String sub : subs) {
+            File f = new File(current, sub);
+            if (f.isFile()) {
+                if (instr.matches(sub) && !instr.isNegated())
+                    list.add(path + sub);
+            } else
+                tree(list, f, path + sub, instr);
+        }
+    }
+
+    public void refreshAll() {
+        workspace.refresh();
+        refresh();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void script(String type, String script) throws Exception {
+        // TODO check tyiping
+        List<Scripter> scripters = getPlugins(Scripter.class);
+        if (scripters.isEmpty()) {
+            error(
+                    "Can not execute script because there are no scripters registered: %s",
+                    script);
+            return;
+        }
+        Map x = (Map) getProperties();
+        scripters.get(0)
+                .eval((Map<String, Object>) x, new StringReader(script));
+    }
+    
+    public String _repos(String args[]) throws Exception {
+        List<RepositoryPlugin> repos = getPlugins(RepositoryPlugin.class);
+        List<String> names = new ArrayList<String>();
+        for ( RepositoryPlugin rp : repos )
+            names.add(rp.getName());
+        return join(names,", ");        
+    }
+    
+    public String _help(String args[]) throws Exception {
+        if ( args.length == 1)
+            return "Specify the option or header you want information for";
+        
+        Syntax syntax = Syntax.HELP.get(args[1]);
+        if  (syntax == null )
+            return "No help for " + args[1];
+        
+        String what = null;
+        if ( args.length> 2)
+            what = args[2];
+     
+        if ( what == null || what.equals("lead"))
+            return syntax.getLead();
+        if ( what == null || what.equals("example"))
+            return syntax.getExample();
+        if ( what == null || what.equals("pattern"))
+            return syntax.getPattern();
+        if ( what == null || what.equals("values"))
+            return syntax.getValues();
+        
+        return "Invalid type specified for help: lead, example, pattern, values";
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ProjectBuilder.java b/bundleplugin/src/main/java/aQute/bnd/build/ProjectBuilder.java
new file mode 100644
index 0000000..9289b8b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ProjectBuilder.java
@@ -0,0 +1,34 @@
+package aQute.bnd.build;
+
+import aQute.lib.osgi.*;
+
+@SuppressWarnings("unchecked")
+public class ProjectBuilder extends Builder {
+    Project project;
+
+    public ProjectBuilder(Project project) {
+        super(project);
+        this.project = project;
+    }
+
+    public ProjectBuilder(ProjectBuilder builder) {
+        super(builder);
+        this.project = builder.project;
+    }
+
+
+    /** 
+     * We put our project and our workspace on the macro path.
+     */
+    protected Object [] getMacroDomains() {
+        return new Object[] {project, project.getWorkspace()};
+    }
+
+    public Builder getSubBuilder() throws Exception {
+        return project.getBuilder(this);
+    }
+
+    public Project getProject() {
+        return project;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ReflectAction.java b/bundleplugin/src/main/java/aQute/bnd/build/ReflectAction.java
new file mode 100644
index 0000000..55c2861
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ReflectAction.java
@@ -0,0 +1,22 @@
+package aQute.bnd.build;
+
+import java.lang.reflect.*;
+
+import aQute.bnd.service.action.*;
+
+public class ReflectAction implements Action {
+    String  what;
+    
+    public ReflectAction(String what) {
+        this.what = what;
+    }
+    
+    public void execute(Project project, String action) throws Exception {
+        Method m = project.getClass().getMethod(what);
+        m.invoke(project);
+    }
+
+    public String toString() {
+        return "ra:" + what;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ScriptAction.java b/bundleplugin/src/main/java/aQute/bnd/build/ScriptAction.java
new file mode 100644
index 0000000..8ca55fd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ScriptAction.java
@@ -0,0 +1,18 @@
+package aQute.bnd.build;
+
+import aQute.bnd.service.action.*;
+
+public class ScriptAction implements Action {
+    final String script;
+    final String type;
+    
+    public ScriptAction(String type, String script) {
+        this.script = script;
+        this.type = type;
+    }
+
+    public void execute(Project project, String action) throws Exception {
+        project.script(type, script);
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Workspace.java b/bundleplugin/src/main/java/aQute/bnd/build/Workspace.java
new file mode 100644
index 0000000..b607492
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Workspace.java
@@ -0,0 +1,109 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.lang.ref.*;
+import java.util.*;
+
+import aQute.bnd.service.action.*;
+import aQute.lib.osgi.*;
+
+public class Workspace extends Processor {
+    public final static int                    STRATEGY_HIGHEST = 1;
+    public final static int                    STRATEGY_EXACT   = 0;
+    public final static int                    STRATEGY_LOWEST  = -1;
+    public static final String                 BUILDFILE        = "build.bnd";
+    public static final String                 CNFDIR           = "cnf";
+
+    static Map<File, WeakReference<Workspace>> cache            = newHashMap();
+    final Map<String, Project>                 models           = newHashMap();
+    final Map<String, Action>                  commands         = newMap();
+
+    /**
+     * This static method finds the workspace and creates a project (or returns
+     * an existing project)
+     * 
+     * @param projectDir
+     * @return
+     */
+    public static Project getProject(File projectDir) throws Exception {
+        projectDir = projectDir.getAbsoluteFile();
+        assert projectDir.isDirectory();
+
+        Workspace ws = getWorkspace(projectDir.getParentFile());
+        return ws.getProject(projectDir.getName());
+    }
+
+    public static Workspace getWorkspace(File workspaceDir) throws Exception {
+        workspaceDir = workspaceDir.getAbsoluteFile();
+        synchronized (cache) {
+            WeakReference<Workspace> wsr = cache.get(workspaceDir);
+            Workspace ws;
+            if (wsr == null || (ws = wsr.get()) == null) {
+                ws = new Workspace(workspaceDir);
+                cache.put(workspaceDir, new WeakReference<Workspace>(ws));
+            }
+            return ws;
+        }
+    }
+
+    public Workspace(File dir) throws Exception {
+        dir = dir.getAbsoluteFile();
+        dir.mkdirs();
+        assert dir.isDirectory();
+
+        File buildDir = new File(dir, CNFDIR).getAbsoluteFile();
+        File buildFile = new File(buildDir, BUILDFILE).getAbsoluteFile();
+        if (!buildFile.isFile())
+            warning("No Build File in " + dir);
+        setProperties(buildFile, dir);
+    }
+
+    public Project getProject(String bsn) throws Exception {
+        synchronized (models) {
+            Project project = models.get(bsn);
+            if (project != null)
+                return project;
+
+            File projectDir = getFile(bsn);
+            project = new Project(this, projectDir);
+            models.put(bsn, project);
+            return project;
+        }
+    }
+
+    public boolean isPresent(String name) {
+        return models.containsKey(name);
+    }
+
+    public Collection<Project> getCurrentProjects() {
+        return models.values();
+    }
+
+    public boolean refresh() {
+        if (super.refresh()) {
+            for (Project project : getCurrentProjects()) {
+                project.propertiesChanged();
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public String _workspace(String args[]) {
+        return getBase().getAbsolutePath();
+    }
+
+    public void addCommand(String menu, Action action) {
+        commands.put(menu, action);
+    }
+
+    public void removeCommand(String menu) {
+        commands.remove(menu);
+    }
+
+    public void fillActions(Map<String, Action> all) {
+        all.putAll(commands);
+    }
+    
+    
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/help/Syntax.java b/bundleplugin/src/main/java/aQute/bnd/help/Syntax.java
new file mode 100644
index 0000000..8dde3da
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/help/Syntax.java
@@ -0,0 +1,482 @@
+package aQute.bnd.help;
+
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.lib.osgi.*;
+
+public class Syntax implements Constants {
+    final String                            header;
+    final String                            lead;
+    final String                            example;
+    final Pattern                           pattern;
+    final String                            values;
+    final Syntax[]                          children;
+
+    static Syntax                           version              = new Syntax(
+                                                                         VERSION_ATTRIBUTE,
+                                                                         "A version range to select the version of an export definition. The default value is 0.0.0 .",
+                                                                         "version=\"[1.2,3.0)\"",
+                                                                         null,
+                                                                         Verifier.VERSIONRANGE);
+    static Syntax                           bundle_symbolic_name = new Syntax(
+                                                                         BUNDLE_SYMBOLIC_NAME_ATTRIBUTE,
+                                                                         "The bundle symbolic name of the exporting bundle.",
+                                                                         "bundle-symbolic-name=com.acme.foo.daffy",
+                                                                         null,
+                                                                         Verifier.SYMBOLICNAME);
+
+    static Syntax                           bundle_version       = new Syntax(
+                                                                         BUNDLE_VERSION_ATTRIBUTE,
+                                                                         "a version range to select the bundle version of the exporting bundle. The default value is 0.0.0.",
+                                                                         "bundle-version=1.3",
+                                                                         null,
+                                                                         Verifier.VERSIONRANGE);
+
+    static Syntax                           path_version         = new Syntax(
+                                                                         VERSION_ATTRIBUTE,
+                                                                         "Specifies the range in the repository, project, or file",
+                                                                         "version=project",
+                                                                         "project,type",
+                                                                         Pattern
+                                                                                 .compile("project|type|"
+                                                                                         + Verifier.VERSIONRANGE
+                                                                                                 .toString()));
+
+    static Syntax[]                         syntaxes             = new Syntax[] {
+            new Syntax(
+                    BUNDLE_ACTIVATION_POLICY,
+                    "The Bundle-ActivationPolicy specifies how the framework should activate the bundle once started. ",
+                    "Bundle-ActivationPolicy: lazy", "lazy", Pattern
+                            .compile("lazy")),
+
+            new Syntax(
+                    BUNDLE_ACTIVATOR,
+                    "The Bundle-Activator header specifies the name of the class used to start and stop the bundle. ",
+                    "Bundle-Activator: com.acme.foo.Activator",
+                    "${classes;implementing;org.osgi.framework.BundleActivator}",
+                    Verifier.FQNPATTERN),
+            new Syntax(
+                    BUNDLE_CATEGORY,
+                    "The Bundle-Category header holds a comma-separated list of category names",
+                    "Bundle-Category: test",
+                    "osgi,test,game,util,eclipse,netbeans,jdk,specification",
+                    null),
+            new Syntax(
+                    BUNDLE_CLASSPATH,
+                    "The Bundle-ClassPath header defines a comma-separated list of JAR file path names or directories (inside the bundle) containing classes and resources. The period (’.’) specifies the root directory of the bundle’s JAR. The period is also the default.",
+                    "Bundle-Classpath: /lib/libnewgen.so, .", null,
+                    Verifier.PATHPATTERN),
+            new Syntax(
+                    BUNDLE_CONTACTADDRESS,
+                    "The Bundle-ContactAddress header provides the contact address of the vendor. ",
+                    "Bundle-ContactAddress: 2400 Oswego Road, Austin, TX 74563",
+                    null, null),
+            new Syntax(
+                    BUNDLE_COPYRIGHT,
+                    "The Bundle-Copyright header contains the copyright specification for this bundle. ",
+                    "Bundle-Copyright: OSGi (c) 2002", null, null),
+            new Syntax(
+                    BUNDLE_DESCRIPTION,
+                    "The Bundle-Description header defines a short description of this bundle.",
+                    "Bundle-Description: Ceci ce n'est pas une bundle", null,
+                    null),
+
+            new Syntax(
+                    BUNDLE_DOCURL,
+                    "The Bundle-DocURL headers must contain a URL pointing to documentation about this bundle.",
+                    "Bundle-DocURL: http://www.aQute.biz/Code/Bnd", null,
+                    Verifier.URLPATTERN),
+
+            new Syntax(
+                    BUNDLE_ICON,
+                    "The optional Bundle-Icon header provides a list of (relative) URLs to icons representing this bundle in different sizes. ",
+                    "Bundle-Icon: /icons/bnd.png;size=64", "/icons/bundle.png",
+                    Verifier.URLPATTERN, new Syntax("size",
+                            "Icons size in pixels, e.g. 64", "64",
+                            "16,32,48,64,128", Verifier.NUMBERPATTERN)),
+
+            new Syntax(
+                    BUNDLE_LICENSE,
+                    "The Bundle-License header provides an optional machine readable form of license information. The purpose of this header is to automate some of the license processing required by many organizations",
+                    "Bundle License: http://www.opensource.org/licenses/jabberpl.php",
+                    "http://www.apache.org/licenses/LICENSE-2.0,<<EXTERNAL>>",
+                    Pattern.compile("(" + Verifier.URLPATTERN
+                            + "|<<EXTERNAL>>)"), new Syntax(
+                            DESCRIPTION_ATTRIBUTE,
+                            "Human readable description of the license",
+                            "description=\"Described the license here\"", null,
+                            Verifier.ANYPATTERN), new Syntax(LINK_ATTRIBUTE,
+                            "", "", null, Verifier.URLPATTERN)),
+            new Syntax(
+                    BUNDLE_LOCALIZATION,
+                    "The Bundle-Localization header contains the location in the bundle where localization files can be found. The default value is OSGI-INF/l10n/bundle. Translations are by default therefore OSGI-INF/l10n/bundle_de.properties, OSGI-INF/l10n/bundle_nl.properties, etc.",
+                    "Bundle-Localization: OSGI-INF/l10n/bundle",
+                    "OSGI-INF/l10n/bundle", Verifier.URLPATTERN),
+            new Syntax(
+                    BUNDLE_MANIFESTVERSION,
+                    "This header is set by bnd automatically to 2. The Bundle-ManifestVersion header defines that the bundle follows the rules of this specification. The Bundle-ManifestVersion header determines whether the bundle follows the rules of this specification.",
+                    "# Bundle-ManifestVersion: 2", "2", Verifier.NUMBERPATTERN),
+            new Syntax(
+                    BUNDLE_NAME,
+                    "This header will be derived from the  Bundle-SymbolicName if not set. The Bundle-Name header defines a readable name for this bundle. This should be a short, human-readable name that can contain spaces.",
+                    "Bundle-Name: My Bundle", null, Verifier.ANYPATTERN),
+            new Syntax(
+                    BUNDLE_NATIVECODE,
+                    "The Bundle-NativeCode header contains a specification of native code libraries contained in this bundle. ",
+                    "Bundle-NativeCode: /lib/http.DLL; osname = QNX; osversion = 3.1",
+                    null,
+                    Verifier.PATHPATTERN,
+                    new Syntax(OSNAME_ATTRIBUTE,
+                            "The name of the operating system", "osname=MacOS",
+                            Processor.join(Verifier.OSNAMES, ","),
+                            Verifier.ANYPATTERN),
+                    new Syntax(OSVERSION_ATTRIBUTE, "Operating System Version",
+                            "osversion=3.1", null, Verifier.ANYPATTERN),
+                    new Syntax(LANGUAGE_ATTRIBUTE, "Language ISO 639 code",
+                            "language=nl", null, Verifier.ISO639),
+                    new Syntax(PROCESSOR_ATTRIBUTE, "Processor name",
+                            "processor=x86", Processor.join(
+                                    Verifier.PROCESSORNAMES, ","),
+                            Verifier.ANYPATTERN),
+                    new Syntax(
+                            SELECTION_FILTER_ATTRIBUTE,
+                            "The value of this attribute must be a filter expression that indicates if the native code clause should be selected or not.",
+                            "selection-filter=\"(com.acme.windowing=win32)\"",
+                            null, Verifier.FILTERPATTERN)),
+            new Syntax(
+                    BUNDLE_REQUIREDEXECUTIONENVIRONMENT,
+                    "The Bundle-RequiredExecutionEnvironment contains a comma-separated list of execution environments that must be present on the Service Platform.",
+                    "Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0",
+                    Processor.join(Verifier.EES, ","), Verifier.ANYPATTERN),
+
+            new Syntax(
+                    BUNDLE_SYMBOLICNAME,
+                    "The Bundle-SymbolicName header specifies a non-localizable name for this bundle. The bundle symbolic name together with a version must identify a  unique bundle. The bundle symbolic name should be based on the reverse  domain name convention",
+                    "Bundle-SymbolicName: com.acme.foo.daffy;singleton:=true",
+                    "${p}",
+                    Verifier.SYMBOLICNAME,
+                    new Syntax(
+                            SINGLETON_DIRECTIVE,
+                            " Indicates that the bundle can only have  a single version resolved.  A value of true indicates that the bundle is a singleton bundle. The default value is false. The Framework must resolve at most one  bundle when multiple versions of a singleton bundle with the same symbolic name are installed. Singleton bundles do not affect the resolution of non-singleton bundles with the same symbolic name.",
+                            "false", "true,false", Verifier.TRUEORFALSEPATTERN),
+                    new Syntax(
+                            FRAGMENT_ATTACHMENT_DIRECTIVE,
+                            "Defines how fragments are allowed to be attached, see the fragments in Fragment Bundles on page73. The following values are valid for this directive:",
+                            "", "always|never|resolve-time", Pattern
+                                    .compile("always|never|resolve-time")),
+                    new Syntax(BLUEPRINT_WAIT_FOR_DEPENDENCIES_ATTRIBUTE, "",
+                            "", "true,false", Verifier.TRUEORFALSEPATTERN),
+                    new Syntax(BLUEPRINT_TIMEOUT_ATTRIBUTE, "", "",
+                            "30000,60000,300000", Verifier.NUMBERPATTERN)),
+
+            new Syntax(
+                    BUNDLE_UPDATELOCATION,
+                    "The Bundle-UpdateLocation header specifies a URL where an update for this bundle should come from. If the bundle is updated, this location should be used, if present, to retrieve the updated JAR file.",
+                    "Bundle-UpdateLocation: http://www.acme.com/Firewall/bundle.jar",
+                    null, Verifier.URLPATTERN),
+
+            new Syntax(
+                    BUNDLE_VENDOR,
+                    "The Bundle-Vendor header contains a human-readable description of the bundle vendor. ",
+                    "Bundle-Vendor: OSGi Alliance ", null, null),
+
+            new Syntax(
+                    BUNDLE_VERSION,
+                    "The Bundle-Version header specifies the version of this bundle",
+                    "Bundle-Version: 1.23.4.build200903221000", null,
+                    Verifier.VERSION),
+
+            new Syntax(
+                    DYNAMICIMPORT_PACKAGE,
+                    "The DynamicImport-Package header contains a comma-separated list of package names that should be dynamically imported when needed.",
+                    "DynamicImport-Package: com.acme.plugin.*", "",
+                    Verifier.WILDCARDNAMEPATTERN, version,
+                    bundle_symbolic_name, bundle_version),
+
+            new Syntax(
+                    EXPORT_PACKAGE,
+                    "The Export-Package header contains a declaration of exported packages.",
+                    "Export-Package: org.osgi.util.tracker;version=1.3",
+                    "${packages}",
+                    null,
+                    new Syntax(
+                            NO_IMPORT_DIRECTIVE,
+                            "By default, bnd makes all exports also imports. Adding a -noimport to an exported package will make it export only",
+                            "-noimport:=true", "true,false",
+                            Verifier.TRUEORFALSEPATTERN),
+                    new Syntax(
+                            USES_DIRECTIVE,
+                            "Calculated by bnd: It is a comma-separated list of package names that are used by the exported package",
+                            "Is calculated by bnd", null, null),
+                    new Syntax(
+                            MANDATORY_DIRECTIVE,
+                            "A comma-separated list of attribute names. Note that the use of a comma in the value requires it to be enclosed in double quotes. A bundle importing the package must specify the mandatory attributes, with a value that matches, to resolve to the exported package",
+                            "mandatory=\"bar,foo\"", null, null),
+                    new Syntax(
+                            INCLUDE_DIRECTIVE,
+                            "A comma-separated list of class names that must be visible to an importer",
+                            "include:=\"Qux*\"", null, null),
+                    new Syntax(
+                            EXCLUDE_DIRECTIVE,
+                            "A comma-separated list of class names that must not be visible to an importer",
+                            "exclude:=\"QuxImpl*,BarImpl\"", null,
+                            Verifier.WILDCARDNAMEPATTERN), new Syntax(
+                            IMPORT_DIRECTIVE, "Experimental", "", null, null)
+
+            ),
+            new Syntax(EXPORT_SERVICE, "Deprecated",
+                    "Export-Service: org.osgi.service.log.LogService ",
+                    "${classes;implementing;*}", null),
+            new Syntax(
+                    FRAGMENT_HOST,
+                    "The Fragment-Host header defines the host bundle for this fragment.",
+                    "Fragment-Host: org.eclipse.swt; bundle-version=\"[3.0.0,4.0.0)\"",
+                    null,
+                    null,
+                    new Syntax(
+                            EXTENSION_DIRECTIVE,
+                            " Indicates this extension is a system or boot class path extension. It is only applicable when the Fragment-Host is the System Bundle",
+                            "extension:=framework", "framework,bootclasspath",
+                            Pattern.compile("framework|bootclasspath")),
+                    bundle_version),
+            new Syntax(
+                    IMPORT_PACKAGE,
+                    "This header is normally calculated by bnd, however, you can decorate packages or skip packages. The Import-Package header declares the imported packages for this bundle",
+                    "Import-Package: !com.exotic.*, com.acme.foo;vendor=ACME, *",
+                    "${exported_packages}",
+                    Verifier.WILDCARDNAMEPATTERN,
+                    new Syntax(
+                            REMOVE_ATTRIBUTE_DIRECTIVE,
+                            "Remove the given attributes from matching imported packages",
+                            "-remove-attribute:=foo.*", null,
+                            Verifier.WILDCARDNAMEPATTERN),
+                    new Syntax(
+                            RESOLUTION_DIRECTIVE,
+                            "Indicates that the packages must be resolved if the value is mandatory, which is the default. If mandatory packages cannot be resolved, then the bundle must fail to resolve. A value of optional indicates that the packages are optional",
+                            "resolution:=optional", "mandatory,optional",
+                            Pattern.compile("mandatory|optional")
+
+                    ), version, bundle_symbolic_name, bundle_version),
+
+            new Syntax(
+                    REQUIRE_BUNDLE,
+                    "The Require-Bundle header specifies the required exports from another bundle.",
+                    "Require-Bundle: com.acme.chess",
+                    null,
+                    Verifier.WILDCARDNAMEPATTERN,
+
+                    new Syntax(
+                            VISIBILITY_DIRECTIVE,
+                            " If the value is private (Default), then all visible packages from the required bundles are not re-exported. If the value is reexport then bundles that require this bundle will transitively have access to these required bundle’s exported packages.",
+                            "visibility:=private", "private,reexport", Pattern
+                                    .compile("private|reexport")),
+
+                    new Syntax(
+                            RESOLUTION_DIRECTIVE,
+                            "If the value is mandatory (default) then the required bundle must exist for this bundle to resolve. If the value is optional, the bundle will resolve even if the required bundle does not exist.",
+                            "resolution:=optional", "mandatory,optional",
+                            Pattern.compile("mandatory|optional")),
+
+                    new Syntax(
+                            SPLIT_PACKAGE_DIRECTIVE,
+                            "Indicates how an imported package should be merged when it is split between different exporters. The default is merge-first with warning",
+                            "-split-package:=merge-first",
+                            "merge-first,merge-last,error,first",
+                            Pattern
+                                    .compile("merge-first|merge-last|error|first")),
+                    bundle_version
+
+            ),
+
+            new Syntax(
+                    BUILDPATH,
+                    "Provides the class path for building the jar. The entries are references to the repository",
+                    "-buildpath=osgi;version=4.1", "${repo;bsns}",
+                    Verifier.SYMBOLICNAME, path_version),
+            new Syntax(
+                    BUMPPOLICY,
+                    "Sets the version bump policy. This is a parameter to the ${version} macro.",
+                    "-bumppolicy==+0", "==+,=+0,+00", Pattern
+                            .compile("[=+-0][=+-0][=+-0]")),
+
+            new Syntax(
+                    CONDUIT,
+                    "Allows a bnd file to point to files which will be returned when the bnd file is build",
+                    "-conduit= jar/osgi.jar", null, null),
+
+            new Syntax(
+                    DEPENDSON,
+                    "List of project names that this project directly depends on. These projects are always build ahead of this project",
+                    "-dependson=org.acme.cm", "${projects}", null),
+
+            new Syntax(DEPLOYREPO,
+                    "Specifies to which repo the project should be deployed.",
+                    "-deployrepo=cnf", "${repos}", null),
+
+            new Syntax(
+                    DONOTCOPY,
+                    "Regular expression for names of files and directories that should not be copied when discovered",
+                    "-donotcopy=(CVS|\\.svn)", null, null),
+
+            new Syntax(
+                    EXPORT_CONTENTS,
+                    "Build the JAR in the normal way but use this header for the Export-Package header manifest generation, same format",
+                    "-exportcontents=!*impl*,*;version=3.0", null, null),
+
+            new Syntax(
+                    FAIL_OK,
+                    "Return with an ok status (0) even if the build generates errors",
+                    "-failok=true", "true,false", Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(
+                    INCLUDE,
+                    "Include files. If an entry starts with '-', it does not have to exist. If it starts with '~', it must not overwrite any existing properties",
+                    "-include: -${java.user}/.bnd", null, null),
+
+            new Syntax(
+                    INCLUDERESOURCE,
+                    "Include resources from the file system. You can specify a directory, or file. All files are copied to the root, unless a destination directory is indicated",
+                    "-includeresource: lib=jar", null, null),
+
+            new Syntax(
+                    MAKE,
+                    "Set patterns for make plugins. These patterns are used to find a plugin that can make a resource that can not be found.",
+                    "-make: (*).jar;type=bnd;  recipe=\"bnd/$1.bnd\"", null,
+                    null, new Syntax("type", "Type name for plugin",
+                            "type=bnd", "bnd", null), new Syntax("recipe",
+                            "Recipe for the plugin, can use back references",
+                            "recipe=\"bnd/$1.bnd\"", "bnd", null)),
+
+            new Syntax(
+                    MANIFEST,
+                    "Directly include a manifest, do not use the calculated manifest",
+                    "-manifest = META-INF/MANIFEST.MF", null, null),
+
+            new Syntax(NOEXTRAHEADERS, "Do not generate housekeeping headers",
+                    "-noextraheaders", "true,false",
+                    Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(NOUSES,
+                    "Do not calculate the uses: directive on exports",
+                    "-nouses=true", "true,false", Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(NOPE,
+                    "Dont do anything, return without building any jars",
+                    "-nope=true", "true,false", Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(
+                    PEDANTIC,
+                    "Warn about things that are not really wrong but still not right",
+                    "-nope=true", "true,false", Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(
+                    PLUGIN,
+                    "Define the plugins",
+                    "-plugin=aQute.lib.spring.SpringComponent,aQute.lib.deployer.FileRepo;location=${repo}",
+                    null, null),
+
+            new Syntax(
+                    SERVICE_COMPONENT,
+                    "The header for Declarative Services",
+                    "Service-Component=com.acme.Foo?;activate='start'",
+                    null, null),
+
+            new Syntax(POM, "Generate a maven pom", "-pom=true", "true,false",
+                    Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(RELEASEREPO,
+                    "Specifies to which repo the project should be released.",
+                    "-releaserepo=cnf", "${repos}", null),
+
+            new Syntax(REMOVE_HEADERS,
+                    "Remove all headers that match the regular expressions",
+                    "-removeheaders=FOO_.*,Proprietary", null, null),
+            new Syntax(
+                    RESOURCEONLY,
+                    "Normally bnd warns when the JAR does not contain any classes, this option suppresses this warning",
+                    "-resourceonly=true", "true,false",
+                    Verifier.TRUEORFALSEPATTERN),
+            new Syntax(SOURCES, "Include sources in the jar", "-sources=true",
+                    "true,false", Verifier.TRUEORFALSEPATTERN),
+            new Syntax(
+                    SOURCEPATH,
+                    "List of directory names that used to source sources for -sources",
+                    "-sourcepath:= src, test", null, null),
+            new Syntax(
+                    SUB,
+                    "Build a set of bnd files that use this bnd file as a basis. The list of bnd file can be specified with wildcards",
+                    "-sub=com.acme.*.bnd", null, null),
+            new Syntax(
+                    RUNPROPERTIES,
+                    "Properties that are set as system properties before the framework is started",
+                    "-runproperties= foo=3, bar=4", null, null),
+            new Syntax(RUNSYSTEMPACKAGES,
+                    "Add additional system packages to a framework run",
+                    "-runsystempackages=com.acme.foo,javax.management", null,
+                    null),
+            new Syntax(
+                    RUNBUNDLES,
+                    "Add additional bundles, specified with their bsn and version like in -buildpath, that are started before the project is run",
+                    "-runbundles=osgi;version=\"[4.1,4.2)\", junit.junit, com.acme.foo;version=project",
+                    null, Verifier.SYMBOLICNAME, path_version),
+            new Syntax(
+                    RUNPATH,
+                    "Additional JARs for the VM path, should include the framework",
+                    "-runpath=org.eclipse.osgi;version=3.5", null, null,
+                    path_version),
+            new Syntax(
+                    RUNVM,
+                    "Additional arguments for the VM invokation. Keys that start with a - are added as options, otherwise they are treated as -D properties for the VM",
+                    "-runvm=-Xmax=30", null, null),
+            new Syntax(
+                    VERSIONPOLICY,
+                    "Provides a version policy to imports that are calculated from exports",
+                    "-versionpolicy = \"[${version;==;${@}},${version;+;${@}})\"",
+                    null, null)
+
+                                                                 };
+
+    public final static Map<String, Syntax> HELP                 = new HashMap<String, Syntax>();
+
+    static {
+        for (Syntax s : syntaxes) {
+            HELP.put(s.header, s);
+        }
+    }
+
+    public Syntax(String header, String lead, String example, String values,
+            Pattern pattern, Syntax... children) {
+        this.header = header;
+        this.children = children;
+        this.lead = lead;
+        this.example = example;
+        this.values = values;
+        this.pattern = pattern;
+    }
+
+    public String getLead() {
+        return lead;
+    }
+
+    public String getExample() {
+        return example;
+    }
+
+    public String getValues() {
+        return values;
+    }
+
+    public String getPattern() {
+        return lead;
+    }
+
+    public Syntax[] getChildren() {
+        return children;
+    }
+
+    public String getHeader() {
+        return header;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/Make.java b/bundleplugin/src/main/java/aQute/bnd/make/Make.java
new file mode 100644
index 0000000..463556c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/Make.java
@@ -0,0 +1,101 @@
+package aQute.bnd.make;
+
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+public class Make {
+    Builder                               builder;
+    Map<Instruction, Map<String, String>> make;
+
+    public Make(Builder builder) {
+        this.builder = builder;
+        // builder.getPlugins().add(new MakeBnd());
+        // builder.getPlugins().add(new MakeCopy());
+    }
+
+    public Resource process(String source) {
+        Map<Instruction, Map<String, String>> make = getMakeHeader();
+        builder.trace("make " + source);
+
+        for (Map.Entry<Instruction, Map<String, String>> entry : make
+                .entrySet()) {
+            Instruction instr = (Instruction) entry.getKey();
+            Matcher m = instr.getMatcher(source);
+            if (m.matches() || instr.isNegated()) {
+                Map<String, String> arguments = replace(m, entry.getValue());
+                List<MakePlugin> plugins = builder.getPlugins(MakePlugin.class);
+                for (MakePlugin plugin : plugins) {
+                    try {
+                        Resource resource = plugin.make(builder,
+                                source, arguments);
+                        if (resource != null) {
+                            builder.trace("Made " + source + " from args "
+                                    + arguments + " with " + plugin);
+                            return resource;
+                        }
+                    } catch (Exception e) {
+                        builder.error("Plugin " + plugin
+                                + " generates error when use in making "
+                                + source + " with args " + arguments, e);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private Map<String, String> replace(Matcher m, Map<String, String> value) {
+        Map<String, String> newArgs = Processor.newMap();
+        for (Map.Entry<String, String> entry : value.entrySet()) {
+            String s = entry.getValue();
+            s = replace(m, s);
+            newArgs.put(entry.getKey(), s);
+        }
+        return newArgs;
+    }
+
+    String replace(Matcher m, CharSequence s) {
+        StringBuffer sb = new StringBuffer();
+        int max = '0' + m.groupCount() + 1;
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            if (c == '$' && i < s.length() - 1) {
+                c = s.charAt(++i);
+                if (c >= '0' && c <= max) {
+                    int index = c - '0';
+                    String replacement = m.group(index);
+                    if (replacement != null)
+                        sb.append(replacement);
+                } else {
+                    if (c == '$')
+                        i++;
+                    sb.append(c);
+                }
+            } else
+                sb.append(c);
+        }
+        return sb.toString();
+    }
+
+    Map<Instruction, Map<String, String>> getMakeHeader() {
+        if (make != null)
+            return make;
+        make = Processor.newMap();
+
+        String s = builder.getProperty(Builder.MAKE);
+        Map<String, Map<String, String>> make = builder.parseHeader(s);
+        for (Iterator<Map.Entry<String, Map<String, String>>> e = make
+                .entrySet().iterator(); e.hasNext();) {
+            Map.Entry<String, Map<String, String>> entry = e.next();
+            String pattern = Processor.removeDuplicateMarker(entry.getKey());
+            
+            Instruction instr = Instruction.getPattern(pattern);
+            this.make.put(instr, entry.getValue());
+        }
+
+        return this.make;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java b/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java
new file mode 100644
index 0000000..d7ae8ed
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java
@@ -0,0 +1,64 @@
+package aQute.bnd.make;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.build.*;
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+public class MakeBnd implements MakePlugin, Constants {
+    final static Pattern JARFILE = Pattern.compile("(.+)\\.(jar|ipa)");
+
+    public Resource make(Builder builder, String destination,
+            Map<String, String> argumentsOnMake) throws Exception {
+        String type = (String) argumentsOnMake.get("type");
+        if (!"bnd".equals(type))
+            return null;
+
+        String recipe = (String) argumentsOnMake.get("recipe");
+        if (recipe == null) {
+            builder.error("No recipe specified on a make instruction for "
+                    + destination);
+            return null;
+        }
+        File bndfile = builder.getFile(recipe);
+        if (bndfile.isFile()) {
+            // We do not use a parent because then we would
+            // build ourselves again. So we can not blindly
+            // inherit the properties.
+            Builder bchild = builder.getSubBuilder();
+            bchild.removeBundleSpecificHeaders();
+            
+            // We must make sure that we do not include ourselves again!
+            bchild.setProperty(Analyzer.INCLUDE_RESOURCE, "");
+            bchild.setProperties(bndfile, builder.getBase());
+            
+            Jar jar = bchild.build();
+            Jar dot = builder.getTarget();
+
+            if (builder.hasSources()) {
+                for (String key : jar.getResources().keySet()) {
+                    if (key.startsWith("OSGI-OPT/src"))
+                        dot.putResource(key, (Resource) jar.getResource(key));
+                }
+            }
+            builder.getInfo(bchild, bndfile.getName() +": ");
+            String debug = bchild.getProperty(DEBUG);
+            if (Processor.isTrue(debug)) {
+                if ( builder instanceof ProjectBuilder ) {
+                    ProjectBuilder pb = (ProjectBuilder) builder;
+                    File target = pb.getProject().getTarget();
+                    target.mkdirs();
+                    String bsn = bchild.getBsn();
+                    File output = new File(target, bsn+".jar");
+                    jar.write(output);
+                }
+            }
+            return new JarResource(jar);
+        } else
+            return null;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java b/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java
new file mode 100644
index 0000000..3d5e4c8
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java
@@ -0,0 +1,45 @@
+package aQute.bnd.make;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+public class MakeCopy implements MakePlugin {
+
+    public Resource make(Builder builder, String destination,
+            Map<String, String> argumentsOnMake) throws Exception {
+        String type = argumentsOnMake.get("type");
+        if (!type.equals("copy"))
+            return null;
+
+        String from = argumentsOnMake.get("from");
+        if (from == null) {
+            String content = argumentsOnMake.get("content");
+            if (content == null)
+                throw new IllegalArgumentException(
+                        "No 'from' or 'content' field in copy "
+                                + argumentsOnMake);
+            return new EmbeddedResource(content.getBytes("UTF-8"),0);
+        } else {
+
+            File f = builder.getFile(from);
+            if (f.isFile())
+                return new FileResource(f);
+            else {
+                try {
+                    URL url = new URL(from);
+                    return new URLResource(url);
+                } catch(MalformedURLException mfue) {
+                    // We ignore this
+                }
+                throw new IllegalArgumentException(
+                        "Copy source does not exist " + from
+                                + " for destination " + destination);
+            }
+        }
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/ServiceComponent.java b/bundleplugin/src/main/java/aQute/bnd/make/ServiceComponent.java
new file mode 100644
index 0000000..a641c0b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/ServiceComponent.java
@@ -0,0 +1,408 @@
+package aQute.bnd.make;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.filter.*;
+import aQute.lib.osgi.*;
+import aQute.libg.version.*;
+
+/**
+ * This class is an analyzer plugin. It looks at the properties and tries to
+ * find out if the Service-Component header contains the bnd shortut syntax. If
+ * not, the header is copied to the output, if it does, an XML file is created
+ * and added to the JAR and the header is modified appropriately.
+ */
+public class ServiceComponent implements AnalyzerPlugin {
+    public final static String      NAMESPACE_STEM                 = "http://www.osgi.org/xmlns/scr";
+    public final static String      JIDENTIFIER                    = "<<identifier>>";
+    public final static String      COMPONENT_FACTORY              = "factory:";
+    public final static String      COMPONENT_SERVICEFACTORY       = "servicefactory:";
+    public final static String      COMPONENT_IMMEDIATE            = "immediate:";
+    public final static String      COMPONENT_ENABLED              = "enabled:";
+    public final static String      COMPONENT_DYNAMIC              = "dynamic:";
+    public final static String      COMPONENT_MULTIPLE             = "multiple:";
+    public final static String      COMPONENT_PROVIDE              = "provide:";
+    public final static String      COMPONENT_OPTIONAL             = "optional:";
+    public final static String      COMPONENT_PROPERTIES           = "properties:";
+    public final static String      COMPONENT_IMPLEMENTATION       = "implementation:";
+
+    // v1.1.0
+    public final static String      COMPONENT_VERSION              = "version:";
+    public final static String      COMPONENT_CONFIGURATION_POLICY = "configuration-policy:";
+    public final static String      COMPONENT_MODIFIED             = "modified:";
+    public final static String      COMPONENT_ACTIVATE             = "activate:";
+    public final static String      COMPONENT_DEACTIVATE           = "deactivate:";
+
+    public final static String[]    componentDirectives            = new String[] {
+            COMPONENT_FACTORY, COMPONENT_IMMEDIATE, COMPONENT_ENABLED,
+            COMPONENT_DYNAMIC, COMPONENT_MULTIPLE, COMPONENT_PROVIDE,
+            COMPONENT_OPTIONAL, COMPONENT_PROPERTIES, COMPONENT_IMPLEMENTATION,
+            COMPONENT_SERVICEFACTORY, COMPONENT_VERSION,
+            COMPONENT_CONFIGURATION_POLICY, COMPONENT_MODIFIED,
+            COMPONENT_ACTIVATE, COMPONENT_DEACTIVATE       };
+
+    public final static Set<String> SET_COMPONENT_DIRECTIVES       = new HashSet<String>(
+                                                                    Arrays
+                                                                            .asList(componentDirectives));
+
+    public final static Set<String> SET_COMPONENT_DIRECTIVES_1_1   = //
+                                                            new HashSet<String>(
+                                                                    Arrays
+                                                                            .asList(
+                                                                                    COMPONENT_VERSION,
+                                                                                    COMPONENT_CONFIGURATION_POLICY,
+                                                                                    COMPONENT_MODIFIED,
+                                                                                    COMPONENT_ACTIVATE,
+                                                                                    COMPONENT_DEACTIVATE));
+
+    public boolean analyzeJar(Analyzer analyzer) throws Exception {
+
+        ComponentMaker m = new ComponentMaker(analyzer);
+
+        Map<String, Map<String, String>> l = m.doServiceComponent();
+
+        if (!l.isEmpty())
+            analyzer.setProperty(Constants.SERVICE_COMPONENT, Processor
+                    .printClauses(l, ""));
+
+        analyzer.getInfo(m, "Service Component");
+        m.close();
+        return false;
+    }
+
+    private static class ComponentMaker extends Processor {
+        Analyzer analyzer;
+
+        ComponentMaker(Analyzer analyzer) {
+            super(analyzer);
+            this.analyzer = analyzer;
+        }
+
+        Map<String, Map<String, String>> doServiceComponent() throws Exception {
+            String header = getProperty(SERVICE_COMPONENT);
+            return doServiceComponent(header);
+        }
+
+        /**
+         * Check if a service component header is actually referring to a class.
+         * If so, replace the reference with an XML file reference. This makes
+         * it easier to create and use components.
+         * 
+         * @throws UnsupportedEncodingException
+         * 
+         */
+        public Map<String, Map<String, String>> doServiceComponent(
+                String serviceComponent) throws IOException {
+            Map<String, Map<String, String>> list = newMap();
+            Map<String, Map<String, String>> sc = parseHeader(serviceComponent);
+            Map<String, String> empty = Collections.emptyMap();
+
+            for (Iterator<Map.Entry<String, Map<String, String>>> i = sc
+                    .entrySet().iterator(); i.hasNext();) {
+                Map.Entry<String, Map<String, String>> entry = i.next();
+                String name = entry.getKey();
+                Map<String, String> info = entry.getValue();
+                if (name == null) {
+                    error("No name in Service-Component header: " + info);
+                    continue;
+                }
+                if (name.indexOf("*") >= 0 || analyzer.getJar().exists(name)) {
+                    // Normal service component, we do not process them
+                    list.put(name, info);
+                } else {
+                    String impl = name;
+
+                    if (info.containsKey(COMPONENT_IMPLEMENTATION))
+                        impl = info.get(COMPONENT_IMPLEMENTATION);
+
+                    if (!analyzer.checkClass(impl)) {
+                        error("Not found Service-Component header: " + name);
+                    } else {
+                        // We have a definition, so make an XML resources
+                        Resource resource = createComponentResource(name, info);
+                        analyzer.getJar().putResource(
+                                "OSGI-INF/" + name + ".xml", resource);
+                        list.put("OSGI-INF/" + name + ".xml", empty);
+                    }
+                }
+            }
+            return list;
+        }
+
+        /**
+         * Create the resource for a DS component.
+         * 
+         * @param list
+         * @param name
+         * @param info
+         * @throws UnsupportedEncodingException
+         */
+        Resource createComponentResource(String name, Map<String, String> info)
+                throws IOException {
+            String namespace = getNamespace(info);
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            PrintWriter pw = new PrintWriter(new OutputStreamWriter(out,
+                    "UTF-8"));
+            pw.println("<?xml version='1.0' encoding='utf-8'?>");
+            pw.print("<component name='" + name + "'");
+            if (namespace != null) {
+                pw.print(" xmlns='" + namespace + "'");
+            }
+
+            doAttribute(pw, info.get(COMPONENT_FACTORY), "factory");
+            doAttribute(pw, info.get(COMPONENT_IMMEDIATE), "immediate",
+                    "false", "true");
+            doAttribute(pw, info.get(COMPONENT_ENABLED), "enabled", "true",
+                    "false");
+            doAttribute(pw, info.get(COMPONENT_CONFIGURATION_POLICY),
+                    "configuration-policy", "optional", "require", "ignore");
+            doAttribute(pw, info.get(COMPONENT_ACTIVATE), "activate",
+                    JIDENTIFIER);
+            doAttribute(pw, info.get(COMPONENT_DEACTIVATE), "deactivate",
+                    JIDENTIFIER);
+            doAttribute(pw, info.get(COMPONENT_MODIFIED), "modified",
+                    JIDENTIFIER);
+
+            pw.println(">");
+
+            // Allow override of the implementation when people
+            // want to choose their own name
+            String impl = (String) info.get(COMPONENT_IMPLEMENTATION);
+            pw.println("  <implementation class='"
+                    + (impl == null ? name : impl) + "'/>");
+
+            String provides = info.get(COMPONENT_PROVIDE);
+            boolean servicefactory = Boolean.getBoolean(info
+                    .get(COMPONENT_SERVICEFACTORY)
+                    + "");
+            provides(pw, provides, servicefactory);
+            properties(pw, info);
+            reference(info, pw);
+            pw.println("</component>");
+            pw.close();
+            byte[] data = out.toByteArray();
+            out.close();
+            return new EmbeddedResource(data, 0);
+        }
+
+        private void doAttribute(PrintWriter pw, String value, String name,
+                String... matches) {
+            if (value != null) {
+                if (matches.length != 0) {
+                    if (matches.length == 1 && matches[0].equals(JIDENTIFIER)) {
+                        if (!Verifier.isIdentifier(value))
+                            error(
+                                    "Component attribute %s has value %s but is not a Java identifier",
+                                    name, value);
+                    } else {
+
+                        if (!Verifier.isMember(value, matches))
+                            error(
+                                    "Component attribute %s has value %s but is not a member of %s",
+                                    name, value, Arrays.toString(matches));
+                    }
+                }
+                pw.print(" ");
+                pw.print(name);
+                pw.print("='");
+                pw.print(value);
+                pw.print("'");
+            }
+        }
+
+        /**
+         * Check if we need to use the v1.1 namespace (or later).
+         * 
+         * @param info
+         * @return
+         */
+        private String getNamespace(Map<String, String> info) {
+            String version = info.get(COMPONENT_VERSION);
+            if (version != null) {
+                try {
+                    Version v = new Version(version);
+                    return NAMESPACE_STEM + "/v" + v;
+                } catch (Exception e) {
+                    error("version: specified on component header but not a valid version: "
+                            + version);
+                    return null;
+                }
+            }
+            for (String key : info.keySet()) {
+                if (SET_COMPONENT_DIRECTIVES_1_1.contains(key)) {
+                    return NAMESPACE_STEM + "/v1.1.0";
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Print the Service-Component properties element
+         * 
+         * @param pw
+         * @param info
+         */
+        void properties(PrintWriter pw, Map<String, String> info) {
+            Collection<String> properties = split(info
+                    .get(COMPONENT_PROPERTIES));
+            for (Iterator<String> p = properties.iterator(); p.hasNext();) {
+                String clause = p.next();
+                int n = clause.indexOf('=');
+                if (n <= 0) {
+                    error("Not a valid property in service component: "
+                            + clause);
+                } else {
+                    String type = null;
+                    String name = clause.substring(0, n);
+                    if (name.indexOf('@') >= 0) {
+                        String parts[] = name.split("@");
+                        name = parts[1];
+                        type = parts[0];
+                    }
+                    String value = clause.substring(n + 1).trim();
+                    // TODO verify validity of name and value.
+                    pw.print("<property name='");
+                    pw.print(name);
+                    pw.print("'");
+
+                    if (type != null) {
+                        if (VALID_PROPERTY_TYPES.matcher(type).matches()) {
+                            pw.print(" type='");
+                            pw.print(type);
+                            pw.print("'");
+                        } else {
+                            warning("Invalid property type '" + type
+                                    + "' for property " + name);
+                        }
+                    }
+
+                    String parts[] = value.split("\\s*(\\||\\n)\\s*");
+                    if (parts.length > 1) {
+                        pw.println(">");
+                        for (String part : parts) {
+                            pw.println(part);
+                        }
+                        pw.println("</property>");
+                    } else {
+                        pw.print(" value='");
+                        pw.print(parts[0]);
+                        pw.print("'/>");
+                    }
+                }
+            }
+        }
+
+        /**
+         * @param pw
+         * @param provides
+         */
+        void provides(PrintWriter pw, String provides, boolean servicefactory) {
+            if (provides != null) {
+                if (!servicefactory)
+                    pw.println("  <service>");
+                else
+                    pw.println("  <service servicefactory='true'>");
+
+                StringTokenizer st = new StringTokenizer(provides, ",");
+                while (st.hasMoreTokens()) {
+                    String interfaceName = st.nextToken();
+                    pw.println("    <provide interface='" + interfaceName
+                            + "'/>");
+                    if (!analyzer.checkClass(interfaceName))
+                        error("Component definition provides a class that is neither imported nor contained: "
+                                + interfaceName);
+                }
+                pw.println("  </service>");
+            }
+        }
+
+        public final static Pattern REFERENCE = Pattern.compile("([^(]+)(\\(.+\\))?");
+
+        /**
+         * @param info
+         * @param pw
+         */
+
+        void reference(Map<String, String> info, PrintWriter pw) {
+            Collection<String> dynamic = new ArrayList<String>(split(info.get(COMPONENT_DYNAMIC)));
+            Collection<String> optional =  new ArrayList<String>(split(info.get(COMPONENT_OPTIONAL)));
+            Collection<String> multiple = new ArrayList<String>(split(info.get(COMPONENT_MULTIPLE)));
+
+            for (Iterator<Map.Entry<String, String>> r = info.entrySet()
+                    .iterator(); r.hasNext();) {
+                Map.Entry<String, String> ref = r.next();
+                String referenceName = (String) ref.getKey();
+                String target = null;
+                String interfaceName = (String) ref.getValue();
+                if (interfaceName == null || interfaceName.length() == 0) {
+                    error("Invalid Interface Name for references in Service Component: "
+                            + referenceName + "=" + interfaceName);
+                }
+                char c = interfaceName.charAt(interfaceName.length() - 1);
+                if ("?+*~".indexOf(c) >= 0) {
+                    if (c == '?' || c == '*' || c == '~')
+                        optional.add(referenceName);
+                    if (c == '+' || c == '*')
+                        multiple.add(referenceName);
+                    if (c == '+' || c == '*' || c == '?')
+                        dynamic.add(referenceName);
+                    interfaceName = interfaceName.substring(0, interfaceName
+                            .length() - 1);
+                }
+
+                if (referenceName.endsWith(":")) {
+                    if (!SET_COMPONENT_DIRECTIVES.contains(referenceName))
+                        error("Unrecognized directive in Service-Component header: "
+                                + referenceName);
+                    continue;
+                }
+
+                Matcher m = REFERENCE.matcher(interfaceName);
+                if (m.matches()) {
+                    interfaceName = m.group(1);
+                    target = m.group(2);
+                }
+
+                if (!analyzer.checkClass(interfaceName))
+                    error("Component definition refers to a class that is neither imported nor contained: "
+                            + interfaceName);
+
+                pw.print("  <reference name='" + referenceName
+                        + "' interface='" + interfaceName + "'");
+
+                String cardinality = optional.contains(referenceName) ? "0"
+                        : "1";
+                cardinality += "..";
+                cardinality += multiple.contains(referenceName) ? "n" : "1";
+                if (!cardinality.equals("1..1"))
+                    pw.print(" cardinality='" + cardinality + "'");
+
+                if (Character.isLowerCase(referenceName.charAt(0))) {
+                    String z = referenceName.substring(0, 1).toUpperCase()
+                            + referenceName.substring(1);
+                    pw.print(" bind='set" + z + "'");
+                    pw.print(" unbind='unset" + z + "'");
+                    // TODO Verify that the methods exist
+                }
+
+                if (dynamic.contains(referenceName)) {
+                    pw.print(" policy='dynamic'");
+                }
+
+                if (target != null) {
+                    Filter filter = new Filter(target);
+                    if (filter.verify() == null)
+                        pw.print(" target='" + filter.toString() + "'");
+                    else
+                        error("Target for " + referenceName
+                                + " is not a correct filter: " + target + " "
+                                + filter.verify());
+                }
+                pw.println("/>");
+            }
+        }
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/AnalyzerPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/AnalyzerPlugin.java
new file mode 100644
index 0000000..3efe8ee
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/AnalyzerPlugin.java
@@ -0,0 +1,20 @@
+package aQute.bnd.service;
+
+import aQute.lib.osgi.*;
+
+public interface AnalyzerPlugin {
+
+    /**
+     * This plugin is called after analysis. The plugin is free to modify the
+     * jar and/or change the classpath information (see referred, contained).
+     * This plugin is called after analysis of the JAR but before manifest
+     * generation.
+     * 
+     * @param analyzer
+     * @return true if the classpace has been modified so that the bundle
+     *         classpath must be reanalyzed
+     * @throws Exception
+     */
+
+    boolean analyzeJar(Analyzer analyzer) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/MakePlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/MakePlugin.java
new file mode 100644
index 0000000..20a1849
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/MakePlugin.java
@@ -0,0 +1,21 @@
+package aQute.bnd.service;
+
+import java.util.*;
+
+import aQute.lib.osgi.*;
+
+public interface MakePlugin {
+
+    /**
+     * This plugin is called when Include-Resource detects a reference to a resource
+     * that it can not find in the file system.
+     * 
+     * @param builder   The current builder
+     * @param source    The source string (i.e. the place where bnd looked)
+     * @param arguments Any arguments on the clause in Include-Resource
+     * @return          A resource or null if no resource could be made
+     * @throws Exception
+     */
+    Resource make(Builder builder, String source, Map<String,String> arguments) throws Exception;
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/Plugin.java b/bundleplugin/src/main/java/aQute/bnd/service/Plugin.java
new file mode 100644
index 0000000..065fac8
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/Plugin.java
@@ -0,0 +1,31 @@
+package aQute.bnd.service;
+
+import java.util.*;
+
+import aQute.libg.reporter.*;
+
+/**
+ * An optional interface for plugins. If a plugin implements this interface then
+ * it can receive the reminaing attributes and directives given in its clause as
+ * well as the reporter to use.
+ * 
+ */
+public interface Plugin {
+    /**
+     * Give the plugin the remaining properties.
+     * 
+     * When a plugin is declared, the clause can contain extra properties.
+     * All the properties and directives are given to the plugin to use.
+     * 
+     * @param map attributes and directives for this plugin's clause
+     */
+    void setProperties(Map<String,String> map);
+    
+    /**
+     * Set the current reporter. This is called at init time. This plugin
+     * should report all errors and warnings to this reporter.
+     * 
+     * @param processor
+     */
+    void setReporter(Reporter processor);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/Refreshable.java b/bundleplugin/src/main/java/aQute/bnd/service/Refreshable.java
new file mode 100644
index 0000000..e5e62e9
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/Refreshable.java
@@ -0,0 +1,8 @@
+package aQute.bnd.service;
+
+import java.io.*;
+
+public interface Refreshable {
+    boolean refresh();
+    File getRoot();
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java
new file mode 100644
index 0000000..14282ec
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java
@@ -0,0 +1,59 @@
+package aQute.bnd.service;
+
+import java.io.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+import aQute.libg.version.*;
+
+public interface RepositoryPlugin {
+    /**
+     * Return a URL to a matching version of the given bundle.
+     * 
+     * @param bsn
+     *            Bundle-SymbolicName of the searched bundle
+     * @param range
+     *            Version range for this bundle,"latest" if you only want the
+     *            latest, or null when you want all.
+     * @return A list of URLs sorted on version, lowest version is at index 0.
+     *         null is returned when no files with the given bsn ould be found.
+     * @throws Exception
+     *             when anything goes wrong
+     */
+    File[] get(String bsn, String range) throws Exception;
+    
+    /**
+     * Answer if this repository can be used to store files.
+     * 
+     * @return true if writable
+     */
+    boolean canWrite();
+    
+    /**
+     * Put a JAR file in the repository.
+     * 
+     * @param jar
+     * @throws Exception
+     */
+    File  put(Jar jar) throws Exception;
+    
+    /**
+     * Return a list of bsns that are present in the repository.
+     * 
+     * @param regex if not null, match against the bsn and if matches, return otherwise skip
+     * @return A list of bsns that match the regex parameter or all if regex is null
+     */
+    List<String> list(String regex);
+    
+    /**
+     * Return a list of versions.
+     */
+    
+    List<Version> versions(String bsn);
+    
+    /**
+     * @return The name of the repository
+     */
+    String getName();
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/SignerPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/SignerPlugin.java
new file mode 100644
index 0000000..aaef646
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/SignerPlugin.java
@@ -0,0 +1,15 @@
+package aQute.bnd.service;
+
+import aQute.lib.osgi.*;
+
+public interface SignerPlugin {
+    /**
+     * Sign the current jar. The alias is the given certificate 
+     * keystore.
+     * 
+     * @param builder   The current builder that contains the jar to sign
+     * @param alias     The keystore certificate alias
+     * @throws Exception When anything goes wrong
+     */
+    void sign(Builder builder, String alias) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/action/Action.java b/bundleplugin/src/main/java/aQute/bnd/service/action/Action.java
new file mode 100644
index 0000000..9fd42ed
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/action/Action.java
@@ -0,0 +1,25 @@
+package aQute.bnd.service.action;
+
+import aQute.bnd.build.*;
+
+public interface Action {
+    /**
+     * A String[] that specifies a menu entry. The entry
+     * can be hierarchical by separating the parts with a ':'.
+     * 
+     * <pre>
+     *  A:B:C
+     *  A:B:D
+     *  
+     *      A
+     *      |
+     *      B
+     *     / \
+     *    C   D
+     *    
+     * </pre>
+     */
+    String ACTION_MENU  = "bnd.action.menu";
+
+    void execute( Project project, String action) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/test/ProjectLauncher.java b/bundleplugin/src/main/java/aQute/bnd/test/ProjectLauncher.java
new file mode 100644
index 0000000..dd3f117
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/test/ProjectLauncher.java
@@ -0,0 +1,336 @@
+package aQute.bnd.test;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.build.*;
+import aQute.lib.osgi.*;
+import aQute.libg.header.*;
+
+public class ProjectLauncher extends Processor {
+    final Project project;
+    static File   runtime;
+    String        report;
+
+    public ProjectLauncher(Project project) {
+        super(project);
+        this.project = project;
+    }
+
+    /**
+     * Calculate the classpath. We include our own runtime.jar which includes
+     * the test framework and we include the first of the test frameworks
+     * specified.
+     */
+    public String[] getClasspath() {
+        try {
+            List<String> classpath = new ArrayList<String>();
+            classpath.add(getRuntime().getAbsolutePath());
+
+            for (Container c : project.getRunpath()) {
+                if (c.getType() != Container.TYPE.ERROR) {
+                    if (!c.getFile().getName().startsWith("ee."))
+                        classpath.add(c.getFile().getAbsolutePath());
+                } else {
+                    error("Invalid entry on the " + Constants.RUNPATH + ": "
+                            + c);
+                }
+            }
+            return classpath.toArray(new String[classpath.size()]);
+        } catch (Exception e) {
+            error("Calculating class path", e);
+        }
+        return null;
+    }
+
+    /**
+     * Extract the runtime on the file system so we can refer to it. in the
+     * remote VM.
+     * 
+     * @return
+     */
+    public static File getRuntime() {
+        if (runtime == null) {
+            try {
+                URL url = ProjectLauncher.class
+                        .getResource("aQute.runtime.jar");
+                if (url == null)
+                    throw new IllegalStateException(
+                            "Can not find my runtime.jar");
+
+                runtime = File.createTempFile("aQute.runtime", ".jar");
+                // runtime.deleteOnExit();
+                FileOutputStream out = new FileOutputStream(runtime);
+                InputStream in = url.openStream();
+                copy(in, out);
+                out.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return runtime;
+    }
+
+    public void doRunbundles(List<String> programArguments) throws Exception {
+        // we are going to use this for running, so we want to
+        // use the "best" version. For compile, we should
+        // use the lowest version.
+        Collection<Container> testbundles = project.getRunbundles();
+
+        for (Container c : testbundles) {
+            if (c.getError() != null)
+                error("Invalid bundle on " + Constants.RUNBUNDLES + " "
+                        + c.getError());
+            else {
+                // Do we need to build any sub projects?
+                if (c.getVersion() != null && c.getVersion().equals("project")) {
+                    Project sub = c.getProject();
+                    sub.clear();
+                    File[] outputs = sub.build(false);
+                    for (File f : outputs) {
+                        programArguments.add("-bundle");
+                        programArguments.add(f.getAbsolutePath());
+                    }
+                    getInfo(sub);
+                } else {
+                    programArguments.add("-bundle");
+                    programArguments.add(c.getFile().getAbsolutePath());
+                }
+            }
+        }
+    }
+
+    private void doRunpath(List<String> programArguments) throws Exception {
+        Collection<Container> testpath = project.getRunpath();
+        Container found = null;
+        for (Container c : testpath) {
+            if (c.getAttributes().containsKey("framework")) {
+                if (found != null) {
+                    warning("Specifying multiple framework classes on the "
+                            + Constants.RUNPATH + "\n" + "Previous found: "
+                            + found.getProject() + " " + found.getAttributes()
+                            + "\n" + "Now found     : " + c.getProject() + " "
+                            + c.getAttributes());
+                }
+                programArguments.add("-framework");
+                programArguments.add(c.getAttributes().get("framework"));
+                found = c;
+            }
+            if (c.getAttributes().containsKey("factory")) {
+                if (found != null) {
+                    warning("Specifying multiple framework factories on the "
+                            + Constants.RUNPATH + "\n" + "Previous found: "
+                            + found.getProject() + " " + found.getAttributes()
+                            + "\n" + "Now found     : " + c.getProject() + " "
+                            + c.getAttributes());
+                }
+                programArguments.add("-framework");
+                programArguments.add(c.getAttributes().get("factory"));
+                found = c;
+            }
+            String exports = c.getAttributes().get("export");
+            if (exports != null) {
+                String parts[] = exports.split("\\s*,\\s*");
+                for (String p : parts) {
+                    programArguments.add("-export");
+                    programArguments.add(p);
+                }
+            }
+        }
+
+        doSystemPackages(programArguments);
+        doRunProperties(programArguments);
+    }
+
+    private void doRunProperties(List<String> programArguments) {
+        Map<String, String> properties = OSGiHeader
+                .parseProperties(getProperty(RUNPROPERTIES));
+        for (Map.Entry<String, String> entry : properties.entrySet()) {
+            programArguments.add("-set");
+            programArguments.add(entry.getKey());
+            programArguments.add(entry.getValue());
+        }
+    }
+
+    private void doSystemPackages(List<String> programArguments) {
+        Map<String, Map<String, String>> systemPackages = parseHeader(getProperty(RUNSYSTEMPACKAGES));
+        for (Map.Entry<String, Map<String, String>> entry : systemPackages
+                .entrySet()) {
+            programArguments.add("-export");
+            StringBuffer sb = new StringBuffer();
+            sb.append(entry.getKey());
+            printClause(entry.getValue(), null, sb);
+            programArguments.add(sb.toString());
+        }
+    }
+
+    private void doStorage(List<String> programArguments) throws Exception {
+        File tmp = new File(project.getTarget(), "fwtmp");
+        tmp.mkdirs();
+        tmp.deleteOnExit();
+
+        programArguments.add("-storage");
+        programArguments.add(tmp.getAbsolutePath());
+    }
+
+    /**
+     * Utility to copy a file from a resource.
+     * 
+     * @param in
+     * @param out
+     * @throws IOException
+     */
+    private static void copy(InputStream in, FileOutputStream out)
+            throws IOException {
+        byte buf[] = new byte[8192];
+        int size = in.read(buf);
+        while (size > 0) {
+            out.write(buf, 0, size);
+            size = in.read(buf);
+        }
+        in.close();
+    }
+
+    private Process launch(File[] targets) throws Exception {
+        List<String> arguments = newList();
+        List<String> vmArguments = newList();
+
+        vmArguments.add(getProperty("java", "java"));
+        doClasspath(vmArguments);
+
+        getArguments(targets, vmArguments, arguments);
+
+        vmArguments.add("aQute.junit.runtime.Target");
+        arguments.add("-report");
+        arguments.add(getTestreport());
+
+        List<String> all = newList();
+        all.addAll(vmArguments);
+        all.addAll(arguments);
+
+        System.out.println("Cmd: " + all);
+
+        String[] cmdarray = all.toArray(new String[all.size()]);
+        if (getErrors().size() > 0)
+            return null;
+
+        return Runtime.getRuntime().exec(cmdarray, null, project.getBase());
+    }
+/*
+    static Pattern ARGUMENT = Pattern.compile("[-a-zA-Z0-9\\._]+");
+    private void doVMArguments(List<String> arguments) {
+        Map<String,String> map = OSGiHeader.parseProperties( getProperty(RUNVM));
+        for ( String key : map.keySet() ) {
+            if ( ARGUMENT.matcher(key).matches())
+                if ( key.startsWith("-"))
+                    arguments.add(key);
+                else
+                    arguments.add("-D" + key.trim() + "=" + map.get(key));
+            else
+                warning("VM Argument is not a proper property key: " + key );
+        }
+    }
+*/
+    private void doVMArguments(List<String> arguments) {
+        Map<String, String> map = OSGiHeader
+                .parseProperties(getProperty(RUNVM));
+        for (String key : map.keySet()) {
+            if (key.startsWith("-"))
+                arguments.add(key);
+            else
+                arguments.add("-D" + key.trim() + "=" + map.get(key));
+        }
+    }
+    private void doClasspath(List<String> arguments) {
+        Collection<String> cp = Arrays.asList(getClasspath());
+        if (!cp.isEmpty()) {
+            arguments.add("-classpath");
+            arguments.add(join(cp, File.pathSeparator));
+        }
+    }
+
+    public int run(File f) throws Exception {
+        final Process process = launch(new File[] { f });
+
+        Thread killer = new Thread() {
+            public void run() {
+                process.destroy();
+            }
+        };
+        Runtime.getRuntime().addShutdownHook(killer);
+        Streamer sin = new Streamer(process.getInputStream(), System.out);
+        Streamer serr = new Streamer(process.getErrorStream(), System.out);
+        try {
+            sin.start();
+            serr.start();
+            return process.waitFor();
+        } finally {
+            Runtime.getRuntime().removeShutdownHook(killer);
+            sin.join();
+            serr.join();
+        }
+    }
+
+    static class Streamer extends Thread {
+        final InputStream  in;
+        final OutputStream out;
+
+        Streamer(InputStream in, OutputStream out) {
+            this.in = in;
+            this.out = out;
+        }
+
+        public void run() {
+            try {
+                int c;
+                while ((c = in.read()) > 0) {
+                    this.out.write(c);
+                }
+            } catch (IOException ioe) {
+                // Ignore
+            }
+        };
+
+    };
+
+    public String getTestreport() {
+        if (report != null)
+            return report;
+        return report = getProperty(Constants.TESTREPORT,
+                "${target}/test-report.xml");
+
+    }
+
+    public void getArguments(List<String> vmArguments,
+            List<String> programArguments, boolean undertest) throws Exception {
+        File files[] = project.build(undertest);
+        getInfo(project);
+        if (files == null)
+            return;
+
+        getArguments(files, vmArguments, programArguments);
+    }
+
+    public void getArguments(File files[], List<String> vmArguments,
+            List<String> programArguments) throws Exception {
+        doVMArguments(vmArguments);
+        doStorage(programArguments);
+        doRunpath(programArguments);
+        doRunbundles(programArguments);
+        for (File file : files) {
+            programArguments.add("-target");
+            programArguments.add(file.getAbsolutePath());
+        }
+    }
+
+    public String getReport() {
+        return report;
+    }
+
+    public void setReport(String report) {
+        this.report = report;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/filter/Filter.java b/bundleplugin/src/main/java/aQute/lib/filter/Filter.java
new file mode 100644
index 0000000..e505a81
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/filter/Filter.java
@@ -0,0 +1,353 @@
+/**
+ * Copyright (c) 2000 Gatespace AB. All Rights Reserved.
+ *
+ * Gatespace grants Open Services Gateway Initiative (OSGi) an irrevocable,
+ * perpetual, non-exclusive, worldwide, paid-up right and license to
+ * reproduce, display, perform, prepare and have prepared derivative works
+ * based upon and distribute and sublicense this material and derivative
+ * works thereof as set out in the OSGi MEMBER AGREEMENT as of January 24
+ * 2000, for use in accordance with Section 2.2 of the BY-LAWS of the
+ * OSGi MEMBER AGREEMENT.
+ */
+
+package aQute.lib.filter;
+
+import java.lang.reflect.*;
+import java.math.*;
+import java.util.*;
+
+public class Filter {
+    final char     WILDCARD = 65535;
+
+    final int      EQ       = 0;
+    final int      LE       = 1;
+    final int      GE       = 2;
+    final int      APPROX   = 3;
+
+    private String filter;
+
+    abstract class Query {
+        static final String GARBAGE   = "Trailing garbage";
+        static final String MALFORMED = "Malformed query";
+        static final String EMPTY     = "Empty list";
+        static final String SUBEXPR   = "No subexpression";
+        static final String OPERATOR  = "Undefined operator";
+        static final String TRUNCATED = "Truncated expression";
+        static final String EQUALITY  = "Only equality supported";
+
+        private String      tail;
+
+        boolean match() throws IllegalArgumentException {
+            tail = filter;
+            boolean val = doQuery();
+            if (tail.length() > 0)
+                error(GARBAGE);
+            return val;
+        }
+
+        private boolean doQuery() throws IllegalArgumentException {
+            if (tail.length() < 3 || !prefix("("))
+                error(MALFORMED);
+            boolean val;
+
+            switch (tail.charAt(0)) {
+            case '&':
+                val = doAnd();
+                break;
+            case '|':
+                val = doOr();
+                break;
+            case '!':
+                val = doNot();
+                break;
+            default:
+                val = doSimple();
+                break;
+            }
+
+            if (!prefix(")"))
+                error(MALFORMED);
+            return val;
+        }
+
+        private boolean doAnd() throws IllegalArgumentException {
+            tail = tail.substring(1);
+            boolean val = true;
+            if (!tail.startsWith("("))
+                error(EMPTY);
+            do {
+                if (!doQuery())
+                    val = false;
+            } while (tail.startsWith("("));
+            return val;
+        }
+
+        private boolean doOr() throws IllegalArgumentException {
+            tail = tail.substring(1);
+            boolean val = false;
+            if (!tail.startsWith("("))
+                error(EMPTY);
+            do {
+                if (doQuery())
+                    val = true;
+            } while (tail.startsWith("("));
+            return val;
+        }
+
+        private boolean doNot() throws IllegalArgumentException {
+            tail = tail.substring(1);
+            if (!tail.startsWith("("))
+                error(SUBEXPR);
+            return !doQuery();
+        }
+
+        private boolean doSimple() throws IllegalArgumentException {
+            int op = 0;
+            Object attr = getAttr();
+
+            if (prefix("="))
+                op = EQ;
+            else if (prefix("<="))
+                op = LE;
+            else if (prefix(">="))
+                op = GE;
+            else if (prefix("~="))
+                op = APPROX;
+            else
+                error(OPERATOR);
+
+            return compare(attr, op, getValue());
+        }
+
+        private boolean prefix(String pre) {
+            if (!tail.startsWith(pre))
+                return false;
+            tail = tail.substring(pre.length());
+            return true;
+        }
+
+        private Object getAttr() {
+            int len = tail.length();
+            int ix = 0;
+            label: for (; ix < len; ix++) {
+                switch (tail.charAt(ix)) {
+                case '(':
+                case ')':
+                case '<':
+                case '>':
+                case '=':
+                case '~':
+                case '*':
+                case '\\':
+                    break label;
+                }
+            }
+            String attr = tail.substring(0, ix).toLowerCase();
+            tail = tail.substring(ix);
+            return getProp(attr);
+        }
+
+        abstract Object getProp(String key);
+
+        private String getValue() {
+            StringBuffer sb = new StringBuffer();
+            int len = tail.length();
+            int ix = 0;
+            label: for (; ix < len; ix++) {
+                char c = tail.charAt(ix);
+                switch (c) {
+                case '(':
+                case ')':
+                    break label;
+                case '*':
+                    sb.append(WILDCARD);
+                    break;
+                case '\\':
+                    if (ix == len - 1)
+                        break label;
+                    sb.append(tail.charAt(++ix));
+                    break;
+                default:
+                    sb.append(c);
+                    break;
+                }
+            }
+            tail = tail.substring(ix);
+            return sb.toString();
+        }
+
+        private void error(String m) throws IllegalArgumentException {
+            throw new IllegalArgumentException(m + " " + tail);
+        }
+
+        private boolean compare(Object obj, int op, String s) {
+            if (obj == null)
+                return false;
+            try {
+                Class<?> numClass = obj.getClass();
+                if (numClass == String.class) {
+                    return compareString((String) obj, op, s);
+                } else if (numClass == Character.class) {
+                    return compareString(obj.toString(), op, s);
+                } else if (numClass == Long.class) {
+                    return compareSign(op, Long.valueOf(s)
+                            .compareTo((Long) obj));
+                } else if (numClass == Integer.class) {
+                    return compareSign(op, Integer.valueOf(s).compareTo(
+                            (Integer) obj));
+                } else if (numClass == Short.class) {
+                    return compareSign(op, Short.valueOf(s).compareTo(
+                            (Short) obj));
+                } else if (numClass == Byte.class) {
+                    return compareSign(op, Byte.valueOf(s)
+                            .compareTo((Byte) obj));
+                } else if (numClass == Double.class) {
+                    return compareSign(op, Double.valueOf(s).compareTo(
+                            (Double) obj));
+                } else if (numClass == Float.class) {
+                    return compareSign(op, Float.valueOf(s).compareTo(
+                            (Float) obj));
+                } else if (numClass == Boolean.class) {
+                    if (op != EQ)
+                        return false;
+                    int a = Boolean.valueOf(s).booleanValue() ? 1 : 0;
+                    int b = ((Boolean) obj).booleanValue() ? 1 : 0;
+                    return compareSign(op, a - b);
+                } else if (numClass == BigInteger.class) {
+                    return compareSign(op, new BigInteger(s)
+                            .compareTo((BigInteger) obj));
+                } else if (numClass == BigDecimal.class) {
+                    return compareSign(op, new BigDecimal(s)
+                            .compareTo((BigDecimal) obj));
+                } else if (obj instanceof Collection) {
+                    for (Object x : (Collection<?>) obj)
+                        if (compare(x, op, s))
+                            return true;
+                } else if (numClass.isArray()) {
+                    int len = Array.getLength(obj);
+                    for (int i = 0; i < len; i++)
+                        if (compare(Array.get(obj, i), op, s))
+                            return true;
+                }
+            } catch (Exception e) {
+            }
+            return false;
+        }
+    }
+
+    class DictQuery extends Query {
+        private Dictionary<?,?> dict;
+
+        DictQuery(Dictionary<?,?> dict) {
+            this.dict = dict;
+        }
+
+        Object getProp(String key) {
+            return dict.get(key);
+        }
+    }
+
+    public Filter(String filter) throws IllegalArgumentException {
+        // NYI: Normalize the filter string?
+        this.filter = filter;
+        if (filter == null || filter.length() == 0)
+            throw new IllegalArgumentException("Null query");
+    }
+
+    public boolean match(Dictionary<?,?> dict) {
+        try {
+            return new DictQuery(dict).match();
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+    }
+
+    public String verify() {
+        try {
+            new DictQuery(new Hashtable<Object,Object>()).match();
+        } catch (IllegalArgumentException e) {
+            return e.getMessage();
+        }
+        return null;
+    }
+
+    public String toString() {
+        return filter;
+    }
+
+    public boolean equals(Object obj) {
+        return obj != null && obj instanceof Filter
+                && filter.equals(((Filter) obj).filter);
+    }
+
+    public int hashCode() {
+        return filter.hashCode();
+    }
+
+    boolean compareString(String s1, int op, String s2) {
+        switch (op) {
+        case EQ:
+            return patSubstr(s1, s2);
+        case APPROX:
+            return fixupString(s2).equals(fixupString(s1));
+        default:
+            return compareSign(op, s2.compareTo(s1));
+        }
+    }
+
+    boolean compareSign(int op, int cmp) {
+        switch (op) {
+        case LE:
+            return cmp >= 0;
+        case GE:
+            return cmp <= 0;
+        case EQ:
+            return cmp == 0;
+        default: /* APPROX */
+            return cmp == 0;
+        }
+    }
+
+    String fixupString(String s) {
+        StringBuffer sb = new StringBuffer();
+        int len = s.length();
+        boolean isStart = true;
+        boolean isWhite = false;
+        for (int i = 0; i < len; i++) {
+            char c = s.charAt(i);
+            if (Character.isWhitespace(c)) {
+                isWhite = true;
+            } else {
+                if (!isStart && isWhite)
+                    sb.append(' ');
+                if (Character.isUpperCase(c))
+                    c = Character.toLowerCase(c);
+                sb.append(c);
+                isStart = false;
+                isWhite = false;
+            }
+        }
+        return sb.toString();
+    }
+
+    boolean patSubstr(String s, String pat) {
+        if (s == null)
+            return false;
+        if (pat.length() == 0)
+            return s.length() == 0;
+        if (pat.charAt(0) == WILDCARD) {
+            pat = pat.substring(1);
+            for (;;) {
+                if (patSubstr(s, pat))
+                    return true;
+                if (s.length() == 0)
+                    return false;
+                s = s.substring(1);
+            }
+        } else {
+            if (s.length() == 0 || s.charAt(0) != pat.charAt(0))
+                return false;
+            return patSubstr(s.substring(1), pat.substring(1));
+        }
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/About.java b/bundleplugin/src/main/java/aQute/lib/osgi/About.java
new file mode 100644
index 0000000..52a2529
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/About.java
@@ -0,0 +1,48 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+/**
+ * This package contains a number of classes that assists by analyzing JARs and
+ * constructing bundles.
+ * 
+ * The Analyzer class can be used to analyze an existing bundle and can create a
+ * manifest specification from proposed (wildcard) Export-Package,
+ * Bundle-Includes, and Import-Package headers.
+ * 
+ * The Builder class can use the headers to construct a JAR from the classpath.
+ * 
+ * The Verifier class can take an existing JAR and verify that all headers are
+ * correctly set. It will verify the syntax of the headers, match it against the
+ * proper contents, and verify imports and exports.
+ * 
+ * A number of utility classes are available.
+ * 
+ * Jar, provides an abstraction of a Jar file. It has constructors for creating
+ * a Jar from a stream, a directory, or a jar file. A Jar, keeps a collection
+ * Resource's. There are Resource implementations for File, from ZipFile, or from
+ * a stream (which copies the data). The Jar tries to minimize the work during
+ * build up so that it is cheap to use. The Resource's can be used to iterate 
+ * over the names and later read the resources when needed.
+ * 
+ * Clazz, provides a parser for the class files. This will be used to define the
+ * imports and exports.
+ * 
+ * A key component in this library is the Map. Headers are translated to Maps of Maps. OSGi
+ * header syntax is like:
+ * <pre>
+ * 	  header = clause ( ',' clause ) *
+ *    clause = file ( ';' file ) * ( parameter ) *
+ *    param  = attr '=' value | directive ':=' value
+ * </pre>
+ * These headers are translated to a Map that contains all headers (the order is
+ * maintained). Each additional file in a header definition will have its own
+ * entry (only native code does not work this way). The clause is represented
+ * as another map. The ':' of directives is considered part of the name. This
+ * allows attributes and directives to be maintained in the clause map. 
+ * 
+ * @version $Revision: 1.1 $
+ */
+public class About {
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/AbstractResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/AbstractResource.java
new file mode 100644
index 0000000..532b33e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/AbstractResource.java
@@ -0,0 +1,50 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+
+public abstract class AbstractResource implements Resource {
+    String extra;
+    byte[] calculated;
+    long   lastModified;
+
+    protected AbstractResource(long modified) {
+        lastModified = modified;
+    }
+
+    public String getExtra() {
+        return extra;
+    }
+
+    public long lastModified() {
+        return lastModified;
+    }
+
+    public InputStream openInputStream() throws IOException {
+        return new ByteArrayInputStream(getLocalBytes());
+    }
+
+    private byte[] getLocalBytes() throws IOException {
+        try {
+            if (calculated != null)
+                return calculated;
+
+            return calculated = getBytes();
+        } catch (IOException e) {
+            throw e;
+        } catch (Exception e) {
+            IOException ee = new IOException("Opening resource");
+            ee.initCause(e);
+            throw ee;
+        }
+    }
+
+    public void setExtra(String extra) {
+        this.extra = extra;
+    }
+
+    public void write(OutputStream out) throws IOException {
+        out.write(getLocalBytes());
+    }
+
+    abstract protected byte[] getBytes() throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Analyzer.java b/bundleplugin/src/main/java/aQute/lib/osgi/Analyzer.java
new file mode 100644
index 0000000..a529fbc
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Analyzer.java
@@ -0,0 +1,1596 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+/**
+ * This class can calculate the required headers for a (potential) JAR file. It
+ * analyzes a directory or JAR for the packages that are contained and that are
+ * referred to by the bytecodes. The user can the use regular expressions to
+ * define the attributes and directives. The matching is not fully regex for
+ * convenience. A * and ? get a . prefixed and dots are escaped.
+ * 
+ * <pre>
+ *                                                             			*;auto=true				any		
+ *                                                             			org.acme.*;auto=true    org.acme.xyz
+ *                                                             			org.[abc]*;auto=true    org.acme.xyz
+ * </pre>
+ * 
+ * Additional, the package instruction can start with a '=' or a '!'. The '!'
+ * indicates negation. Any matching package is removed. The '=' is literal, the
+ * expression will be copied verbatim and no matching will take place.
+ * 
+ * Any headers in the given properties are used in the output properties.
+ */
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.jar.Attributes.*;
+import java.util.regex.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.filter.*;
+
+public class Analyzer extends Processor {
+
+    static Pattern                         doNotCopy      = Pattern
+                                                                  .compile("CVS|.svn");
+    static String                          version;
+    static Pattern                         versionPattern = Pattern
+                                                                  .compile("(\\d+\\.\\d+)\\.\\d+.*");
+    final Map<String, Map<String, String>> contained      = newHashMap();                            // package
+    final Map<String, Map<String, String>> referred       = newHashMap();                            // package
+    final Map<String, Set<String>>         uses           = newHashMap();                            // package
+    Map<String, Clazz>                     classspace;
+    Map<String, Map<String, String>>       exports;
+    Map<String, Map<String, String>>       imports;
+    Map<String, Map<String, String>>       bundleClasspath;                                          // Bundle
+    final Map<String, Map<String, String>> ignored        = newHashMap();                            // Ignored
+    // packages
+    Jar                                    dot;
+    Map<String, Map<String, String>>       classpathExports;
+
+    String                                 activator;
+
+    final List<Jar>                        classpath      = newList();
+
+    static Properties                      bndInfo;
+
+    boolean                                analyzed;
+    String                                 bsn;
+
+    public Analyzer(Processor parent) {
+        super(parent);
+    }
+
+    public Analyzer() {
+    }
+
+    /**
+     * Specifically for Maven
+     * 
+     * @param properties
+     *            the properties
+     */
+
+    public static Properties getManifest(File dirOrJar) throws IOException {
+        Analyzer analyzer = new Analyzer();
+        analyzer.setJar(dirOrJar);
+        Properties properties = new Properties();
+        properties.put(IMPORT_PACKAGE, "*");
+        properties.put(EXPORT_PACKAGE, "*");
+        analyzer.setProperties(properties);
+        Manifest m = analyzer.calcManifest();
+        Properties result = new Properties();
+        for (Iterator<Object> i = m.getMainAttributes().keySet().iterator(); i
+                .hasNext();) {
+            Attributes.Name name = (Attributes.Name) i.next();
+            result.put(name.toString(), m.getMainAttributes().getValue(name));
+        }
+        return result;
+    }
+
+    /**
+     * Calcualtes the data structures for generating a manifest.
+     * 
+     * @throws IOException
+     */
+    public void analyze() throws IOException {
+        if (!analyzed) {
+            analyzed = true;
+            classpathExports = newHashMap();
+            activator = getProperty(BUNDLE_ACTIVATOR);
+            bundleClasspath = parseHeader(getProperty(BUNDLE_CLASSPATH));
+
+            analyzeClasspath();
+
+            classspace = analyzeBundleClasspath(dot, bundleClasspath,
+                    contained, referred, uses);
+
+            for (AnalyzerPlugin plugin : getPlugins(AnalyzerPlugin.class)) {
+                if (plugin instanceof AnalyzerPlugin) {
+                    AnalyzerPlugin analyzer = (AnalyzerPlugin) plugin;
+                    try {
+                        boolean reanalyze = analyzer.analyzeJar(this);
+                        if (reanalyze)
+                            classspace = analyzeBundleClasspath(dot,
+                                    bundleClasspath, contained, referred, uses);
+                    } catch (Exception e) {
+                        error("Plugin Analyzer " + analyzer
+                                + " throws exception " + e);
+                        e.printStackTrace();
+                    }
+                }
+            }
+
+            if (activator != null) {
+                // Add the package of the activator to the set
+                // of referred classes. This must be done before we remove
+                // contained set.
+                int n = activator.lastIndexOf('.');
+                if (n > 0) {
+                    referred.put(activator.substring(0, n),
+                            new LinkedHashMap<String, String>());
+                }
+            }
+
+            referred.keySet().removeAll(contained.keySet());
+            if (referred.containsKey(".")) {
+                error("The default package '.' is not permitted by the Import-Package syntax. \n"
+                        + " This can be caused by compile errors in Eclipse because Eclipse creates \n"
+                        + "valid class files regardless of compile errors.\n"
+                        + "The following package(s) import from the default package "
+                        + getUsedBy("."));
+            }
+
+            Map<String, Map<String, String>> exportInstructions = parseHeader(getProperty(EXPORT_PACKAGE));
+            Map<String, Map<String, String>> additionalExportInstructions = parseHeader(getProperty(EXPORT_CONTENTS));
+            exportInstructions.putAll(additionalExportInstructions);
+            Map<String, Map<String, String>> importInstructions = parseHeader(getImportPackages());
+            Map<String, Map<String, String>> dynamicImports = parseHeader(getProperty(DYNAMICIMPORT_PACKAGE));
+
+            if (dynamicImports != null) {
+                // Remove any dynamic imports from the referred set.
+                referred.keySet().removeAll(dynamicImports.keySet());
+            }
+
+            Map<String, Map<String, String>> superfluous = newHashMap();
+            // Tricky!
+            for (Iterator<String> i = exportInstructions.keySet().iterator(); i
+                    .hasNext();) {
+                String instr = i.next();
+                if (!instr.startsWith("!"))
+                    superfluous.put(instr, exportInstructions.get(instr));
+            }
+
+            exports = merge("export-package", exportInstructions, contained,
+                    superfluous.keySet(), null);
+
+            // disallow export of default package
+            exports.remove(".");
+
+            for (Iterator<Map.Entry<String, Map<String, String>>> i = superfluous
+                    .entrySet().iterator(); i.hasNext();) {
+                // It is possible to mention metadata directories in the export
+                // explicitly, they are then exported and removed from the
+                // warnings. Note that normally metadata directories are not
+                // exported.
+                Map.Entry<String, Map<String, String>> entry = i.next();
+                String pack = entry.getKey();
+                if (isDuplicate(pack))
+                    i.remove();
+                else if (isMetaData(pack)) {
+                    exports.put(pack, entry.getValue());
+                    i.remove();
+                }
+            }
+
+            if (!superfluous.isEmpty()) {
+                warning("Superfluous export-package instructions: "
+                        + superfluous.keySet());
+            }
+
+            // Add all exports that do not have an -noimport: directive
+            // to the imports.
+            Map<String, Map<String, String>> referredAndExported = newMap(referred);
+            referredAndExported.putAll(addExportsToImports(exports));
+
+            // match the imports to the referred and exported packages,
+            // merge the info for matching packages
+            Set<String> extra = new TreeSet<String>(importInstructions.keySet());
+            imports = merge("import-package", importInstructions,
+                    referredAndExported, extra, ignored);
+
+            // Instructions that have not been used could be superfluous
+            // or if they do not contain wildcards, should be added
+            // as extra imports, the user knows best.
+            for (Iterator<String> i = extra.iterator(); i.hasNext();) {
+                String p = i.next();
+                if (p.startsWith("!") || p.indexOf('*') >= 0
+                        || p.indexOf('?') >= 0 || p.indexOf('[') >= 0) {
+                    if (!isResourceOnly())
+                        warning("Did not find matching referal for " + p);
+                } else {
+                    Map<String, String> map = importInstructions.get(p);
+                    imports.put(p, map);
+                }
+            }
+
+            // See what information we can find to augment the
+            // imports. I.e. look on the classpath
+            augmentImports();
+
+            // Add the uses clause to the exports
+            doUses(exports, uses, imports);
+        }
+    }
+
+    /**
+     * Copy the input collection into an output set but skip names that have
+     * been marked as duplicates or are optional.
+     * 
+     * @param superfluous
+     * @return
+     */
+    Set<Instruction> removeMarkedDuplicates(Collection<Instruction> superfluous) {
+        Set<Instruction> result = new HashSet<Instruction>();
+        for (Iterator<Instruction> i = superfluous.iterator(); i.hasNext();) {
+            Instruction instr = (Instruction) i.next();
+            if (!isDuplicate(instr.getPattern()) && !instr.isOptional())
+                result.add(instr);
+        }
+        return result;
+    }
+
+    /**
+     * Analyzer has an empty default but the builder has a * as default.
+     * 
+     * @return
+     */
+    protected String getImportPackages() {
+        return getProperty(IMPORT_PACKAGE);
+    }
+
+    /**
+     * 
+     * @return
+     */
+    boolean isResourceOnly() {
+        return getProperty(RESOURCEONLY, "false").equalsIgnoreCase("true");
+    }
+
+    /**
+     * Answer the list of packages that use the given package.
+     */
+    Set<String> getUsedBy(String pack) {
+        Set<String> set = newSet();
+        for (Iterator<Map.Entry<String, Set<String>>> i = uses.entrySet()
+                .iterator(); i.hasNext();) {
+            Map.Entry<String, Set<String>> entry = i.next();
+            Set<String> used = entry.getValue();
+            if (used.contains(pack))
+                set.add(entry.getKey());
+        }
+        return set;
+    }
+
+    /**
+     * One of the main workhorses of this class. This will analyze the current
+     * setp and calculate a new manifest according to this setup. This method
+     * will also set the manifest on the main jar dot
+     * 
+     * @return
+     * @throws IOException
+     */
+    public Manifest calcManifest() throws IOException {
+        analyze();
+        Manifest manifest = new Manifest();
+        Attributes main = manifest.getMainAttributes();
+
+        main.put(Attributes.Name.MANIFEST_VERSION, "1.0");
+        main.putValue(BUNDLE_MANIFESTVERSION, "2");
+
+        boolean noExtraHeaders = "true"
+                .equalsIgnoreCase(getProperty(NOEXTRAHEADERS));
+
+        if (!noExtraHeaders) {
+            main.putValue(CREATED_BY, System.getProperty("java.version") + " ("
+                    + System.getProperty("java.vendor") + ")");
+            main.putValue(TOOL, "Bnd-" + getVersion());
+            main.putValue(BND_LASTMODIFIED, "" + System.currentTimeMillis());
+        }
+        String exportHeader = printClauses(exports,
+                "uses:|include:|exclude:|mandatory:|" + IMPORT_DIRECTIVE, true);
+
+        if (exportHeader.length() > 0)
+            main.putValue(EXPORT_PACKAGE, exportHeader);
+        else
+            main.remove(EXPORT_PACKAGE);
+
+        Map<String, Map<String, String>> temp = removeKeys(imports, "java.");
+        if (!temp.isEmpty()) {
+            main.putValue(IMPORT_PACKAGE, printClauses(temp, "resolution:"));
+        } else {
+            main.remove(IMPORT_PACKAGE);
+        }
+
+        temp = newMap(contained);
+        temp.keySet().removeAll(exports.keySet());
+
+        if (!temp.isEmpty())
+            main.putValue(PRIVATE_PACKAGE, printClauses(temp, ""));
+        else
+            main.remove(PRIVATE_PACKAGE);
+
+        if (!ignored.isEmpty()) {
+            main.putValue(IGNORE_PACKAGE, printClauses(ignored, ""));
+        } else {
+            main.remove(IGNORE_PACKAGE);
+        }
+
+        if (bundleClasspath != null && !bundleClasspath.isEmpty())
+            main.putValue(BUNDLE_CLASSPATH, printClauses(bundleClasspath, ""));
+        else
+            main.remove(BUNDLE_CLASSPATH);
+
+
+        for (Enumeration<?> h = getProperties().propertyNames(); h
+                .hasMoreElements();) {
+            String header = (String) h.nextElement();
+            if (header.trim().length() == 0) {
+                warning("Empty property set with value: "
+                        + getProperties().getProperty(header));
+                continue;
+            }
+            if (!Character.isUpperCase(header.charAt(0))) {
+                if (header.charAt(0) == '@')
+                    doNameSection(manifest, header);
+                continue;
+            }
+
+            if (header.equals(BUNDLE_CLASSPATH)
+                    || header.equals(EXPORT_PACKAGE)
+                    || header.equals(IMPORT_PACKAGE))
+                continue;
+
+            if (header.equalsIgnoreCase("Name")) {
+                error("Your bnd file contains a header called 'Name'. This interferes with the manifest name section.");
+                continue;
+            }
+
+            if (Verifier.HEADER_PATTERN.matcher(header).matches()) {
+                String value = getProperty(header);
+                if (value != null && main.getValue(header) == null) {
+                    if (value.trim().length() == 0)
+                        main.remove(header);
+                    else if (value.trim().equals("<<EMPTY>>"))
+                        main.putValue(header, "");
+                    else
+                        main.putValue(header, value);
+                }
+            } else {
+                // TODO should we report?
+            }
+        }
+
+        //
+        // Calculate the bundle symbolic name if it is
+        // not set.
+        // 1. set
+        // 2. name of properties file (must be != bnd.bnd)
+        // 3. name of directory, which is usualy project name
+        //
+        String bsn = getBsn();
+        if (main.getValue(BUNDLE_SYMBOLICNAME) == null) {
+            main.putValue(BUNDLE_SYMBOLICNAME, bsn);
+        }
+
+        //
+        // Use the same name for the bundle name as BSN when
+        // the bundle name is not set
+        //
+        if (main.getValue(BUNDLE_NAME) == null) {
+            main.putValue(BUNDLE_NAME, bsn);
+        }
+
+        if (main.getValue(BUNDLE_VERSION) == null)
+            main.putValue(BUNDLE_VERSION, "0");
+
+        // Copy old values into new manifest, when they
+        // exist in the old one, but not in the new one
+        merge(manifest, dot.getManifest());
+
+        // Remove all the headers mentioned in -removeheaders
+        Map<String, Map<String, String>> removes = parseHeader(getProperty(REMOVE_HEADERS));
+        for (Iterator<String> i = removes.keySet().iterator(); i.hasNext();) {
+            String header = i.next();
+            for (Iterator<Object> j = main.keySet().iterator(); j.hasNext();) {
+                Attributes.Name attr = (Attributes.Name) j.next();
+                if (attr.toString().matches(header)) {
+                    j.remove();
+                    progress("Removing header: " + header);
+                }
+            }
+        }
+
+        dot.setManifest(manifest);
+        return manifest;
+    }
+
+    /**
+     * This method is called when the header starts with a @, signifying a name
+     * section header. The name part is defined by replacing all the @ signs to
+     * a /, removing the first and the last, and using the last part as header
+     * name:
+     * 
+     * <pre>
+     * &#064;org@osgi@service@event@Implementation-Title
+     * </pre>
+     * 
+     * This will be the header Implementation-Title in the
+     * org/osgi/service/event named section.
+     * 
+     * @param manifest
+     * @param header
+     */
+    private void doNameSection(Manifest manifest, String header) {
+        String path = header.replace('@', '/');
+        int n = path.lastIndexOf('/');
+        // Must succeed because we start with @
+        String name = path.substring(n + 1);
+        // Skip first /
+        path = path.substring(1, n);
+        if (name.length() != 0 && path.length() != 0) {
+            Attributes attrs = manifest.getAttributes(path);
+            if (attrs == null) {
+                attrs = new Attributes();
+                manifest.getEntries().put(path, attrs);
+            }
+            attrs.putValue(name, getProperty(header));
+        } else {
+            warning(
+                    "Invalid header (starts with @ but does not seem to be for the Name section): %s",
+                    header);
+        }
+    }
+
+    /**
+     * Clear the key part of a header. I.e. remove everything from the first ';'
+     * 
+     * @param value
+     * @return
+     */
+    public String getBsn() {
+        String value = getProperty(BUNDLE_SYMBOLICNAME);
+        if (value == null) {
+            if (getPropertiesFile() != null)
+                value = getPropertiesFile().getName();
+
+            if (value == null || value.equals("bnd.bnd"))
+                value = getBase().getName();
+            else if (value.endsWith(".bnd"))
+                value = value.substring(0, value.length() - 4);
+        }
+
+        if (value == null)
+            return "untitled";
+
+        int n = value.indexOf(';');
+        if (n > 0)
+            value = value.substring(0, n);
+        return value.trim();
+    }
+
+    public String _bsn(String args[]) {
+        return getBsn();
+    }
+
+    /**
+     * Calculate an export header solely based on the contents of a JAR file
+     * 
+     * @param bundle
+     *            The jar file to analyze
+     * @return
+     */
+    public String calculateExportsFromContents(Jar bundle) {
+        String ddel = "";
+        StringBuffer sb = new StringBuffer();
+        Map<String, Map<String, Resource>> map = bundle.getDirectories();
+        for (Iterator<String> i = map.keySet().iterator(); i.hasNext();) {
+            String directory = (String) i.next();
+            if (directory.equals("META-INF")
+                    || directory.startsWith("META-INF/"))
+                continue;
+            if (directory.equals("OSGI-OPT")
+                    || directory.startsWith("OSGI-OPT/"))
+                continue;
+            if (directory.equals("/"))
+                continue;
+
+            if (directory.endsWith("/"))
+                directory = directory.substring(0, directory.length() - 1);
+
+            directory = directory.replace('/', '.');
+            sb.append(ddel);
+            sb.append(directory);
+            ddel = ",";
+        }
+        return sb.toString();
+    }
+
+
+    public Map<String, Map<String, String>> getBundleClasspath() {
+        return bundleClasspath;
+    }
+
+    public Map<String, Map<String, String>> getContained() {
+        return contained;
+    }
+
+    public Map<String, Map<String, String>> getExports() {
+        return exports;
+    }
+
+    public Map<String, Map<String, String>> getImports() {
+        return imports;
+    }
+
+    public Jar getJar() {
+        return dot;
+    }
+
+    public Map<String, Map<String, String>> getReferred() {
+        return referred;
+    }
+
+    /**
+     * Return the set of unreachable code depending on exports and the bundle
+     * activator.
+     * 
+     * @return
+     */
+    public Set<String> getUnreachable() {
+        Set<String> unreachable = new HashSet<String>(uses.keySet()); // all
+        for (Iterator<String> r = exports.keySet().iterator(); r.hasNext();) {
+            String packageName = r.next();
+            removeTransitive(packageName, unreachable);
+        }
+        if (activator != null) {
+            String pack = activator.substring(0, activator.lastIndexOf('.'));
+            removeTransitive(pack, unreachable);
+        }
+        return unreachable;
+    }
+
+    public Map<String, Set<String>> getUses() {
+        return uses;
+    }
+
+    /**
+     * Get the version from the manifest, a lot of work!
+     * 
+     * @return version or unknown.
+     */
+    public String getVersion() {
+        return getBndInfo("version", "<unknown version>");
+    }
+
+    public long getBndLastModified() {
+        String time = getBndInfo("modified", "0");
+        try {
+            return Long.parseLong(time);
+        } catch (Exception e) {
+        }
+        return 0;
+    }
+
+    public String getBndInfo(String key, String defaultValue) {
+        if (bndInfo == null) {
+            bndInfo = new Properties();
+            try {
+                InputStream in = Analyzer.class.getResourceAsStream("bnd.info");
+                if (in != null) {
+                    bndInfo.load(in);
+                    in.close();
+                }
+            } catch (IOException ioe) {
+                warning("Could not read bnd.info in "
+                        + Analyzer.class.getPackage() + ioe);
+            }
+        }
+        return bndInfo.getProperty(key, defaultValue);
+    }
+
+    /**
+     * Merge the existing manifest with the instructions.
+     * 
+     * @param manifest
+     *            The manifest to merge with
+     * @throws IOException
+     */
+    public void mergeManifest(Manifest manifest) throws IOException {
+        if (manifest != null) {
+            Attributes attributes = manifest.getMainAttributes();
+            for (Iterator<Object> i = attributes.keySet().iterator(); i
+                    .hasNext();) {
+                Name name = (Name) i.next();
+                String key = name.toString();
+                // Dont want instructions
+                if (key.startsWith("-"))
+                    continue;
+
+                if (getProperty(key) == null)
+                    setProperty(key, (String) attributes.get(name));
+            }
+        }
+    }
+
+    public void setBase(File file) {
+        super.setBase(file);
+        getProperties().put("project.dir", getBase().getAbsolutePath());
+    }
+
+    /**
+     * Set the classpath for this analyzer by file.
+     * 
+     * @param classpath
+     * @throws IOException
+     */
+    public void setClasspath(File[] classpath) throws IOException {
+        List<Jar> list = new ArrayList<Jar>();
+        for (int i = 0; i < classpath.length; i++) {
+            if (classpath[i].exists()) {
+                Jar current = new Jar(classpath[i]);
+                list.add(current);
+            } else {
+                error("Missing file on classpath: " + classpath[i]);
+            }
+        }
+        for (Iterator<Jar> i = list.iterator(); i.hasNext();) {
+            addClasspath(i.next());
+        }
+    }
+
+    public void setClasspath(Jar[] classpath) {
+        for (int i = 0; i < classpath.length; i++) {
+            addClasspath(classpath[i]);
+        }
+    }
+
+    public void setClasspath(String[] classpath) {
+        for (int i = 0; i < classpath.length; i++) {
+            Jar jar = getJarFromName(classpath[i], " setting classpath");
+            if (jar != null)
+                addClasspath(jar);
+        }
+    }
+
+    /**
+     * Set the JAR file we are going to work in. This will read the JAR in
+     * memory.
+     * 
+     * @param jar
+     * @return
+     * @throws IOException
+     */
+    public Jar setJar(File jar) throws IOException {
+        Jar jarx = new Jar(jar);
+        addClose(jarx);
+        return setJar(jarx);
+    }
+
+    /**
+     * Set the JAR directly we are going to work on.
+     * 
+     * @param jar
+     * @return
+     */
+    public Jar setJar(Jar jar) {
+        this.dot = jar;
+        return jar;
+    }
+
+    protected void begin() {
+        super.begin();
+
+        updateModified(getBndLastModified(), "bnd last modified");
+        String doNotCopy = getProperty(DONOTCOPY);
+        if (doNotCopy != null)
+            Analyzer.doNotCopy = Pattern.compile(doNotCopy);
+
+        verifyManifestHeadersCase(getProperties());
+    }
+
+    /**
+     * Check if the given class or interface name is contained in the jar.
+     * 
+     * @param interfaceName
+     * @return
+     */
+    public boolean checkClass(String interfaceName) {
+        String path = interfaceName.replace('.', '/') + ".class";
+        if (classspace.containsKey(path))
+            return true;
+
+        String pack = interfaceName;
+        int n = pack.lastIndexOf('.');
+        if (n > 0)
+            pack = pack.substring(0, n);
+        else
+            pack = ".";
+
+        return imports.containsKey(pack);
+    }
+
+    /**
+     * Try to get a Jar from a file name/path or a url, or in last resort from
+     * the classpath name part of their files.
+     * 
+     * @param name
+     *            URL or filename relative to the base
+     * @param from
+     *            Message identifying the caller for errors
+     * @return null or a Jar with the contents for the name
+     */
+    Jar getJarFromName(String name, String from) {
+        File file = new File(name);
+        if (!file.isAbsolute())
+            file = new File(getBase(), name);
+
+        if (file.exists())
+            try {
+                Jar jar = new Jar(file);
+                addClose(jar);
+                return jar;
+            } catch (Exception e) {
+                error("Exception in parsing jar file for " + from + ": " + name
+                        + " " + e);
+            }
+        // It is not a file ...
+        try {
+            // Lets try a URL
+            URL url = new URL(name);
+            Jar jar = new Jar(fileName(url.getPath()));
+            addClose(jar);
+            URLConnection connection = url.openConnection();
+            InputStream in = connection.getInputStream();
+            long lastModified = connection.getLastModified();
+            if (lastModified == 0)
+                // We assume the worst :-(
+                lastModified = System.currentTimeMillis();
+            EmbeddedResource.build(jar, in, lastModified);
+            in.close();
+            return jar;
+        } catch (IOException ee) {
+            // Check if we have files on the classpath
+            // that have the right name, allows us to specify those
+            // names instead of the full path.
+            for (Iterator<Jar> cp = getClasspath().iterator(); cp.hasNext();) {
+                Jar entry = cp.next();
+                if (entry.source != null && entry.source.getName().equals(name)) {
+                    return entry;
+                }
+            }
+            // error("Can not find jar file for " + from + ": " + name);
+        }
+        return null;
+    }
+
+    private String fileName(String path) {
+        int n = path.lastIndexOf('/');
+        if (n > 0)
+            return path.substring(n + 1);
+        return path;
+    }
+
+    /**
+     * 
+     * @param manifest
+     * @throws Exception
+     */
+    void merge(Manifest result, Manifest old) throws IOException {
+        if (old != null) {
+            for (Iterator<Map.Entry<Object, Object>> e = old
+                    .getMainAttributes().entrySet().iterator(); e.hasNext();) {
+                Map.Entry<Object, Object> entry = e.next();
+                Attributes.Name name = (Attributes.Name) entry.getKey();
+                String value = (String) entry.getValue();
+                if (name.toString().equalsIgnoreCase("Created-By"))
+                    name = new Attributes.Name("Originally-Created-By");
+                if (!result.getMainAttributes().containsKey(name))
+                    result.getMainAttributes().put(name, value);
+            }
+
+            // do not overwrite existing entries
+            Map<String, Attributes> oldEntries = old.getEntries();
+            Map<String, Attributes> newEntries = result.getEntries();
+            for (Iterator<Map.Entry<String, Attributes>> e = oldEntries
+                    .entrySet().iterator(); e.hasNext();) {
+                Map.Entry<String, Attributes> entry = e.next();
+                if (!newEntries.containsKey(entry.getKey())) {
+                    newEntries.put(entry.getKey(), entry.getValue());
+                }
+            }
+        }
+    }
+
+    String stem(String name) {
+        int n = name.lastIndexOf('.');
+        if (n > 0)
+            return name.substring(0, n);
+        else
+            return name;
+    }
+
+    /**
+     * Bnd is case sensitive for the instructions so we better check people are
+     * not using an invalid case. We do allow this to set headers that should
+     * not be processed by us but should be used by the framework.
+     * 
+     * @param properties
+     *            Properties to verify.
+     */
+
+    void verifyManifestHeadersCase(Properties properties) {
+        for (Iterator<Object> i = properties.keySet().iterator(); i.hasNext();) {
+            String header = (String) i.next();
+            for (int j = 0; j < headers.length; j++) {
+                if (!headers[j].equals(header)
+                        && headers[j].equalsIgnoreCase(header)) {
+                    warning("Using a standard OSGi header with the wrong case (bnd is case sensitive!), using: "
+                            + header + " and expecting: " + headers[j]);
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * We will add all exports to the imports unless there is a -noimport
+     * directive specified on an export. This directive is skipped for the
+     * manifest.
+     * 
+     * We also remove any version parameter so that augmentImports can do the
+     * version policy.
+     * 
+     */
+    Map<String, Map<String, String>> addExportsToImports(
+            Map<String, Map<String, String>> exports) {
+        Map<String, Map<String, String>> importsFromExports = newHashMap();
+        for (Map.Entry<String, Map<String, String>> packageEntry : exports
+                .entrySet()) {
+            String packageName = packageEntry.getKey();
+            Map<String, String> parameters = packageEntry.getValue();
+            String noimport = (String) parameters.get(NO_IMPORT_DIRECTIVE);
+            if (noimport == null || !noimport.equalsIgnoreCase("true")) {
+                if (parameters.containsKey(VERSION_ATTRIBUTE)) {
+                    parameters = newMap(parameters);
+                    parameters.remove(VERSION_ATTRIBUTE);
+                }
+                importsFromExports.put(packageName, parameters);
+            }
+        }
+        return importsFromExports;
+    }
+
+    /**
+     * Create the imports/exports by parsing
+     * 
+     * @throws IOException
+     */
+    void analyzeClasspath() throws IOException {
+        classpathExports = newHashMap();
+        for (Iterator<Jar> c = getClasspath().iterator(); c.hasNext();) {
+            Jar current = c.next();
+            checkManifest(current);
+            for (Iterator<String> j = current.getDirectories().keySet()
+                    .iterator(); j.hasNext();) {
+                String dir = j.next();
+                Resource resource = current.getResource(dir + "/packageinfo");
+                if (resource != null) {
+                    InputStream in = resource.openInputStream();
+                    String version = parsePackageInfo(in);
+                    in.close();
+                    setPackageInfo(dir, "version", version);
+                }
+            }
+        }
+    }
+
+    /**
+     * 
+     * @param jar
+     */
+    void checkManifest(Jar jar) {
+        try {
+            Manifest m = jar.getManifest();
+            if (m != null) {
+                String exportHeader = m.getMainAttributes().getValue(
+                        EXPORT_PACKAGE);
+                if (exportHeader != null) {
+                    Map<String, Map<String, String>> exported = parseHeader(exportHeader);
+                    if (exported != null)
+                        classpathExports.putAll(exported);
+                }
+            }
+        } catch (Exception e) {
+            warning("Erroneous Manifest for " + jar + " " + e);
+        }
+    }
+
+    /**
+     * Find some more information about imports in manifest and other places.
+     */
+    void augmentImports() {
+        for (String packageName : imports.keySet()) {
+            setProperty(CURRENT_PACKAGE, packageName);
+            try {
+                Map<String, String> importAttributes = imports.get(packageName);
+                Map<String, String> exporterAttributes = classpathExports
+                        .get(packageName);
+                if (exporterAttributes == null)
+                    exporterAttributes = exports.get(packageName);
+
+                if (exporterAttributes != null) {
+                    augmentVersion(importAttributes, exporterAttributes);
+                    augmentMandatory(importAttributes, exporterAttributes);
+                    if (exporterAttributes.containsKey(IMPORT_DIRECTIVE))
+                        importAttributes.put(IMPORT_DIRECTIVE,
+                                exporterAttributes.get(IMPORT_DIRECTIVE));
+                }
+
+                // Convert any attribute values that have macros.
+                for (String key : importAttributes.keySet()) {
+                    String value = importAttributes.get(key);
+                    if (value.indexOf('$') >= 0) {
+                        value = getReplacer().process(value);
+                        importAttributes.put(key, value);
+                    }
+                }
+
+                // You can add a remove-attribute: directive with a regular
+                // expression for attributes that need to be removed. We also
+                // remove all attributes that have a value of !. This allows
+                // you to use macros with ${if} to remove values.
+                String remove = importAttributes
+                        .remove(REMOVE_ATTRIBUTE_DIRECTIVE);
+                Instruction removeInstr = null;
+
+                if (remove != null)
+                    removeInstr = Instruction.getPattern(remove);
+
+                for (Iterator<Map.Entry<String, String>> i = importAttributes
+                        .entrySet().iterator(); i.hasNext();) {
+                    Map.Entry<String, String> entry = i.next();
+                    if (entry.getValue().equals("!"))
+                        i.remove();
+                    else if (removeInstr != null
+                            && removeInstr.matches((String) entry.getKey()))
+                        i.remove();
+                    else {
+                        // Not removed ...
+                    }
+                }
+
+            } finally {
+                unsetProperty(CURRENT_PACKAGE);
+            }
+        }
+    }
+
+    /**
+     * If we use an import with mandatory attributes we better all use them
+     * 
+     * @param currentAttributes
+     * @param exporter
+     */
+    private void augmentMandatory(Map<String, String> currentAttributes,
+            Map<String, String> exporter) {
+        String mandatory = (String) exporter.get("mandatory:");
+        if (mandatory != null) {
+            String[] attrs = mandatory.split("\\s*,\\s*");
+            for (int i = 0; i < attrs.length; i++) {
+                if (!currentAttributes.containsKey(attrs[i]))
+                    currentAttributes.put(attrs[i], exporter.get(attrs[i]));
+            }
+        }
+    }
+
+    /**
+     * Check if we can augment the version from the exporter.
+     * 
+     * We allow the version in the import to specify a @ which is replaced with
+     * the exporter's version.
+     * 
+     * @param currentAttributes
+     * @param exporter
+     */
+    private void augmentVersion(Map<String, String> currentAttributes,
+            Map<String, String> exporter) {
+
+        String exportVersion = (String) exporter.get("version");
+        if (exportVersion == null)
+            exportVersion = (String) exporter.get("specification-version");
+        if (exportVersion == null)
+            return;
+
+        exportVersion = cleanupVersion(exportVersion);
+
+        setProperty("@", exportVersion);
+
+        String importRange = currentAttributes.get("version");
+        if (importRange != null) {
+            importRange = cleanupVersion(importRange);
+            importRange = getReplacer().process(importRange);
+        } else
+            importRange = getVersionPolicy();
+
+        unsetProperty("@");
+
+        // See if we can borrow the version
+        // we mist replace the ${@} with the version we
+        // found this can be useful if you want a range to start
+        // with the found version.
+        currentAttributes.put("version", importRange);
+    }
+
+    /**
+     * Add the uses clauses
+     * 
+     * @param exports
+     * @param uses
+     * @throws MojoExecutionException
+     */
+    void doUses(Map<String, Map<String, String>> exports,
+            Map<String, Set<String>> uses,
+            Map<String, Map<String, String>> imports) {
+        if ("true".equalsIgnoreCase(getProperty(NOUSES)))
+            return;
+
+        for (Iterator<String> i = exports.keySet().iterator(); i.hasNext();) {
+            String packageName = i.next();
+            setProperty(CURRENT_PACKAGE, packageName);
+            try {
+                Map<String, String> clause = exports.get(packageName);
+                String override = clause.get(USES_DIRECTIVE);
+                if (override == null)
+                    override = USES_USES;
+
+                Set<String> usedPackages = uses.get(packageName);
+                if (usedPackages != null) {
+                    // Only do a uses on exported or imported packages
+                    // and uses should also not contain our own package
+                    // name
+                    Set<String> sharedPackages = new HashSet<String>();
+                    sharedPackages.addAll(imports.keySet());
+                    sharedPackages.addAll(exports.keySet());
+                    usedPackages.retainAll(sharedPackages);
+                    usedPackages.remove(packageName);
+
+                    StringBuffer sb = new StringBuffer();
+                    String del = "";
+                    for (Iterator<String> u = usedPackages.iterator(); u
+                            .hasNext();) {
+                        String usedPackage = u.next();
+                        if (!usedPackage.startsWith("java.")) {
+                            sb.append(del);
+                            sb.append(usedPackage);
+                            del = ",";
+                        }
+                    }
+                    if (override.indexOf('$') >= 0) {
+                        setProperty(CURRENT_USES, sb.toString());
+                        override = getReplacer().process(override);
+                        unsetProperty(CURRENT_USES);
+                    } else
+                        // This is for backward compatibility 0.0.287
+                        // can be deprecated over time
+                        override = override
+                                .replaceAll(USES_USES, sb.toString()).trim();
+                    if (override.endsWith(","))
+                        override = override.substring(0, override.length() - 1);
+                    if (override.startsWith(","))
+                        override = override.substring(1);
+                    if (override.length() > 0) {
+                        clause.put("uses:", override);
+                    }
+                }
+            } finally {
+                unsetProperty(CURRENT_PACKAGE);
+            }
+        }
+    }
+
+    /**
+     * Transitively remove all elemens from unreachable through the uses link.
+     * 
+     * @param name
+     * @param unreachable
+     */
+    void removeTransitive(String name, Set<String> unreachable) {
+        if (!unreachable.contains(name))
+            return;
+
+        unreachable.remove(name);
+
+        Set<String> ref = uses.get(name);
+        if (ref != null) {
+            for (Iterator<String> r = ref.iterator(); r.hasNext();) {
+                String element = (String) r.next();
+                removeTransitive(element, unreachable);
+            }
+        }
+    }
+
+    /**
+     * Helper method to set the package info
+     * 
+     * @param dir
+     * @param key
+     * @param value
+     */
+    void setPackageInfo(String dir, String key, String value) {
+        if (value != null) {
+            String pack = dir.replace('/', '.');
+            Map<String, String> map = classpathExports.get(pack);
+            if (map == null) {
+                map = new HashMap<String, String>();
+                classpathExports.put(pack, map);
+            }
+            map.put(key, value);
+        }
+    }
+
+    public void close() {
+        super.close();
+        if (dot != null)
+            dot.close();
+
+        if (classpath != null)
+            for (Iterator<Jar> j = classpath.iterator(); j.hasNext();) {
+                Jar jar = j.next();
+                jar.close();
+            }
+    }
+
+    /**
+     * Findpath looks through the contents of the JAR and finds paths that end
+     * with the given regular expression
+     * 
+     * ${findpath (; reg-expr (; replacement)? )? }
+     * 
+     * @param args
+     * @return
+     */
+    public String _findpath(String args[]) {
+        return findPath("findpath", args, true);
+    }
+
+    public String _findname(String args[]) {
+        return findPath("findname", args, false);
+    }
+
+    String findPath(String name, String[] args, boolean fullPathName) {
+        if (args.length > 3) {
+            warning("Invalid nr of arguments to " + name + " "
+                    + Arrays.asList(args) + ", syntax: ${" + name
+                    + " (; reg-expr (; replacement)? )? }");
+            return null;
+        }
+
+        String regexp = ".*";
+        String replace = null;
+
+        switch (args.length) {
+        case 3:
+            replace = args[2];
+        case 2:
+            regexp = args[1];
+        }
+        StringBuffer sb = new StringBuffer();
+        String del = "";
+
+        Pattern expr = Pattern.compile(regexp);
+        for (Iterator<String> e = dot.getResources().keySet().iterator(); e
+                .hasNext();) {
+            String path = e.next();
+            if (!fullPathName) {
+                int n = path.lastIndexOf('/');
+                if (n >= 0) {
+                    path = path.substring(n + 1);
+                }
+            }
+
+            Matcher m = expr.matcher(path);
+            if (m.matches()) {
+                if (replace != null)
+                    path = m.replaceAll(replace);
+
+                sb.append(del);
+                sb.append(path);
+                del = ", ";
+            }
+        }
+        return sb.toString();
+    }
+
+    public void putAll(Map<String, String> additional, boolean force) {
+        for (Iterator<Map.Entry<String, String>> i = additional.entrySet()
+                .iterator(); i.hasNext();) {
+            Map.Entry<String, String> entry = i.next();
+            if (force || getProperties().get(entry.getKey()) == null)
+                setProperty((String) entry.getKey(), (String) entry.getValue());
+        }
+    }
+
+    boolean firstUse = true;
+
+    public List<Jar> getClasspath() {
+        if (firstUse) {
+            firstUse = false;
+            String cp = getProperty(CLASSPATH);
+            if (cp != null)
+                for (String s : split(cp)) {
+                    Jar jar = getJarFromName(s, "getting classpath");
+                    if (jar != null)
+                        addClasspath(jar);
+                }
+        }
+        return classpath;
+    }
+
+    public void addClasspath(Jar jar) {
+        if (isPedantic() && jar.getResources().isEmpty())
+            warning("There is an empty jar or directory on the classpath: "
+                    + jar.getName());
+
+        classpath.add(jar);
+    }
+
+    public void addClasspath(File cp) throws IOException {
+        if (!cp.exists())
+            warning("File on classpath that does not exist: " + cp);
+        Jar jar = new Jar(cp);
+        addClose(jar);
+        classpath.add(jar);
+    }
+
+    public void clear() {
+        classpath.clear();
+    }
+
+    public Jar getTarget() {
+        return dot;
+    }
+
+    public Map<String, Clazz> analyzeBundleClasspath(Jar dot,
+            Map<String, Map<String, String>> bundleClasspath,
+            Map<String, Map<String, String>> contained,
+            Map<String, Map<String, String>> referred,
+            Map<String, Set<String>> uses) throws IOException {
+        Map<String, Clazz> classSpace = new HashMap<String, Clazz>();
+
+        if (bundleClasspath.isEmpty()) {
+            analyzeJar(dot, "", classSpace, contained, referred, uses);
+        } else {
+            for (String path : bundleClasspath.keySet()) {
+                if (path.equals(".")) {
+                    analyzeJar(dot, "", classSpace, contained, referred, uses);
+                    continue;
+                }
+                //
+                // There are 3 cases:
+                // - embedded JAR file
+                // - directory
+                // - error
+                //
+
+                Resource resource = dot.getResource(path);
+                if (resource != null) {
+                    try {
+                        Jar jar = new Jar(path);
+                        addClose(jar);
+                        EmbeddedResource.build(jar, resource);
+                        analyzeJar(jar, "", classSpace, contained, referred,
+                                uses);
+                    } catch (Exception e) {
+                        warning("Invalid bundle classpath entry: " + path + " "
+                                + e);
+                    }
+                } else {
+                    if (dot.getDirectories().containsKey(path)) {
+                        analyzeJar(dot, path + '/', classSpace, contained,
+                                referred, uses);
+                    } else {
+                        warning("No sub JAR or directory " + path);
+                    }
+                }
+            }
+        }
+        return classSpace;
+    }
+
+    /**
+     * We traverse through all the classes that we can find and calculate the
+     * contained and referred set and uses. This method ignores the Bundle
+     * classpath.
+     * 
+     * @param jar
+     * @param contained
+     * @param referred
+     * @param uses
+     * @throws IOException
+     */
+    private void analyzeJar(Jar jar, String prefix,
+            Map<String, Clazz> classSpace,
+            Map<String, Map<String, String>> contained,
+            Map<String, Map<String, String>> referred,
+            Map<String, Set<String>> uses) throws IOException {
+
+        next: for (String path : jar.getResources().keySet()) {
+            if (path.startsWith(prefix)) {
+                String relativePath = path.substring(prefix.length());
+                String pack = getPackage(relativePath);
+
+                if (pack != null && !contained.containsKey(pack)) {
+                    if (!isMetaData(relativePath)) {
+
+                        Map<String, String> map = new LinkedHashMap<String, String>();
+                        contained.put(pack, map);
+                        Resource pinfo = jar.getResource(prefix
+                                + pack.replace('.', '/') + "/packageinfo");
+                        if (pinfo != null) {
+                            InputStream in = pinfo.openInputStream();
+                            String version = parsePackageInfo(in);
+                            in.close();
+                            if (version != null)
+                                map.put("version", version);
+                        }
+                    }
+                }
+
+                if (path.endsWith(".class")) {
+                    Resource resource = jar.getResource(path);
+                    Clazz clazz;
+
+                    try {
+                        InputStream in = resource.openInputStream();
+                        clazz = new Clazz(relativePath, in);
+                        in.close();
+                    } catch (Throwable e) {
+                        error("Invalid class file: " + relativePath, e);
+                        e.printStackTrace();
+                        continue next;
+                    }
+
+                    String calculatedPath = clazz.getClassName() + ".class";
+                    if (!calculatedPath.equals(relativePath))
+                        error("Class in different directory than declared. Path from class name is "
+                                + calculatedPath
+                                + " but the path in the jar is "
+                                + relativePath
+                                + " from " + jar);
+
+                    classSpace.put(relativePath, clazz);
+                    referred.putAll(clazz.getReferred());
+
+                    // Add all the used packages
+                    // to this package
+                    Set<String> t = uses.get(pack);
+                    if (t == null)
+                        uses.put(pack, t = new LinkedHashSet<String>());
+                    t.addAll(clazz.getReferred().keySet());
+                    t.remove(pack);
+                }
+            }
+        }
+    }
+
+    /**
+     * Clean up version parameters. Other builders use more fuzzy definitions of
+     * the version syntax. This method cleans up such a version to match an OSGi
+     * version.
+     * 
+     * @param VERSION_STRING
+     * @return
+     */
+    static Pattern fuzzyVersion      = Pattern
+                                             .compile(
+                                                     "(\\d+)(\\.(\\d+)(\\.(\\d+))?)?([^a-zA-Z0-9](.*))?",
+                                                     Pattern.DOTALL);
+    static Pattern fuzzyVersionRange = Pattern
+                                             .compile(
+                                                     "(\\(|\\[)\\s*([-\\da-zA-Z.]+)\\s*,\\s*([-\\da-zA-Z.]+)\\s*(\\]|\\))",
+                                                     Pattern.DOTALL);
+    static Pattern fuzzyModifier     = Pattern.compile("(\\d+[.-])*(.*)",
+                                             Pattern.DOTALL);
+
+    static Pattern nummeric          = Pattern.compile("\\d*");
+
+    static public String cleanupVersion(String version) {
+        if (Verifier.VERSIONRANGE.matcher(version).matches())
+            return version;
+
+        Matcher m = fuzzyVersionRange.matcher(version);
+        if (m.matches()) {
+            String prefix = m.group(1);
+            String first = m.group(2);
+            String last = m.group(3);
+            String suffix = m.group(4);
+            return prefix + cleanupVersion(first) + "," + cleanupVersion(last)
+                    + suffix;
+        } else {
+            m = fuzzyVersion.matcher(version);
+            if (m.matches()) {
+                StringBuffer result = new StringBuffer();
+                String major = m.group(1);
+                String minor = m.group(3);
+                String micro = m.group(5);
+                String qualifier = m.group(7);
+
+                if (major != null) {
+                    result.append(major);
+                    if (minor != null) {
+                        result.append(".");
+                        result.append(minor);
+                        if (micro != null) {
+                            result.append(".");
+                            result.append(micro);
+                            if (qualifier != null) {
+                                result.append(".");
+                                cleanupModifier(result, qualifier);
+                            }
+                        } else if (qualifier != null) {
+                            result.append(".0.");
+                            cleanupModifier(result, qualifier);
+                        }
+                    } else if (qualifier != null) {
+                        result.append(".0.0.");
+                        cleanupModifier(result, qualifier);
+                    }
+                    return result.toString();
+                }
+            }
+        }
+        return version;
+    }
+
+    static void cleanupModifier(StringBuffer result, String modifier) {
+        Matcher m = fuzzyModifier.matcher(modifier);
+        if (m.matches())
+            modifier = m.group(2);
+
+        for (int i = 0; i < modifier.length(); i++) {
+            char c = modifier.charAt(i);
+            if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z')
+                    || (c >= 'A' && c <= 'Z') || c == '_' || c == '-')
+                result.append(c);
+        }
+    }
+
+    /**
+     * Decide if the package is a metadata package.
+     * 
+     * @param pack
+     * @return
+     */
+    boolean isMetaData(String pack) {
+        for (int i = 0; i < METAPACKAGES.length; i++) {
+            if (pack.startsWith(METAPACKAGES[i]))
+                return true;
+        }
+        return false;
+    }
+
+    public String getPackage(String clazz) {
+        int n = clazz.lastIndexOf('/');
+        if (n < 0)
+            return ".";
+        return clazz.substring(0, n).replace('/', '.');
+    }
+
+    //
+    // We accept more than correct OSGi versions because in a later
+    // phase we actually cleanup maven versions. But it is a bit yucky
+    //
+    static String parsePackageInfo(InputStream jar) throws IOException {
+        try {
+            Properties p = new Properties();
+            p.load(jar);
+            jar.close();
+            if (p.containsKey("version")) {
+                return p.getProperty("version");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public String getVersionPolicy() {
+        return getProperty(VERSIONPOLICY, "${version;==;${@}}");
+    }
+
+    /**
+     * The extends macro traverses all classes and returns a list of class names
+     * that extend a base class.
+     */
+
+    static String _classesHelp = "${classes;'implementing'|'extending'|'importing'|'named'|'version'|'any';<pattern>}, Return a list of class fully qualified class names that extend/implement/import any of the contained classes matching the pattern\n";
+
+    public String _classes(String args[]) {
+        // Macro.verifyCommand(args, _classesHelp, new
+        // Pattern[]{null,Pattern.compile("(implementing|implements|extending|extends|importing|imports|any)"),
+        // null}, 3,3);
+        Set<Clazz> matched = new HashSet<Clazz>(classspace.values());
+        for (int i = 1; i < args.length; i += 2) {
+            if (args.length < i + 1)
+                throw new IllegalArgumentException(
+                        "${classes} macro must have odd number of arguments. "
+                                + _classesHelp);
+
+            String typeName = args[i];
+            Clazz.QUERY type = null;
+            if (typeName.equals("implementing")
+                    || typeName.equals("implements"))
+                type = Clazz.QUERY.IMPLEMENTS;
+            else if (typeName.equals("extending") || typeName.equals("extends"))
+                type = Clazz.QUERY.EXTENDS;
+            else if (typeName.equals("importing") || typeName.equals("imports"))
+                type = Clazz.QUERY.IMPORTS;
+            else if (typeName.equals("all"))
+                type = Clazz.QUERY.ANY;
+            else if (typeName.equals("version"))
+                type = Clazz.QUERY.VERSION;
+            else if (typeName.equals("named"))
+                type = Clazz.QUERY.NAMED;
+
+            if (type == null)
+                throw new IllegalArgumentException(
+                        "${classes} has invalid type: " + typeName + ". "
+                                + _classesHelp);
+            // The argument is declared as a dotted name but the classes
+            // use a slashed named. So convert the name before we make it a
+            // instruction.
+            String pattern = args[i + 1].replace('.', '/');
+            Instruction instr = Instruction.getPattern(pattern);
+
+            for (Iterator<Clazz> c = matched.iterator(); c.hasNext();) {
+                Clazz clazz = c.next();
+                if (!clazz.is(type, instr, classspace))
+                    c.remove();
+            }
+        }
+        if (matched.isEmpty())
+            return "";
+
+        return join(matched);
+    }
+
+    /**
+     * Get the exporter of a package ...
+     */
+
+    public String _exporters(String args[]) throws Exception {
+        Macro
+                .verifyCommand(
+                        args,
+                        "${exporters;<packagename>}, returns the list of jars that export the given package",
+                        null, 2, 2);
+        StringBuilder sb = new StringBuilder();
+        String del = "";
+        String pack = args[1].replace('.', '/');
+        for (Jar jar : classpath) {
+            if (jar.getDirectories().containsKey(pack)) {
+                sb.append(del);
+                sb.append(jar.getName());
+            }
+        }
+        return sb.toString();
+    }
+
+    public Map<String, Clazz> getClassspace() {
+        return classspace;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java b/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
new file mode 100644
index 0000000..2da1980
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
@@ -0,0 +1,1135 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+import java.util.zip.*;
+
+import aQute.bnd.make.*;
+import aQute.bnd.service.*;
+
+/**
+ * Include-Resource: ( [name '=' ] file )+
+ * 
+ * Private-Package: package-decl ( ',' package-decl )*
+ * 
+ * Export-Package: package-decl ( ',' package-decl )*
+ * 
+ * Import-Package: package-decl ( ',' package-decl )*
+ * 
+ * @version $Revision: 1.17 $
+ */
+public class Builder extends Analyzer {
+    private static final int SPLIT_MERGE_LAST  = 1;
+    private static final int SPLIT_MERGE_FIRST = 2;
+    private static final int SPLIT_ERROR       = 3;
+    private static final int SPLIT_FIRST       = 4;
+    private static final int SPLIT_DEFAULT     = 0;
+
+    private static final File[] EMPTY_FILE = new File[0];
+    
+    List<File>               sourcePath        = new ArrayList<File>();
+    Pattern                  NAME_URL          = Pattern
+                                                       .compile("(.*)(http://.*)");
+
+    Make                     make              = new Make(this);
+
+    public Builder(Processor parent) {
+        super(parent);
+    }
+
+    public Builder() {
+    }
+
+    public Jar build() throws Exception {
+        if (getProperty(NOPE) != null)
+            return null;
+
+        String sub = getProperty(SUB);
+        if (sub != null && sub.trim().length() > 0)
+            error("Specified "
+                    + SUB
+                    + " but calls build() instead of builds() (might be a programmer error)");
+
+        if (getProperty(CONDUIT) != null)
+            error("Specified "
+                    + CONDUIT
+                    + " but calls build() instead of builds() (might be a programmer error");
+
+        dot = new Jar("dot");
+        addClose(dot);
+        try {
+            long modified = Long.parseLong(getProperty("base.modified"));
+            dot.updateModified(modified, "Base modified");
+        } catch (Exception e) {
+        }
+
+        doExpand(dot);
+        doIncludeResources(dot);
+
+        doConditional(dot);
+
+        // NEW!
+        // Check if we override the calculation of the
+        // manifest. We still need to calculated it because
+        // we need to have analyzed the classpath.
+
+        Manifest manifest = calcManifest();
+
+        String mf = getProperty(MANIFEST);
+        if (mf != null) {
+            File mff = getFile(mf);
+            if (mff.isFile()) {
+                try {
+                    InputStream in = new FileInputStream(mff);
+                    manifest = new Manifest(in);
+                    in.close();
+                } catch (Exception e) {
+                    error(MANIFEST + " while reading manifest file", e);
+                }
+            } else {
+                error(MANIFEST + ", no such file " + mf);
+            }
+        }
+
+        if (getProperty(NOMANIFEST) == null)
+            dot.setManifest(manifest);
+        else
+            dot.setNoManifest(true);
+
+        // This must happen after we analyzed so
+        // we know what it is on the classpath
+        addSources(dot);
+        if (getProperty(POM) != null)
+            doPom(dot);
+
+        doVerify(dot);
+
+        if (dot.getResources().isEmpty())
+            error("The JAR is empty");
+
+        dot.updateModified(lastModified(), "Last Modified Processor");
+        dot.setName(getBsn());
+
+        sign(dot);
+        return dot;
+    }
+
+    /**
+     * Sign the jar file.
+     * 
+     * -sign : <alias> [ ';' 'password:=' <password> ] [ ';' 'keystore:='
+     * <keystore> ] [ ';' 'sign-password:=' <pw> ] ( ',' ... )*
+     * 
+     * @return
+     */
+
+    void sign(Jar jar) throws Exception {
+        String signing = getProperty("-sign");
+        if (signing == null)
+            return;
+
+        trace("Signing %s, with %s", getBsn(), signing);
+        List<SignerPlugin> signers = getPlugins(SignerPlugin.class);
+
+        Map<String, Map<String, String>> infos = parseHeader(signing);
+        for (Map.Entry<String, Map<String, String>> entry : infos.entrySet()) {
+            for (SignerPlugin signer : signers) {
+                signer.sign(this, entry.getKey());
+            }
+        }
+    }
+
+    public boolean hasSources() {
+        return isTrue(getProperty(SOURCES));
+    }
+
+    protected String getImportPackages() {
+        String ip = super.getImportPackages();
+        if (ip != null)
+            return ip;
+
+        return "*";
+    }
+
+    private void doConditional(Jar dot) throws IOException {
+        Map<String, Map<String, String>> conditionals = getHeader(CONDITIONAL_PACKAGE);
+        int size;
+        do {
+            size = dot.getDirectories().size();
+            analyze();
+            analyzed = false;
+            Map<String, Map<String, String>> imports = getImports();
+
+            // Match the packages specified in conditionals
+            // against the imports. Any match must become a
+            // Private-Package
+            Map<String, Map<String, String>> filtered = merge(
+                    CONDITIONAL_PACKAGE, conditionals, imports,
+                    new HashSet<String>(), null);
+
+            // Imports can also specify a private import. These
+            // packages must also be copied to the bundle
+            for (Map.Entry<String, Map<String, String>> entry : getImports()
+                    .entrySet()) {
+                String type = entry.getValue().get(IMPORT_DIRECTIVE);
+                if (type != null && type.equals("private"))
+                    filtered.put(entry.getKey(), entry.getValue());
+            }
+
+            // remove existing packages to prevent merge errors
+            filtered.keySet().removeAll(dot.getPackages());
+            doExpand(dot, CONDITIONAL_PACKAGE + " Private imports",
+                    replaceWitInstruction(filtered, CONDITIONAL_PACKAGE), false);
+        } while (dot.getDirectories().size() > size);
+        analyzed = true;
+    }
+
+    /**
+     * Intercept the call to analyze and cleanup versions after we have analyzed
+     * the setup. We do not want to cleanup if we are going to verify.
+     */
+
+    public void analyze() throws IOException {
+        super.analyze();
+        cleanupVersion(imports);
+        cleanupVersion(exports);
+        String version = getProperty(BUNDLE_VERSION);
+        if (version != null)
+            setProperty(BUNDLE_VERSION, cleanupVersion(version));
+    }
+
+    public void cleanupVersion(Map<String, Map<String, String>> mapOfMap) {
+        for (Iterator<Map.Entry<String, Map<String, String>>> e = mapOfMap
+                .entrySet().iterator(); e.hasNext();) {
+            Map.Entry<String, Map<String, String>> entry = e.next();
+            Map<String, String> attributes = entry.getValue();
+            if (attributes.containsKey("version")) {
+                attributes.put("version", cleanupVersion(attributes
+                        .get("version")));
+            }
+        }
+    }
+
+    /**
+     * 
+     */
+    private void addSources(Jar dot) {
+        if (!hasSources())
+            return;
+
+        Set<String> packages = new HashSet<String>();
+
+        try {
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            getProperties().store(out, "Generated by BND, at " + new Date());
+            dot.putResource("OSGI-OPT/bnd.bnd", new EmbeddedResource(out
+                    .toByteArray(), 0));
+            out.close();
+        } catch (Exception e) {
+            error("Can not embed bnd file in JAR: " + e);
+        }
+
+        for (Iterator<String> cpe = classspace.keySet().iterator(); cpe
+                .hasNext();) {
+            String path = cpe.next();
+            path = path.substring(0, path.length() - ".class".length())
+                    + ".java";
+            String pack = getPackage(path).replace('.', '/');
+            if (pack.length() > 1)
+                pack = pack + "/";
+            boolean found = false;
+            String[] fixed = { "packageinfo", "package.html",
+                    "module-info.java", "package-info.java" };
+            for (Iterator<File> i = getSourcePath().iterator(); i.hasNext();) {
+                File root = i.next();
+                File f = getFile(root, path);
+                if (f.exists()) {
+                    found = true;
+                    if (!packages.contains(pack)) {
+                        packages.add(pack);
+                        File bdir = getFile(root, pack);
+                        for (int j = 0; j < fixed.length; j++) {
+                            File ff = getFile(bdir, fixed[j]);
+                            if (ff.isFile()) {
+                                dot.putResource("OSGI-OPT/src/" + pack
+                                        + fixed[j], new FileResource(ff));
+                            }
+                        }
+                    }
+                    dot
+                            .putResource("OSGI-OPT/src/" + path,
+                                    new FileResource(f));
+                }
+            }
+            if (!found) {
+                for (Jar jar : classpath) {
+                    Resource resource = jar.getResource(path);
+                    if (resource != null) {
+                        dot.putResource("OSGI-OPT/src", resource);
+                    } else {
+                        resource = jar.getResource("OSGI-OPT/src/" + path);
+                        if (resource != null) {
+                            dot.putResource("OSGI-OPT/src", resource);
+                        }
+                    }
+                }
+            }
+            if (getSourcePath().isEmpty())
+                warning("Including sources but " + SOURCEPATH
+                        + " does not contain any source directories ");
+            // TODO copy from the jars where they came from
+        }
+    }
+
+    boolean firstUse = true;
+
+    public Collection<File> getSourcePath() {
+        if (firstUse) {
+            firstUse = false;
+            String sp = getProperty(SOURCEPATH);
+            if (sp != null) {
+                Map<String, Map<String, String>> map = parseHeader(sp);
+                for (Iterator<String> i = map.keySet().iterator(); i.hasNext();) {
+                    String file = i.next();
+                    if (!isDuplicate(file)) {
+                        File f = getFile(file);
+                        if (!f.isDirectory()) {
+                            error("Adding a sourcepath that is not a directory: "
+                                    + f);
+                        } else {
+                            sourcePath.add(f);
+                        }
+                    }
+                }
+            }
+        }
+        return sourcePath;
+    }
+
+    private void doVerify(Jar dot) throws Exception {
+        Verifier verifier = new Verifier(dot, getProperties());
+        verifier.setPedantic(isPedantic());
+
+        // Give the verifier the benefit of our analysis
+        // prevents parsing the files twice
+        verifier.setClassSpace(classspace, contained, referred, uses);
+        verifier.verify();
+        getInfo(verifier);
+    }
+
+    private void doExpand(Jar jar) throws IOException {
+        if (getClasspath().size() == 0
+                && (getProperty(EXPORT_PACKAGE) != null || getProperty(PRIVATE_PACKAGE) != null))
+            warning("Classpath is empty. Private-Package and Export-Package can only expand from the classpath when there is one");
+
+        Map<Instruction, Map<String, String>> privateMap = replaceWitInstruction(
+                getHeader(PRIVATE_PACKAGE), PRIVATE_PACKAGE);
+        Map<Instruction, Map<String, String>> exportMap = replaceWitInstruction(
+                getHeader(EXPORT_PACKAGE), EXPORT_PACKAGE);
+
+        if (isTrue(getProperty(Constants.UNDERTEST))) {
+            privateMap.putAll(replaceWitInstruction(parseHeader(getProperty(
+                    Constants.TESTPACKAGES, "test;presence:=optional")),
+                    TESTPACKAGES));
+        }
+        if (!privateMap.isEmpty())
+            doExpand(jar, "Private-Package, or -testpackages", privateMap, true);
+
+        if (!exportMap.isEmpty()) {
+            Jar exports = new Jar("exports");
+            doExpand(exports, "Export-Package", exportMap, true);
+            jar.addAll(exports);
+            exports.close();
+        }
+
+        if (privateMap.isEmpty() && exportMap.isEmpty() && !isResourceOnly()) {
+            warning("Neither Export-Package, Private-Package, -testpackages is set, therefore no packages will be included");
+        }
+    }
+
+    /**
+     * 
+     * @param jar
+     * @param name
+     * @param instructions
+     */
+    private void doExpand(Jar jar, String name,
+            Map<Instruction, Map<String, String>> instructions,
+            boolean mandatory) {
+        Set<Instruction> superfluous = removeMarkedDuplicates(instructions
+                .keySet());
+
+        for (Iterator<Jar> c = getClasspath().iterator(); c.hasNext();) {
+            Jar now = c.next();
+            doExpand(jar, instructions, now, superfluous);
+        }
+
+        if (mandatory && superfluous.size() > 0) {
+            StringBuffer sb = new StringBuffer();
+            String del = "Instructions in " + name + " that are never used: ";
+            for (Iterator<Instruction> i = superfluous.iterator(); i.hasNext();) {
+                Instruction p = i.next();
+                sb.append(del);
+                sb.append(p.getPattern());
+                del = ", ";
+            }
+            warning(sb.toString());
+        }
+    }
+
+    /**
+     * Iterate over each directory in the class path entry and check if that
+     * directory is a desired package.
+     * 
+     * @param included
+     * @param classpathEntry
+     */
+    private void doExpand(Jar jar,
+            Map<Instruction, Map<String, String>> included, Jar classpathEntry,
+            Set<Instruction> superfluous) {
+
+        loop: for (Map.Entry<String, Map<String, Resource>> directory : classpathEntry
+                .getDirectories().entrySet()) {
+            String path = directory.getKey();
+
+            if (doNotCopy.matcher(getName(path)).matches())
+                continue;
+
+            if (directory.getValue() == null)
+                continue;
+
+            String pack = path.replace('/', '.');
+            Instruction instr = matches(included, pack, superfluous);
+            if (instr != null) {
+                // System.out.println("Pattern match: " + pack + " " +
+                // instr.getPattern() + " " + instr.isNegated());
+                if (!instr.isNegated()) {
+                    Map<String, Resource> contents = directory.getValue();
+
+                    // What to do with split packages? Well if this
+                    // directory already exists, we will check the strategy
+                    // and react accordingly.
+                    boolean overwriteResource = true;
+                    if (jar.hasDirectory(path)) {
+                        Map<String, String> directives = included.get(instr);
+
+                        switch (getSplitStrategy((String) directives
+                                .get(SPLIT_PACKAGE_DIRECTIVE))) {
+                        case SPLIT_MERGE_LAST:
+                            overwriteResource = true;
+                            break;
+
+                        case SPLIT_MERGE_FIRST:
+                            overwriteResource = false;
+                            break;
+
+                        case SPLIT_ERROR:
+                            error(diagnostic(pack, getClasspath(),
+                                    classpathEntry.source));
+                            continue loop;
+
+                        case SPLIT_FIRST:
+                            continue loop;
+
+                        default:
+                            warning(diagnostic(pack, getClasspath(),
+                                    classpathEntry.source));
+                            overwriteResource = false;
+                            break;
+                        }
+                    }
+
+                    jar.addDirectory(contents, overwriteResource);
+
+                    String key = path + "/bnd.info";
+                    Resource r = jar.getResource(key);
+                    if (r != null)
+                        jar.putResource(key, new PreprocessResource(this, r));
+
+                    if (hasSources()) {
+                        String srcPath = "OSGI-OPT/src/" + path;
+                        Map<String, Resource> srcContents = classpathEntry
+                                .getDirectories().get(srcPath);
+                        if (srcContents != null) {
+                            jar.addDirectory(srcContents, overwriteResource);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Analyze the classpath for a split package
+     * 
+     * @param pack
+     * @param classpath
+     * @param source
+     * @return
+     */
+    private String diagnostic(String pack, List<Jar> classpath, File source) {
+        // Default is like merge-first, but with a warning
+        // Find the culprits
+        pack = pack.replace('.', '/');
+        List<Jar> culprits = new ArrayList<Jar>();
+        for (Iterator<Jar> i = classpath.iterator(); i.hasNext();) {
+            Jar culprit = (Jar) i.next();
+            if (culprit.getDirectories().containsKey(pack)) {
+                culprits.add(culprit);
+            }
+        }
+        return "Split package "
+                + pack
+                + "\nUse directive -split-package:=(merge-first|merge-last|error|first) on Export/Private Package instruction to get rid of this warning\n"
+                + "Package found in   " + culprits + "\n"
+                + "Reference from     " + source + "\n" + "Classpath          "
+                + classpath;
+    }
+
+    private int getSplitStrategy(String type) {
+        if (type == null)
+            return SPLIT_DEFAULT;
+
+        if (type.equals("merge-last"))
+            return SPLIT_MERGE_LAST;
+
+        if (type.equals("merge-first"))
+            return SPLIT_MERGE_FIRST;
+
+        if (type.equals("error"))
+            return SPLIT_ERROR;
+
+        if (type.equals("first"))
+            return SPLIT_FIRST;
+
+        error("Invalid strategy for split-package: " + type);
+        return SPLIT_DEFAULT;
+    }
+
+    private Map<Instruction, Map<String, String>> replaceWitInstruction(
+            Map<String, Map<String, String>> header, String type) {
+        Map<Instruction, Map<String, String>> map = newMap();
+        for (Iterator<Map.Entry<String, Map<String, String>>> e = header
+                .entrySet().iterator(); e.hasNext();) {
+            Map.Entry<String, Map<String, String>> entry = e.next();
+            String pattern = entry.getKey();
+            Instruction instr = Instruction.getPattern(pattern);
+            String presence = entry.getValue().get(PRESENCE_DIRECTIVE);
+            if ("optional".equals(presence))
+                instr.setOptional();
+            map.put(instr, entry.getValue());
+        }
+        return map;
+    }
+
+    private Instruction matches(
+            Map<Instruction, Map<String, String>> instructions, String pack,
+            Set<Instruction> superfluousPatterns) {
+        for (Instruction pattern : instructions.keySet()) {
+            if (pattern.matches(pack)) {
+                superfluousPatterns.remove(pattern);
+                return pattern;
+            }
+        }
+        return null;
+    }
+
+    private Map<String, Map<String, String>> getHeader(String string) {
+        if (string == null)
+            return Collections.emptyMap();
+        return parseHeader(getProperty(string));
+    }
+
+    /**
+     * Parse the Bundle-Includes header. Files in the bundles Include header are
+     * included in the jar. The source can be a directory or a file.
+     * 
+     * @throws IOException
+     * @throws FileNotFoundException
+     */
+    private void doIncludeResources(Jar jar) throws Exception {
+        String includes = getProperty("Bundle-Includes");
+        if (includes == null) {
+            includes = getProperty(INCLUDERESOURCE);
+            if (includes == null)
+                includes = getProperty("Include-Resource");
+        } else
+            warning("Please use -includeresource instead of Bundle-Includes");
+
+        if (includes == null)
+            return;
+
+        Map<String, Map<String, String>> clauses = parseHeader(includes);
+
+        for (Iterator<Map.Entry<String, Map<String, String>>> i = clauses
+                .entrySet().iterator(); i.hasNext();) {
+            Map.Entry<String, Map<String, String>> entry = i.next();
+            doIncludeResource(jar, entry.getKey(), entry.getValue());
+        }
+    }
+
+    private void doIncludeResource(Jar jar, String name,
+            Map<String, String> extra) throws ZipException, IOException,
+            Exception {
+        boolean preprocess = false;
+        if (name.startsWith("{") && name.endsWith("}")) {
+            preprocess = true;
+            name = name.substring(1, name.length() - 1).trim();
+        }
+
+        if (name.startsWith("@")) {
+            extractFromJar(jar, name.substring(1));
+        } else
+        /*
+         * NEW
+         */
+        if (extra.containsKey("literal")) {
+            String literal = (String) extra.get("literal");
+            Resource r = new EmbeddedResource(literal.getBytes("UTF-8"), 0);
+            String x = (String) extra.get("extra");
+            if (x != null)
+                r.setExtra(x);
+            jar.putResource(name, r);
+        } else {
+            String source;
+            File sourceFile;
+            String destinationPath;
+
+            String parts[] = name.split("\\s*=\\s*");
+            if (parts.length == 1) {
+                // Just a copy, destination path defined by
+                // source path.
+                source = parts[0];
+                sourceFile = getFile(source);
+                // Directories should be copied to the root
+                // but files to their file name ...
+                if (sourceFile.isDirectory())
+                    destinationPath = "";
+                else
+                    destinationPath = sourceFile.getName();
+            } else {
+                source = parts[1];
+                sourceFile = getFile(source);
+                destinationPath = parts[0];
+                
+                // Handle directives
+                if (sourceFile.isDirectory()) {
+                	String filter = extra.get("filter:");
+            		boolean flatten = isTrue(extra.get("flatten:"));
+            		boolean recursive = true; 
+            		String directive = extra.get("recursive:");
+            		if (directive != null) {
+            			recursive = isTrue(directive);
+            		}
+
+            		InstructionFilter iFilter = null;
+            		if (filter != null) {
+            			iFilter = new InstructionFilter(Instruction.getPattern(filter), recursive);
+            		} else {
+            			iFilter = new InstructionFilter(null, recursive);
+            		}
+                    
+            		destinationPath = checkDestinationPath(destinationPath);
+
+            		File[] files = resolveFiles(sourceFile, iFilter, recursive);
+            		for (File file : files) {
+            			String dp;
+            			if (flatten) {
+	            			if (destinationPath.length() == 0) {
+	            				dp = file.getName();
+	            			} else {
+	                			dp = destinationPath + File.separator + file.getName();
+	            			}
+            			} else {
+            				dp = destinationPath + file.getParentFile().getAbsolutePath().substring(sourceFile.getAbsolutePath().length());
+            				if (dp.length() > 0) {
+            					dp += File.separator + file.getName();
+            				} else {
+            					dp = file.getName();
+            				}
+            			} 
+        				copy(jar, dp, file, preprocess, extra);
+            		}
+            		return;
+                }
+            }
+        	
+            destinationPath = checkDestinationPath(destinationPath);
+
+            if (!sourceFile.exists()) {
+                noSuchFile(jar, name, extra, source, destinationPath);
+            } else
+                copy(jar, destinationPath, sourceFile, preprocess, extra);
+         }
+    }
+    
+    private String checkDestinationPath(String destinationPath) {
+        
+    	// Some people insist on ending a directory with
+        // a slash ... it now also works if you do /=dir
+        if (destinationPath.endsWith("/"))
+            destinationPath = destinationPath.substring(0, destinationPath
+                    .length() - 1);
+        return destinationPath;
+    }
+    
+    private File[] resolveFiles(File dir, FileFilter filter, boolean recursive) {
+    	return resolveFiles(dir, filter, null, recursive);
+    }
+
+    private File[] resolveFiles(File dir, FileFilter filter,  File[] files, boolean recursive) {
+    	if (files == null) {
+    		files = EMPTY_FILE;
+    	}
+    	
+    	if (Analyzer.doNotCopy.matcher(dir.getName()).matches()) {
+    		return files;
+    	}
+    	
+    	File[] fs = dir.listFiles(filter);
+    	for (File file : fs) {
+    		if (file.isDirectory()) {
+    			if (recursive) {
+	    			files = resolveFiles(file, filter, files, recursive);
+    			}
+    		} else {
+				if (files.length == 0) {
+					files = new File[] { file };
+				} else {
+					File[] newFiles = new File[files.length + 1];
+					System.arraycopy(files, 0, newFiles, 0, files.length);
+					newFiles[newFiles.length - 1] = file;
+					files = newFiles;
+				}
+    		}
+    	}
+    	return files;
+    }
+
+    private void noSuchFile(Jar jar, String clause, Map<String, String> extra,
+            String source, String destinationPath) throws Exception {
+        Jar src = getJarFromName(source, "Include-Resource " + source);
+        if (src != null) {
+            JarResource jarResource = new JarResource(src);
+            jar.putResource(destinationPath, jarResource);
+        } else {
+            Resource lastChance = make.process(source);
+            if (lastChance != null) {
+                String x = extra.get("extra");
+                if ( x != null )
+                    lastChance.setExtra(x);
+                jar.putResource(destinationPath, lastChance);
+            } else
+                error("Input file does not exist: " + source);
+        }
+    }
+
+    /**
+     * Extra resources from a Jar and add them to the given jar. The clause is
+     * the
+     * 
+     * @param jar
+     * @param clauses
+     * @param i
+     * @throws ZipException
+     * @throws IOException
+     */
+    private void extractFromJar(Jar jar, String name) throws ZipException,
+            IOException {
+        // Inline all resources and classes from another jar
+        // optionally appended with a modified regular expression
+        // like @zip.jar!/META-INF/MANIFEST.MF
+        int n = name.lastIndexOf("!/");
+        Pattern filter = null;
+        if (n > 0) {
+            String fstring = name.substring(n + 2);
+            name = name.substring(0, n);
+            filter = wildcard(fstring);
+        }
+        Jar sub = getJarFromName(name, "extract from jar");
+        if (sub == null)
+            error("Can not find JAR file " + name);
+        else
+            jar.addAll(sub, filter);
+    }
+
+    private Pattern wildcard(String spec) {
+        StringBuffer sb = new StringBuffer();
+        for (int j = 0; j < spec.length(); j++) {
+            char c = spec.charAt(j);
+            switch (c) {
+            case '.':
+                sb.append("\\.");
+                break;
+
+            case '*':
+                // test for ** (all directories)
+                if (j < spec.length() - 1 && spec.charAt(j + 1) == '*') {
+                    sb.append(".*");
+                    j++;
+                } else
+                    sb.append("[^/]*");
+                break;
+            default:
+                sb.append(c);
+                break;
+            }
+        }
+        String s = sb.toString();
+        try {
+            return Pattern.compile(s);
+        } catch (Exception e) {
+            error("Invalid regular expression on wildcarding: " + spec
+                    + " used *");
+        }
+        return null;
+    }
+
+    private void copy(Jar jar, String path, File from, boolean preprocess,
+            Map<String, String> extra) throws Exception {
+        if (doNotCopy.matcher(from.getName()).matches())
+            return;
+
+        if (from.isDirectory()) {
+            String next = path;
+            if (next.length() != 0)
+                next += '/';
+
+            File files[] = from.listFiles();
+            for (int i = 0; i < files.length; i++) {
+                copy(jar, next + files[i].getName(), files[i], preprocess,
+                        extra);
+            }
+        } else {
+            if (from.exists()) {
+                Resource resource = new FileResource(from);
+                if (preprocess) {
+                    resource = new PreprocessResource(this, resource);
+                }
+                String x = extra.get("extra");
+                if (x != null)
+                    resource.setExtra(x);
+                jar.putResource(path, resource);
+            } else {
+                error("Input file does not exist: " + from);
+            }
+        }
+    }
+
+    private String getName(String where) {
+        int n = where.lastIndexOf('/');
+        if (n < 0)
+            return where;
+
+        return where.substring(n + 1);
+    }
+
+    public void setSourcepath(File[] files) {
+        for (int i = 0; i < files.length; i++)
+            addSourcepath(files[i]);
+    }
+
+    public void addSourcepath(File cp) {
+        if (!cp.exists())
+            warning("File on sourcepath that does not exist: " + cp);
+
+        sourcePath.add(cp);
+    }
+
+    /**
+     * Create a POM reseource for Maven containing as much information as
+     * possible from the manifest.
+     * 
+     * @param output
+     * @param builder
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    public void doPom(Jar dot) throws FileNotFoundException, IOException {
+        {
+            Manifest manifest = dot.getManifest();
+            String name = manifest.getMainAttributes().getValue(
+                    Analyzer.BUNDLE_NAME);
+            String description = manifest.getMainAttributes().getValue(
+                    Analyzer.BUNDLE_DESCRIPTION);
+            String docUrl = manifest.getMainAttributes().getValue(
+                    Analyzer.BUNDLE_DOCURL);
+            String version = manifest.getMainAttributes().getValue(
+                    Analyzer.BUNDLE_VERSION);
+            String bundleVendor = manifest.getMainAttributes().getValue(
+                    Analyzer.BUNDLE_VENDOR);
+            ByteArrayOutputStream s = new ByteArrayOutputStream();
+            PrintStream ps = new PrintStream(s);
+            String bsn = manifest.getMainAttributes().getValue(
+                    Analyzer.BUNDLE_SYMBOLICNAME);
+            String licenses = manifest.getMainAttributes().getValue(
+                    BUNDLE_LICENSE);
+
+            if (bsn == null) {
+                error("Can not create POM unless Bundle-SymbolicName is set");
+                return;
+            }
+
+            bsn = bsn.trim();
+            int n = bsn.lastIndexOf('.');
+            if (n <= 0) {
+                error("Can not create POM unless Bundle-SymbolicName contains a .");
+                ps.close();
+                s.close();
+                return;
+            }
+            String groupId = bsn.substring(0, n);
+            String artifactId = bsn.substring(n + 1);
+            ps
+                    .println("<project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'>");
+            ps.println("  <modelVersion>4.0.0</modelVersion>");
+            ps.println("  <groupId>" + groupId + "</groupId>");
+
+            n = artifactId.indexOf(';');
+            if (n > 0)
+                artifactId = artifactId.substring(0, n).trim();
+
+            ps.println("  <artifactId>" + artifactId + "</artifactId>");
+            ps.println("  <version>" + version + "</version>");
+            if (description != null) {
+                ps.println("  <description>");
+                ps.print("    ");
+                ps.println(description);
+                ps.println("  </description>");
+            }
+            if (name != null) {
+                ps.print("  <name>");
+                ps.print(name);
+                ps.println("</name>");
+            }
+            if (docUrl != null) {
+                ps.print("  <url>");
+                ps.print(docUrl);
+                ps.println("</url>");
+            }
+
+            if (bundleVendor != null) {
+                Matcher m = NAME_URL.matcher(bundleVendor);
+                String namePart = bundleVendor;
+                String urlPart = null;
+                if (m.matches()) {
+                    namePart = m.group(1);
+                    urlPart = m.group(2);
+                }
+                ps.println("  <organization>");
+                ps.print("    <name>");
+                ps.print(namePart.trim());
+                ps.println("</name>");
+                if (urlPart != null) {
+                    ps.print("    <url>");
+                    ps.print(urlPart.trim());
+                    ps.println("</url>");
+                }
+                ps.println("  </organization>");
+            }
+            if (licenses != null) {
+                ps.println("  <licenses>");
+                Map<String, Map<String, String>> map = parseHeader(licenses);
+                for (Iterator<Map.Entry<String, Map<String, String>>> e = map
+                        .entrySet().iterator(); e.hasNext();) {
+                    Map.Entry<String, Map<String, String>> entry = e.next();
+                    ps.println("    <license>");
+                    Map<String, String> values = entry.getValue();
+                    print(ps, values, "name", "name", (String) values
+                            .get("url"));
+                    print(ps, values, "url", "url", null);
+                    print(ps, values, "distribution", "distribution", "repo");
+                    ps.println("    </license>");
+                }
+                ps.println("  </licenses>");
+            }
+            ps.println("</project>");
+            ps.close();
+            s.close();
+            dot
+                    .putResource("pom.xml", new EmbeddedResource(s
+                            .toByteArray(), 0));
+        }
+    }
+
+    /**
+     * Utility function to print a tag from a map
+     * 
+     * @param ps
+     * @param values
+     * @param string
+     * @param tag
+     * @param object
+     */
+    private void print(PrintStream ps, Map<String, String> values,
+            String string, String tag, String object) {
+        String value = (String) values.get(string);
+        if (value == null)
+            value = object;
+        if (value == null)
+            return;
+        ps.println("    <" + tag + ">" + value.trim() + "</" + tag + ">");
+    }
+
+    public void close() {
+        super.close();
+    }
+
+    /**
+     * Build Multiple jars. If the -sub command is set, we filter the file with
+     * the given patterns.
+     * 
+     * @return
+     * @throws Exception
+     */
+    public Jar[] builds() throws Exception {
+        begin();
+
+        // Are we acting as a conduit for another JAR?
+        String conduit = getProperty(CONDUIT);
+        if (conduit != null) {
+            Map<String, Map<String, String>> map = parseHeader(conduit);
+            Jar[] result = new Jar[map.size()];
+            int n = 0;
+            for (String file : map.keySet()) {
+                Jar c = new Jar(getFile(file));
+                addClose(c);
+                String name = map.get(file).get("name");
+                if (name != null)
+                    c.setName(name);
+
+                result[n++] = c;
+            }
+            return result;
+        }
+
+        // If no -sub property, then reuse this builder object
+        // other wise, build all the sub parts.
+        String sub = getProperty(SUB);
+        if (sub == null) {
+            Jar jar = build();
+            if (jar == null)
+                return new Jar[0];
+
+            return new Jar[] { jar };
+        }
+
+        List<Jar> result = new ArrayList<Jar>();
+
+        // Get the Instruction objects that match the sub header
+        Set<Instruction> subs = replaceWitInstruction(parseHeader(sub), SUB)
+                .keySet();
+
+        // Get the member files of this directory
+        List<File> members = new ArrayList<File>(Arrays.asList(getBase()
+                .listFiles()));
+
+        getProperties().remove(SUB);
+        // For each member file
+        nextFile: while (members.size() > 0) {
+
+            File file = members.remove(0);
+            if (file.equals(getPropertiesFile()))
+                continue nextFile;
+
+            for (Iterator<Instruction> i = subs.iterator(); i.hasNext();) {
+
+                Instruction instruction = i.next();
+                if (instruction.matches(file.getName())) {
+
+                    if (!instruction.isNegated()) {
+
+                        Builder builder = null;
+                        try {
+                            builder = getSubBuilder();
+                            addClose(builder);
+                            builder.setProperties(file);
+                            builder.setProperty(SUB, "");
+                            // Recursively build
+                            // TODO
+                            Jar jar = builder.build();
+                            jar.setName(builder.getBsn());
+                            result.add(jar);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            error("Sub Building " + file, e);
+                        }
+                        if (builder != null)
+                            getInfo(builder, file.getName() + ": ");
+                    }
+
+                    // Because we matched (even though we could be negated)
+                    // we skip any remaining searches
+                    continue nextFile;
+                }
+            }
+        }
+        setProperty(SUB, sub);
+        return result.toArray(new Jar[result.size()]);
+    }
+
+    public Builder getSubBuilder() throws Exception {
+        Builder builder = new Builder(this);
+        builder.setBase(getBase());
+
+        for (Jar file : getClasspath()) {
+            builder.addClasspath(file);
+        }
+
+        return builder;
+    }
+
+    /**
+     * A macro to convert a maven version to an OSGi version
+     */
+
+    public String _maven_version(String args[]) {
+        if (args.length > 2)
+            error("${maven_version} macro receives too many arguments "
+                    + Arrays.toString(args));
+        else if (args.length < 2)
+            error("${maven_version} macro has no arguments, use ${maven_version;1.2.3-SNAPSHOT}");
+        else {
+            return cleanupVersion(args[1]);
+        }
+        return null;
+    }
+
+    public String _permissions(String args[]) throws IOException {
+        StringBuilder sb = new StringBuilder();
+
+        for (String arg : args) {
+            if ("packages".equals(arg) || "all".equals(arg)) {
+                for (String imp : getImports().keySet()) {
+                    if (!imp.startsWith("java.")) {
+                        sb.append("(org.osgi.framework.PackagePermission \"");
+                        sb.append(imp);
+                        sb.append("\" \"import\")\r\n");
+                    }
+                }
+                for (String exp : getExports().keySet()) {
+                    sb.append("(org.osgi.framework.PackagePermission \"");
+                    sb.append(exp);
+                    sb.append("\" \"export\")\r\n");
+                }
+            } else if ("admin".equals(arg) || "all".equals(arg)) {
+                sb.append("(org.osgi.framework.AdminPermission)");
+            } else if ("permissions".equals(arg))
+                ;
+            else
+                error("Invalid option in ${permissions}: %s", arg);
+        }
+        return sb.toString();
+    }
+
+    public void removeBundleSpecificHeaders() {
+        Set<String> set = new HashSet<String>(Arrays
+                .asList(BUNDLE_SPECIFIC_HEADERS));
+        setForceLocal(set);
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/ClassDataCollector.java b/bundleplugin/src/main/java/aQute/lib/osgi/ClassDataCollector.java
new file mode 100644
index 0000000..e09e00f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/ClassDataCollector.java
@@ -0,0 +1,11 @@
+package aQute.lib.osgi;
+
+public interface ClassDataCollector {
+    void classBegin(int access, String name);
+    void extendsClass(String name);
+    void implementsInterfaces(String name[]);
+    void field(int access, String descriptor);
+    void method(int access, String descriptor);
+    void addReference(String token);
+    void classEnd();
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Clazz.java b/bundleplugin/src/main/java/aQute/lib/osgi/Clazz.java
new file mode 100644
index 0000000..93fe6ac
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Clazz.java
@@ -0,0 +1,832 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+
+public class Clazz {
+    public static enum QUERY {
+        IMPLEMENTS, EXTENDS, IMPORTS, NAMED, ANY, VERSION
+    };
+
+    static protected class Assoc {
+        Assoc(byte tag, int a, int b) {
+            this.tag = tag;
+            this.a = a;
+            this.b = b;
+        }
+
+        byte tag;
+        int  a;
+        int  b;
+    }
+
+    final 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
+                                                 };
+
+    String                           className;
+    Object                           pool[];
+    int                              intPool[];
+    Map<String, Map<String, String>> imports     = new HashMap<String, Map<String, String>>();
+    String                           path;
+
+    // static String type = "([BCDFIJSZ\\[]|L[^<>]+;)";
+    // static Pattern descriptor = Pattern.compile("\\(" + type + "*\\)(("
+    // + type + ")|V)");
+    int                              minor       = 0;
+    int                              major       = 0;
+
+    String                           sourceFile;
+    Set<String>                      xref;
+    Set<Integer>                     classes;
+    Set<Integer>                     descriptors;
+    int                              forName     = 0;
+    int                              class$      = 0;
+    String[]                         interfaces;
+    String                           zuper;
+    ClassDataCollector               cd          = new ClassDataCollector() {
+                                                     public void addReference(
+                                                             String token) {
+                                                     }
+
+                                                     public void classBegin(
+                                                             int access,
+                                                             String name) {
+                                                     }
+
+                                                     public void classEnd() {
+                                                     }
+
+                                                     public void extendsClass(
+                                                             String name) {
+                                                     }
+
+                                                     public void field(
+                                                             int access,
+                                                             String descriptor) {
+                                                     }
+
+                                                     public void implementsInterfaces(
+                                                             String[] name) {
+                                                     }
+
+                                                     public void method(
+                                                             int access,
+                                                             String descriptor) {
+                                                     }
+                                                 };
+
+    public Clazz(String path) {
+        this.path = path;
+    }
+
+    public Clazz(String path, InputStream in) throws IOException {
+        this.path = path;
+        DataInputStream din = new DataInputStream(in);
+        parseClassFile(din);
+        din.close();
+    }
+
+    Set<String> parseClassFile(DataInputStream in) throws IOException {
+
+        xref = new HashSet<String>();
+        classes = new HashSet<Integer>();
+        descriptors = new HashSet<Integer>();
+
+        boolean crawl = false; // Crawl the byte code
+        int magic = in.readInt();
+        if (magic != 0xCAFEBABE)
+            throw new IOException("Not a valid class file (no CAFEBABE header)");
+
+        minor = in.readUnsignedShort(); // minor version
+        major = in.readUnsignedShort(); // major version
+        int count = in.readUnsignedShort();
+        pool = new Object[count];
+        intPool = new int[count];
+
+        process: for (int poolIndex = 1; poolIndex < count; poolIndex++) {
+            byte tag = in.readByte();
+            switch (tag) {
+            case 0:
+                break process;
+            case 1:
+                constantUtf8(in, poolIndex);
+                break;
+
+            // For some insane optimization reason are
+            // the long and the double two entries in the
+            // constant pool. See 4.4.5
+            case 5:
+                constantLong(in, poolIndex);
+                poolIndex++;
+                break;
+
+            case 6:
+                constantDouble(in, poolIndex);
+                poolIndex++;
+                break;
+
+            case 7:
+                constantClass(in, poolIndex);
+                break;
+
+            case 8:
+                constantString(in, poolIndex);
+                break;
+
+            case 10: // Method ref
+                methodRef(in, poolIndex);
+                break;
+
+            // Name and Type
+            case 12:
+                nameAndType(in, poolIndex, tag);
+                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;
+            }
+        }
+
+        pool(pool, intPool);
+        /*
+         * Parse after the constant pool, code thanks to Hans Christian
+         * Falkenberg
+         */
+
+        int access_flags = in.readUnsignedShort(); // access
+        int this_class = in.readUnsignedShort();
+        className = (String) pool[intPool[this_class]];
+        cd.classBegin(access_flags, className);
+
+        try {
+
+            int super_class = in.readUnsignedShort();
+            zuper = (String) pool[intPool[super_class]];
+            if (zuper != null) {
+                addReference(zuper);
+                cd.extendsClass(zuper);
+            }
+
+            int interfacesCount = in.readUnsignedShort();
+            if (interfacesCount > 0) {
+                interfaces = new String[interfacesCount];
+                for (int i = 0; i < interfacesCount; i++)
+                    interfaces[i] = (String) pool[intPool[in
+                            .readUnsignedShort()]];
+                cd.implementsInterfaces(interfaces);
+            }
+
+            int fieldsCount = in.readUnsignedShort();
+            for (int i = 0; i < fieldsCount; i++) {
+                access_flags = in.readUnsignedShort(); // skip access flags
+                int name_index = in.readUnsignedShort();
+                int descriptor_index = in.readUnsignedShort();
+
+                // Java prior to 1.5 used a weird
+                // static variable to hold the com.X.class
+                // result construct. If it did not find it
+                // it would create a variable class$com$X
+                // that would be used to hold the class
+                // object gotten with Class.forName ...
+                // Stupidly, they did not actively use the
+                // class name for the field type, so bnd
+                // would not see a reference. We detect
+                // this case and add an artificial descriptor
+                String name = pool[name_index].toString(); // name_index
+                if (name.startsWith("class$")) {
+                    crawl = true;
+                }
+                cd.field(access_flags, pool[descriptor_index].toString());
+                descriptors.add(new Integer(descriptor_index));
+                doAttributes(in, false);
+            }
+
+            //
+            // Check if we have to crawl the code to find
+            // the ldc(_w) <string constant> invokestatic Class.forName
+            // if so, calculate the method ref index so we
+            // can do this efficiently
+            //
+            if (crawl) {
+                forName = findMethod("java/lang/Class", "forName",
+                        "(Ljava/lang/String;)Ljava/lang/Class;");
+                class$ = findMethod(className, "class$",
+                        "(Ljava/lang/String;)Ljava/lang/Class;");
+            }
+
+            //
+            // Handle the methods
+            //
+            int methodCount = in.readUnsignedShort();
+            for (int i = 0; i < methodCount; i++) {
+                access_flags = in.readUnsignedShort();
+                /* int name_index = */in.readUnsignedShort();
+                int descriptor_index = in.readUnsignedShort();
+                // String s = (String) pool[name_index];
+                descriptors.add(new Integer(descriptor_index));
+                if ( pool[descriptor_index ] == null ) {
+                    System.out.println("Value in pool=null, descriptor_index=" +descriptor_index);
+                }
+                cd.method(access_flags, pool[descriptor_index].toString());
+                doAttributes(in, crawl);
+            }
+
+            doAttributes(in, false);
+
+            //
+            // Now iterate over all classes we found and
+            // parse those as well. We skip duplicates
+            //
+
+            for (Iterator<Integer> e = classes.iterator(); e.hasNext();) {
+                int class_index = e.next().intValue();
+                doClassReference((String) pool[class_index]);
+            }
+
+            //
+            // Parse all the descriptors we found
+            //
+
+            for (Iterator<Integer> e = descriptors.iterator(); e.hasNext();) {
+                Integer index = e.next();
+                String prototype = (String) pool[index.intValue()];
+                if (prototype != null)
+                    parseDescriptor(prototype);
+                else
+                    System.err.println("Unrecognized descriptor: " + index);
+            }
+            Set<String> xref = this.xref;
+            reset();
+            return xref;
+        } finally {
+            cd.classEnd();
+        }
+    }
+
+    protected void pool(Object[] pool, int[] intPool) {
+    }
+
+    /**
+     * @param in
+     * @param poolIndex
+     * @param tag
+     * @throws IOException
+     */
+    protected void nameAndType(DataInputStream in, int poolIndex, byte tag)
+            throws IOException {
+        int name_index = in.readUnsignedShort();
+        int descriptor_index = in.readUnsignedShort();
+        descriptors.add(new Integer(descriptor_index));
+        pool[poolIndex] = new Assoc(tag, name_index, descriptor_index);
+    }
+
+    /**
+     * @param in
+     * @param poolIndex
+     * @param tag
+     * @throws IOException
+     */
+    private void methodRef(DataInputStream in, int poolIndex)
+            throws IOException {
+        int class_index = in.readUnsignedShort();
+        int name_and_type_index = in.readUnsignedShort();
+        pool[poolIndex] = new Assoc((byte) 10, class_index, name_and_type_index);
+    }
+
+    /**
+     * @param in
+     * @param poolIndex
+     * @throws IOException
+     */
+    private void constantString(DataInputStream in, int poolIndex)
+            throws IOException {
+        int string_index = in.readUnsignedShort();
+        intPool[poolIndex] = string_index;
+    }
+
+    /**
+     * @param in
+     * @param poolIndex
+     * @throws IOException
+     */
+    protected void constantClass(DataInputStream in, int poolIndex)
+            throws IOException {
+        int class_index = in.readUnsignedShort();
+        classes.add(new Integer(class_index));
+        intPool[poolIndex] = class_index;
+    }
+
+    /**
+     * @param in
+     * @throws IOException
+     */
+    protected void constantDouble(DataInputStream in, int poolIndex)
+            throws IOException {
+        in.skipBytes(8);
+    }
+
+    /**
+     * @param in
+     * @throws IOException
+     */
+    protected void constantLong(DataInputStream in, int poolIndex)
+            throws IOException {
+        in.skipBytes(8);
+    }
+
+    /**
+     * @param in
+     * @param poolIndex
+     * @throws IOException
+     */
+    protected void constantUtf8(DataInputStream in, int poolIndex)
+            throws IOException {
+        // CONSTANT_Utf8
+
+        String name = in.readUTF();
+        xref.add(name);
+        pool[poolIndex] = name;
+    }
+
+    /**
+     * Find a method reference in the pool that points to the given class,
+     * methodname and descriptor.
+     * 
+     * @param clazz
+     * @param methodname
+     * @param descriptor
+     * @return index in constant pool
+     */
+    private int findMethod(String clazz, String methodname, String descriptor) {
+        for (int i = 1; i < pool.length; i++) {
+            if (pool[i] instanceof Assoc) {
+                Assoc methodref = (Assoc) pool[i];
+                if (methodref.tag == 10) {
+                    // Method ref
+                    int class_index = methodref.a;
+                    int class_name_index = intPool[class_index];
+                    if (clazz.equals(pool[class_name_index])) {
+                        int name_and_type_index = methodref.b;
+                        Assoc name_and_type = (Assoc) pool[name_and_type_index];
+                        if (name_and_type.tag == 12) {
+                            // Name and Type
+                            int name_index = name_and_type.a;
+                            int type_index = name_and_type.b;
+                            if (methodname.equals(pool[name_index])) {
+                                if (descriptor.equals(pool[type_index])) {
+                                    return i;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return -1;
+    }
+
+    private void doClassReference(String next) {
+        if (next != null) {
+            String normalized = normalize(next);
+            if (normalized != null) {
+                cd.addReference(next);
+                String pack = getPackage(normalized);
+                packageReference(pack);
+            }
+        } else
+            throw new IllegalArgumentException("Invalid class, parent=");
+    }
+
+    /**
+     * Called for each attribute in the class, field, or method.
+     * 
+     * @param in
+     *            The stream
+     * @throws IOException
+     */
+    private void doAttributes(DataInputStream in, boolean crawl)
+            throws IOException {
+        int attributesCount = in.readUnsignedShort();
+        for (int j = 0; j < attributesCount; j++) {
+            // skip name CONSTANT_Utf8 pointer
+            doAttribute(in, crawl);
+        }
+    }
+
+    /**
+     * Process a single attribute, if not recognized, skip it.
+     * 
+     * @param in
+     *            the data stream
+     * @throws IOException
+     */
+    private void doAttribute(DataInputStream in, boolean crawl)
+            throws IOException {
+        int attribute_name_index = in.readUnsignedShort();
+        String attributeName = (String) pool[attribute_name_index];
+        long attribute_length = in.readInt();
+        attribute_length &= 0xFFFFFFFF;
+        if ("RuntimeVisibleAnnotations".equals(attributeName))
+            doAnnotations(in);
+        else if ("RuntimeVisibleParameterAnnotations".equals(attributeName))
+            doParameterAnnotations(in);
+        else if ("SourceFile".equals(attributeName))
+            doSourceFile(in);
+        else if ("Code".equals(attributeName) && crawl)
+            doCode(in);
+//        else if ("Signature".equals(attributeName))
+//            doSignature(in);
+        else {
+            if (attribute_length > 0x7FFFFFFF) {
+                throw new IllegalArgumentException("Attribute > 2Gb");
+            }
+            in.skipBytes((int) attribute_length);
+        }
+    }
+
+    /**
+     * Handle a signature
+     * 
+     * <pre>
+     * Signature_attribute { 
+     *     u2 attribute_name_index; 
+     *     u4 attribute_length; 
+     *     u2 signature_index; 
+     *     } 
+     * </pre>
+     */
+
+//    void doSignature(DataInputStream in) throws IOException {
+//        /*int attribute_length =*/ in.readInt();
+//        int signature_index = in.readUnsignedShort();
+//        String signature = (String) pool[signature_index];        
+//    }
+
+    /**
+     * <pre>
+     * Code_attribute {
+     * 		u2 attribute_name_index;
+     * 		u4 attribute_length;
+     * 		u2 max_stack;
+     * 		u2 max_locals;
+     * 		u4 code_length;
+     * 		u1 code[code_length];
+     * 		u2 exception_table_length;
+     * 		{    	u2 start_pc;
+     * 		      	u2 end_pc;
+     * 		      	u2  handler_pc;
+     * 		      	u2  catch_type;
+     * 		}	exception_table[exception_table_length];
+     * 		u2 attributes_count;
+     * 		attribute_info attributes[attributes_count];
+     * 	}
+     * </pre>
+     * 
+     * @param in
+     * @param pool
+     * @throws IOException
+     */
+    private void doCode(DataInputStream in) throws IOException {
+        /* int max_stack = */in.readUnsignedShort();
+        /* int max_locals = */in.readUnsignedShort();
+        int code_length = in.readInt();
+        byte code[] = new byte[code_length];
+        in.readFully(code);
+        crawl(code);
+        int exception_table_length = in.readUnsignedShort();
+        in.skipBytes(exception_table_length * 8);
+        doAttributes(in, false);
+    }
+
+    /**
+     * We must find Class.forName references ...
+     * 
+     * @param code
+     */
+    protected void crawl(byte[] code) {
+        ByteBuffer bb = ByteBuffer.wrap(code);
+        bb.order(ByteOrder.BIG_ENDIAN);
+        int lastReference = -1;
+
+        while (bb.remaining() > 0) {
+            int instruction = 0xFF & bb.get();
+            switch (instruction) {
+            case OpCodes.ldc:
+                lastReference = 0xFF & bb.get();
+                break;
+
+            case OpCodes.ldc_w:
+                lastReference = 0xFFFF & bb.getShort();
+                break;
+
+            case OpCodes.invokestatic:
+                int methodref = 0xFFFF & bb.getShort();
+                if ((methodref == forName || methodref == class$)
+                        && lastReference != -1
+                        && pool[intPool[lastReference]] instanceof String) {
+                    String clazz = (String) pool[intPool[lastReference]];
+                    doClassReference(clazz.replace('.', '/'));
+                }
+                break;
+
+            case OpCodes.tableswitch:
+                // Skip to place divisible by 4
+                while ((bb.position() & 0x3) != 0)
+                    bb.get();
+                /* int deflt = */
+                bb.getInt();
+                int low = bb.getInt();
+                int high = bb.getInt();
+                bb.position(bb.position() + (high - low + 1) * 4);
+                lastReference = -1;
+                break;
+
+            case OpCodes.lookupswitch:
+                // Skip to place divisible by 4
+                while ((bb.position() & 0x3) != 0)
+                    bb.get();
+                /* deflt = */
+                bb.getInt();
+                int npairs = bb.getInt();
+                bb.position(bb.position() + npairs * 8);
+                lastReference = -1;
+                break;
+
+            default:
+                lastReference = -1;
+                bb.position(bb.position() + OpCodes.OFFSETS[instruction]);
+            }
+        }
+    }
+
+    private void doSourceFile(DataInputStream in) throws IOException {
+        int sourcefile_index = in.readUnsignedShort();
+        this.sourceFile = pool[sourcefile_index].toString();
+    }
+
+    private void doParameterAnnotations(DataInputStream in) throws IOException {
+        int num_parameters = in.readUnsignedByte();
+        for (int p = 0; p < num_parameters; p++) {
+            int num_annotations = in.readUnsignedShort(); // # of annotations
+            for (int a = 0; a < num_annotations; a++) {
+                doAnnotation(in);
+            }
+        }
+    }
+
+    private void doAnnotations(DataInputStream in) throws IOException {
+        int num_annotations = in.readUnsignedShort(); // # of annotations
+        for (int a = 0; a < num_annotations; a++) {
+            doAnnotation(in);
+        }
+    }
+
+    private void doAnnotation(DataInputStream in) throws IOException {
+        int type_index = in.readUnsignedShort();
+        descriptors.add(new Integer(type_index));
+        int num_element_value_pairs = in.readUnsignedShort();
+        for (int v = 0; v < num_element_value_pairs; v++) {
+            /* int element_name_index = */in.readUnsignedShort();
+            doElementValue(in);
+        }
+    }
+
+    private void doElementValue(DataInputStream in) throws IOException {
+        int tag = in.readUnsignedByte();
+        switch (tag) {
+        case 'B':
+        case 'C':
+        case 'D':
+        case 'F':
+        case 'I':
+        case 'J':
+        case 'S':
+        case 'Z':
+        case 's':
+            /* int const_value_index = */
+            in.readUnsignedShort();
+            break;
+
+        case 'e':
+            int type_name_index = in.readUnsignedShort();
+            descriptors.add(new Integer(type_name_index));
+            /* int const_name_index = */
+            in.readUnsignedShort();
+            break;
+
+        case 'c':
+            int class_info_index = in.readUnsignedShort();
+            descriptors.add(new Integer(class_info_index));
+            break;
+
+        case '@':
+            doAnnotation(in);
+            break;
+
+        case '[':
+            int num_values = in.readUnsignedShort();
+            for (int i = 0; i < num_values; i++) {
+                doElementValue(in);
+            }
+            break;
+
+        default:
+            throw new IllegalArgumentException(
+                    "Invalid value for Annotation ElementValue tag " + tag);
+        }
+    }
+
+    void packageReference(String pack) {
+        if (pack.indexOf('<') >= 0)
+            System.out.println("Oops: " + pack);
+        if (!imports.containsKey(pack))
+            imports.put(pack, new LinkedHashMap<String, String>());
+    }
+
+    public void parseDescriptor(String prototype) {
+        if (prototype.startsWith("("))
+            parseMethodDescriptor(prototype);
+        else
+            addReference(prototype);
+    }
+
+    void parseMethodDescriptor(String prototype) {
+        int last = prototype.indexOf(')');
+        if (last < 0)
+            throw new IllegalArgumentException(
+                    "Invalid method descriptor in class file: " + className
+                            + " " + prototype);
+
+        for (int i = 1; i < last; i++) {
+            if (prototype.charAt(i) == 'L') {
+                int next = prototype.indexOf(';', i);
+                addReference(prototype.substring(i, next));
+                i = next;
+            }
+        }
+        addReference(prototype.substring(last + 1));
+    }
+
+    private void addReference(String token) {
+        cd.addReference(token);
+        while (token.startsWith("["))
+            token = token.substring(1);
+
+        if (token.startsWith("L")) {
+            String clazz = normalize(token.substring(1));
+            if (clazz.startsWith("java/"))
+                return;
+            String pack = getPackage(clazz);
+            packageReference(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";
+    }
+
+    public static String getPackage(String clazz) {
+        int n = clazz.lastIndexOf('/');
+        if (n < 0)
+            return ".";
+        return clazz.substring(0, n).replace('/', '.');
+    }
+
+    public Map<String, Map<String, String>> getReferred() {
+        return imports;
+    }
+
+    String getClassName() {
+        return className;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public Set<String> xref(InputStream in) throws IOException {
+        DataInputStream din = new DataInputStream(in);
+        Set<String> set = parseClassFile(din);
+        din.close();
+        return set;
+    }
+
+    public String getSourceFile() {
+        return sourceFile;
+    }
+
+    /**
+     * .class construct for different compilers
+     * 
+     * sun 1.1 Detect static variable class$com$acme$MyClass 1.2 " 1.3 " 1.4 "
+     * 1.5 ldc_w (class) 1.6 "
+     * 
+     * eclipse 1.1 class$0, ldc (string), invokestatic Class.forName 1.2 " 1.3 "
+     * 1.5 ldc (class) 1.6 "
+     * 
+     * 1.5 and later is not an issue, sun pre 1.5 is easy to detect the static
+     * variable that decodes the class name. For eclipse, the class$0 gives away
+     * we have a reference encoded in a string.
+     * compilerversions/compilerversions.jar contains test versions of all
+     * versions/compilers.
+     */
+
+    public void reset() {
+        pool = null;
+        intPool = null;
+        xref = null;
+        classes = null;
+        descriptors = null;
+    }
+
+    public boolean is(QUERY query, Instruction instr,
+            Map<String, Clazz> classspace) {
+        switch (query) {
+        case ANY:
+            return true;
+
+        case NAMED:
+            if (instr.matches(getClassName()))
+                return !instr.isNegated();
+            return false;
+
+        case VERSION:
+            String v = major + "/" + minor;
+            if (instr.matches(v))
+                return !instr.isNegated();
+            return false;
+
+        case IMPLEMENTS:
+            for (int i = 0; interfaces != null && i < interfaces.length; i++) {
+                if (instr.matches(interfaces[i]))
+                    return !instr.isNegated();
+            }
+            break;
+        case EXTENDS:
+            if (zuper == null)
+                return false;
+
+            if (instr.matches(zuper))
+                return !instr.isNegated();
+            break;
+
+        case IMPORTS:
+            for (String imp : imports.keySet()) {
+                if (instr.matches(imp.replace('.', '/')))
+                    return !instr.isNegated();
+            }
+        }
+
+        if (zuper == null || classspace == null)
+            return false;
+
+        Clazz clazz = classspace.get(zuper);
+        if (clazz == null)
+            return false;
+
+        return clazz.is(query, instr, classspace);
+    }
+
+    public String toString() {
+        return getFQN();
+    }
+
+    public String getFQN() {
+        return getClassName().replace('/', '.');
+    }
+
+    public void setClassDataCollector(ClassDataCollector cd) {
+        this.cd = cd;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Constants.java b/bundleplugin/src/main/java/aQute/lib/osgi/Constants.java
new file mode 100644
index 0000000..8e54aae
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Constants.java
@@ -0,0 +1,197 @@
+package aQute.lib.osgi;
+
+import java.util.*;
+import java.util.regex.*;
+
+public interface Constants {
+    /*
+     * Defined in OSGi
+     */
+    /**
+     * @syntax Bundle-ActivationPolicy ::= policy ( ’;’ directive )* policy ::=
+     *         ’lazy’
+     */
+    String               BUNDLE_ACTIVATION_POLICY                  = "Bundle-ActivationPolicy";
+    String               BUNDLE_ACTIVATOR                          = "Bundle-Activator";
+    String               BUNDLE_BLUEPRINT                          = "Bundle-Copyright";
+    String               BUNDLE_CATEGORY                           = "Bundle-Category";
+    String               BUNDLE_CLASSPATH                          = "Bundle-ClassPath";
+    String               BUNDLE_CONTACTADDRESS                     = "Bundle-ContactAddress";
+    String               BUNDLE_COPYRIGHT                          = "Bundle-Copyright";
+    String               BUNDLE_DESCRIPTION                        = "Bundle-Description";
+    String               BUNDLE_DOCURL                             = "Bundle-DocURL";
+    String               BUNDLE_ICON                               = "Bundle-Icon";
+    String               BUNDLE_LICENSE                            = "Bundle-License";
+    String               BUNDLE_LOCALIZATION                       = "Bundle-Localization";
+    String               BUNDLE_MANIFESTVERSION                    = "Bundle-ManifestVersion";
+    String               BUNDLE_NAME                               = "Bundle-Name";
+    String               BUNDLE_NATIVECODE                         = "Bundle-NativeCode";
+    String               BUNDLE_REQUIREDEXECUTIONENVIRONMENT       = "Bundle-RequiredExecutionEnvironment";
+    String               BUNDLE_SYMBOLICNAME                       = "Bundle-SymbolicName";
+    String               BUNDLE_UPDATELOCATION                     = "Bundle-UpdateLocation";
+    String               BUNDLE_VENDOR                             = "Bundle-Vendor";
+    String               BUNDLE_VERSION                            = "Bundle-Version";
+    String               DYNAMICIMPORT_PACKAGE                     = "DynamicImport-Package";
+    String               EXPORT_PACKAGE                            = "Export-Package";
+    String               EXPORT_SERVICE                            = "Export-Service";
+    String               FRAGMENT_HOST                             = "Fragment-Host";
+    String               IMPORT_PACKAGE                            = "Import-Package";
+    String               IMPORT_SERVICE                            = "Import-Service";
+    String               REQUIRE_BUNDLE                            = "Require-Bundle";
+    String               SERVICE_COMPONENT                         = "Service-Component";
+
+    String               PRIVATE_PACKAGE                           = "Private-Package";
+    String               IGNORE_PACKAGE                            = "Ignore-Package";
+    String               INCLUDE_RESOURCE                          = "Include-Resource";
+    String               CONDITIONAL_PACKAGE                       = "Conditional-Package";
+    String               BND_LASTMODIFIED                          = "Bnd-LastModified";
+    String               CREATED_BY                                = "Created-By";
+    String               TOOL                                      = "Tool";
+    String               TESTCASES                                 = "Test-Cases";
+
+    String               headers[]                                 = {
+            BUNDLE_ACTIVATOR, BUNDLE_CONTACTADDRESS, BUNDLE_COPYRIGHT,
+            BUNDLE_DESCRIPTION, BUNDLE_DOCURL, BUNDLE_LOCALIZATION,
+            BUNDLE_NATIVECODE, BUNDLE_VENDOR, BUNDLE_VERSION, BUNDLE_LICENSE,
+            BUNDLE_CLASSPATH, SERVICE_COMPONENT, EXPORT_PACKAGE,
+            IMPORT_PACKAGE, BUNDLE_LOCALIZATION, BUNDLE_MANIFESTVERSION,
+            BUNDLE_NAME, BUNDLE_NATIVECODE,
+            BUNDLE_REQUIREDEXECUTIONENVIRONMENT, BUNDLE_SYMBOLICNAME,
+            BUNDLE_VERSION, FRAGMENT_HOST, PRIVATE_PACKAGE, IGNORE_PACKAGE,
+            INCLUDE_RESOURCE, REQUIRE_BUNDLE, IMPORT_SERVICE, EXPORT_SERVICE,
+            CONDITIONAL_PACKAGE, BND_LASTMODIFIED, TESTCASES      };
+
+    String               BUILDPATH                                 = "-buildpath";
+    String               BUMPPOLICY                                = "-bumppolicy";
+    String               CONDUIT                                   = "-conduit";
+    String               DEPENDSON                                 = "-dependson";
+    String               DEPLOYREPO                                = "-deployrepo";
+    String               DONOTCOPY                                 = "-donotcopy";
+    String               DEBUG                                     = "-debug";
+    String               EXPORT_CONTENTS                           = "-exportcontents";
+    String               FAIL_OK                                   = "-failok";
+    String               INCLUDE                                   = "-include";
+    String               INCLUDERESOURCE                           = "-includeresource";
+    String               MAKE                                      = "-make";
+    String               MANIFEST                                  = "-manifest";
+    String               NOEXTRAHEADERS                            = "-noextraheaders";
+    String               NOMANIFEST                                = "-nomanifest";
+    String               NOUSES                                    = "-nouses";
+    String               NOPE                                      = "-nope";
+    String               PEDANTIC                                  = "-pedantic";
+    String               PLUGIN                                    = "-plugin";
+    String               POM                                       = "-pom";
+    String               RELEASEREPO                               = "-releaserepo";
+    String               REMOVE_HEADERS                            = "-removeheaders";
+    String               RESOURCEONLY                              = "-resourceonly";
+    String               SOURCES                                   = "-sources";
+    String               SOURCEPATH                                = "-sourcepath";
+    String               SUB                                       = "-sub";
+    String               RUNPROPERTIES                             = "-runproperties";
+    String               RUNSYSTEMPACKAGES                         = "-runsystempackages";
+    String               RUNBUNDLES                                = "-runbundles";
+    String               RUNPATH                                   = "-runpath";
+    String               RUNVM                                     = "-runvm";
+
+    String               REPORTNEWER                               = "-reportnewer";
+    String               SIGN                                      = "-sign";
+    String               TESTPACKAGES                              = "-testpackages";
+    String               TESTREPORT                                = "-testreport";
+    String               TESTBUNDLES                               = "-testbundles";
+    String               UNDERTEST                                 = "-undertest";
+    String               VERBOSE                                   = "-verbose";
+    String               VERSIONPOLICY                             = "-versionpolicy";
+
+    // Deprecated
+    String               CLASSPATH                                 = "-classpath";
+
+    String               options[]                                 = {
+            BUILDPATH, BUMPPOLICY, CONDUIT, CLASSPATH, DEPENDSON, DONOTCOPY,
+            EXPORT_CONTENTS, FAIL_OK, INCLUDE, INCLUDERESOURCE, MAKE, MANIFEST,
+            NOEXTRAHEADERS, NOUSES, NOPE, PEDANTIC, PLUGIN, POM,
+            REMOVE_HEADERS, RESOURCEONLY, SOURCES, SOURCEPATH, SOURCES,
+            SOURCEPATH, SUB, RUNBUNDLES, RUNPATH, RUNSYSTEMPACKAGES,
+            RUNPROPERTIES, REPORTNEWER, UNDERTEST, TESTBUNDLES, TESTPACKAGES,
+            TESTREPORT, VERBOSE, NOMANIFEST, DEPLOYREPO, RELEASEREPO };
+
+    // Ignore bundle specific headers. These bundles do not make
+    // a lot of sense to inherit
+    String[]             BUNDLE_SPECIFIC_HEADERS                   = new String[] {
+            INCLUDE_RESOURCE, BUNDLE_ACTIVATOR, BUNDLE_CLASSPATH, BUNDLE_NAME,
+            BUNDLE_NATIVECODE, BUNDLE_SYMBOLICNAME, IMPORT_PACKAGE,
+            EXPORT_PACKAGE, DYNAMICIMPORT_PACKAGE, FRAGMENT_HOST,
+            REQUIRE_BUNDLE, PRIVATE_PACKAGE, EXPORT_CONTENTS, TESTCASES,
+            NOMANIFEST                                            };
+
+    char                 DUPLICATE_MARKER                          = '~';
+
+    String               SPLIT_PACKAGE_DIRECTIVE                   = "-split-package:";
+    String               IMPORT_DIRECTIVE                          = "-import:";
+    String               NO_IMPORT_DIRECTIVE                       = "-noimport:";
+    String               REMOVE_ATTRIBUTE_DIRECTIVE                = "-remove-attribute:";
+
+    String               USES_DIRECTIVE                            = "uses:";
+    String               MANDATORY_DIRECTIVE                       = "mandatory:";
+    String               INCLUDE_DIRECTIVE                         = "include:";
+    String               EXCLUDE_DIRECTIVE                         = "exclude:";
+    String               PRESENCE_DIRECTIVE                        = "presence:";
+    String               SINGLETON_DIRECTIVE                       = "singleton:";
+    String               EXTENSION_DIRECTIVE                       = "extension:";
+    String               VISIBILITY_DIRECTIVE                      = "visibility:";
+    String               FRAGMENT_ATTACHMENT_DIRECTIVE             = "fragment-attachment:";
+    String               RESOLUTION_DIRECTIVE                      = "resolution:";
+    String               PATH_DIRECTIVE                            = "path:";
+    String               SIZE_ATTRIBUTE                            = "size";
+    String               LINK_ATTRIBUTE                            = "link";
+    String               NAME_ATTRIBUTE                            = "name";
+    String               DESCRIPTION_ATTRIBUTE                     = "description";
+    String               OSNAME_ATTRIBUTE                          = "osname";
+    String               OSVERSION_ATTRIBUTE                       = "osversion";
+    String               PROCESSOR_ATTRIBUTE                       = "processor";
+    String               LANGUAGE_ATTRIBUTE                        = "language";
+    String               SELECTION_FILTER_ATTRIBUTE                = "selection-filter";
+    String               BLUEPRINT_WAIT_FOR_DEPENDENCIES_ATTRIBUTE = "blueprint.wait-for-dependencies";
+    String               BLUEPRINT_TIMEOUT_ATTRIBUTE               = "blueprint.timeout";
+    String               VERSION_ATTRIBUTE                         = "version";
+    String               BUNDLE_SYMBOLIC_NAME_ATTRIBUTE            = "bundle-symbolic-name";
+    String               BUNDLE_VERSION_ATTRIBUTE                  = "bundle-version";
+
+    String               KEYSTORE_LOCATION_DIRECTIVE               = "keystore:";
+    String               KEYSTORE_PROVIDER_DIRECTIVE               = "provider:";
+    String               KEYSTORE_PASSWORD_DIRECTIVE               = "password:";
+    String               SIGN_PASSWORD_DIRECTIVE                   = "sign-password:";
+
+    String               NONE                                      = "none";
+
+    String               directives[]                              = {
+            SPLIT_PACKAGE_DIRECTIVE, NO_IMPORT_DIRECTIVE, IMPORT_DIRECTIVE,
+            RESOLUTION_DIRECTIVE, INCLUDE_DIRECTIVE, USES_DIRECTIVE,
+            EXCLUDE_DIRECTIVE, KEYSTORE_LOCATION_DIRECTIVE,
+            KEYSTORE_PROVIDER_DIRECTIVE, KEYSTORE_PASSWORD_DIRECTIVE,
+            SIGN_PASSWORD_DIRECTIVE,
+
+                                                                   // TODO
+                                                                   };
+
+    String               USES_USES                                 = "<<USES>>";
+    String               CURRENT_USES                              = "@uses";
+    String               IMPORT_REFERENCE                          = "reference";
+    String               IMPORT_PRIVATE                            = "private";
+    String[]             importDirectives                          = {
+            IMPORT_REFERENCE, IMPORT_PRIVATE                      };
+
+    static final Pattern VALID_PROPERTY_TYPES                      = Pattern
+                                                                           .compile("(String|Long|Double|Float|Integer|Byte|Character|Boolean|Short)");
+
+    String               DEFAULT_BND_EXTENSION                     = ".bnd";
+    String               DEFAULT_JAR_EXTENSION                     = ".jar";
+    String               DEFAULT_BAR_EXTENSION                     = ".bar";
+    String[]             METAPACKAGES                              = {
+            "META-INF", "OSGI-INF", "OSGI-OPT"                    };
+
+    int                  STRATEGY_HIGHEST                          = 1;
+    int                  STRATEGY_LOWEST                           = -1;
+
+    String               CURRENT_VERSION                           = "@";
+    String               CURRENT_PACKAGE                           = "@package";
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/EmbeddedResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/EmbeddedResource.java
new file mode 100644
index 0000000..771dbf7
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/EmbeddedResource.java
@@ -0,0 +1,88 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.zip.*;
+
+public class EmbeddedResource implements Resource {
+	byte	data[];
+	long 	lastModified;
+	String	extra;
+
+	public EmbeddedResource(byte data[], long lastModified) {
+		this.data = data;
+		this.lastModified = lastModified;
+	}
+
+	public InputStream openInputStream() throws FileNotFoundException {
+		return new ByteArrayInputStream(data);
+	}
+
+	public void write(OutputStream out) throws IOException {
+		out.write(data);
+	}
+
+	public String toString() {
+		return ":" + data.length + ":";
+	}
+
+	public static void build(Jar jar, InputStream in, long lastModified) throws IOException {
+		ZipInputStream jin = new ZipInputStream(in);
+		ZipEntry entry = jin.getNextEntry();
+		while (entry != null) {
+			if (!entry.isDirectory()) {
+				byte data[] = collect(jin);
+				jar.putResource(entry.getName(), new EmbeddedResource(data, lastModified), true);
+			}
+			entry = jin.getNextEntry();
+		}
+		jin.close();
+	}
+
+	/**
+	 * 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
+	 */
+    static byte[] collect(InputStream in) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        copy(in,out);
+        return out.toByteArray();
+    }
+
+    static void copy(InputStream in, OutputStream out) throws IOException {
+        int available = in.available();
+        if ( available <= 10000)
+            available = 64000;
+        byte [] buffer = new byte[available];
+        int size;
+        while ( (size=in.read(buffer))>0)
+            out.write(buffer,0,size);
+    }
+
+	public long lastModified() {
+		return lastModified;
+	}
+
+	public static void build(Jar sub, Resource resource) throws IOException {
+			InputStream in = resource.openInputStream();
+			build(sub,in, resource.lastModified());
+			in.close();
+	}
+
+	public String getExtra() {
+		return extra;
+	}
+
+	public void setExtra(String extra) {
+		this.extra = extra;
+	}
+
+	public long size() {
+	    return data.length;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/FileResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/FileResource.java
new file mode 100644
index 0000000..fa70e21
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/FileResource.java
@@ -0,0 +1,86 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.regex.Pattern;
+
+public class FileResource implements Resource {
+	File	file;
+	String	extra;
+	
+	public FileResource(File file) {
+		this.file = file;
+	}
+
+	public InputStream openInputStream() throws FileNotFoundException {
+		return new FileInputStream(file);
+	}
+
+	public static void build(Jar jar, File directory, Pattern doNotCopy) {
+		traverse(
+				jar,
+				directory.getAbsolutePath().length(),
+				directory,
+				doNotCopy);
+	}
+
+	public String toString() {
+		return ":" + file.getName() + ":";
+	}
+
+	public void write(OutputStream out) throws IOException {
+		copy(this, out);
+	}
+
+	static synchronized void copy(Resource resource, OutputStream out)
+			throws IOException {
+		InputStream in = resource.openInputStream();
+		try {
+			byte buffer[] = new byte[20000];
+			int size = in.read(buffer);
+			while (size > 0) {
+				out.write(buffer, 0, size);
+				size = in.read(buffer);
+			}
+		}
+		finally {
+			in.close();
+		}
+	}
+
+	static void traverse(Jar jar, int rootlength, File directory,
+			Pattern doNotCopy) {
+		if (doNotCopy.matcher(directory.getName()).matches())
+			return;
+
+		File files[] = directory.listFiles();
+		for (int i = 0; i < files.length; i++) {
+			if (files[i].isDirectory())
+				traverse(jar, rootlength, files[i], doNotCopy);
+			else {
+				String path = files[i].getAbsolutePath().substring(
+						rootlength + 1);
+				if (File.separatorChar != '/')
+					path = path.replace(File.separatorChar, '/');
+				jar.putResource(path, new FileResource(files[i]), true);
+			}
+		}
+	}
+
+	public long lastModified() {
+		return file.lastModified();
+	}
+
+	public String getExtra() {
+		return extra;
+	}
+
+	public void setExtra(String extra) {
+		this.extra = extra;
+	}
+	
+	public long size() {
+	    return (int) file.length();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java b/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java
new file mode 100644
index 0000000..a185ff7
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java
@@ -0,0 +1,113 @@
+/*
+ * $Header: /cvsroot/bnd/aQute.bnd/src/aQute/lib/osgi/Instruction.java,v 1.1 2009/01/19 14:08:30 pkriens Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2006). All Rights Reserved.
+ * 
+ * Licensed 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 aQute.lib.osgi;
+
+import java.util.regex.*;
+
+public class Instruction {
+    Pattern pattern;
+    String  instruction;
+    boolean negated;
+    boolean optional;
+    
+    public Instruction(String instruction, boolean negated) {
+        this.instruction = instruction;
+        this.negated = negated;
+    }
+
+    public boolean matches(String value) {
+        return getMatcher(value).matches();
+    }
+
+    public boolean isNegated() {
+        return negated;
+    }
+
+    public String getPattern() {
+        return instruction;
+    }
+
+    /**
+     * Convert a string based pattern to a regular expression based pattern.
+     * This is called an instruction, this object makes it easier to handle the
+     * different cases
+     * 
+     * @param string
+     * @return
+     */
+    public static Instruction getPattern(String string) {
+        boolean negated = false;
+        if (string.startsWith("!")) {
+            negated = true;
+            string = string.substring(1);
+        }
+        StringBuffer sb = new StringBuffer();
+        for (int c = 0; c < string.length(); c++) {
+            switch (string.charAt(c)) {
+            case '.':
+                sb.append("\\.");
+                break;
+            case '*':
+                sb.append(".*");
+                break;
+            case '?':
+                sb.append(".?");
+                break;
+            default:
+                sb.append(string.charAt(c));
+                break;
+            }
+        }
+        string = sb.toString();
+        if (string.endsWith("\\..*")) {
+            sb.append("|");
+            sb.append(string.substring(0, string.length() - 4));
+        }
+        return new Instruction(sb.toString(), negated);
+    }
+
+    public String toString() {
+        return getPattern();
+    }
+
+    public Matcher getMatcher(String value) {
+        if (pattern == null) {
+            pattern = Pattern.compile(instruction);
+        }
+        return pattern.matcher(value);
+    }
+
+    public int hashCode() {
+        return instruction.hashCode();
+    }
+
+    public boolean equals(Object other) {
+        return other != null && (other instanceof Instruction)
+                && instruction.equals(((Instruction) other).instruction);
+    }
+
+    public void setOptional() {
+        optional = true;
+    }
+    
+    public boolean isOptional() {
+        return optional;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/InstructionFilter.java b/bundleplugin/src/main/java/aQute/lib/osgi/InstructionFilter.java
new file mode 100644
index 0000000..81e5b75
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/InstructionFilter.java
@@ -0,0 +1,34 @@
+/* Copyright 2009 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.File;
+import java.io.FileFilter;
+
+public class InstructionFilter implements FileFilter {
+
+	private Instruction instruction;
+	private boolean recursive;
+	
+	public InstructionFilter (Instruction instruction, boolean recursive) {
+		this.instruction = instruction;
+		this.recursive = recursive;
+	}
+	public boolean isRecursive() {
+		return recursive;
+	}
+	public boolean accept(File pathname) {
+		if (Analyzer.doNotCopy.matcher(pathname.getName()).matches()) {
+			return false;
+		}
+
+		if (pathname.isDirectory() && isRecursive()) {
+			return true;
+		}
+		
+		if (instruction == null) {
+			return true;
+		}
+		return !instruction.isNegated() & instruction.matches(pathname.getName());
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java b/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
new file mode 100644
index 0000000..dfed21f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
@@ -0,0 +1,429 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+import java.util.zip.*;
+
+import aQute.libg.reporter.*;
+
+public class Jar implements Closeable {
+    public static final Object[]       EMPTY_ARRAY = new Jar[0];
+    Map<String, Resource>              resources   = new TreeMap<String, Resource>();
+    Map<String, Map<String, Resource>> directories = new TreeMap<String, Map<String, Resource>>();
+    Manifest                           manifest;
+    boolean                            manifestFirst;
+    String                             name;
+    File                               source;
+    ZipFile                            zipFile;
+    long                               lastModified;
+    String                             lastModifiedReason;
+    Reporter                           reporter;
+    boolean                            doNotTouchManifest;
+    boolean                            nomanifest;
+
+    public Jar(String name) {
+        this.name = name;
+    }
+
+    public Jar(String name, File dirOrFile) throws ZipException, IOException {
+        this(name);
+        source = dirOrFile;
+        if (dirOrFile.isDirectory())
+            FileResource.build(this, dirOrFile, Analyzer.doNotCopy);
+        else {
+            zipFile = ZipResource.build(this, dirOrFile);
+        }
+    }
+
+    public Jar(String name, InputStream in, long lastModified)
+            throws IOException {
+        this(name);
+        EmbeddedResource.build(this, in, lastModified);
+    }
+
+    public Jar(String name, String path) throws IOException {
+        this(name);
+        File f = new File(path);
+        InputStream in = new FileInputStream(f);
+        EmbeddedResource.build(this, in, f.lastModified());
+        in.close();
+    }
+
+    public Jar(File jar) throws IOException {
+        this(getName(jar), jar);
+    }
+
+    /**
+     * Make the JAR file name the project name if we get a src or bin directory.
+     * 
+     * @param f
+     * @return
+     */
+    private static String getName(File f) {
+        f = f.getAbsoluteFile();
+        String name = f.getName();
+        if (name.equals("bin") || name.equals("src"))
+            return f.getParentFile().getName();
+        else {
+            if (name.endsWith(".jar"))
+                name = name.substring(0, name.length() - 4);
+            return name;
+        }
+    }
+
+    public Jar(String string, InputStream resourceAsStream) throws IOException {
+        this(string, resourceAsStream, 0);
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String toString() {
+        return "Jar:" + name;
+    }
+
+    public boolean putResource(String path, Resource resource) {
+        return putResource(path, resource, true);
+    }
+
+    public boolean putResource(String path, Resource resource, boolean overwrite) {
+        updateModified(resource.lastModified(), path);
+
+        if (path.equals("META-INF/MANIFEST.MF")) {
+            manifest = null;
+            if (resources.isEmpty())
+                manifestFirst = true;
+        }
+        String dir = getDirectory(path);
+        Map<String, Resource> s = directories.get(dir);
+        if (s == null) {
+            s = new TreeMap<String, Resource>();
+            directories.put(dir, s);
+            int n = dir.lastIndexOf('/');
+            while (n > 0) {
+                String dd = dir.substring(0, n);
+                if (directories.containsKey(dd))
+                    break;
+                directories.put(dd, null);
+                n = dd.lastIndexOf('/');
+            }
+        }
+        boolean duplicate = s.containsKey(path);
+        if (!duplicate || overwrite) {
+            resources.put(path, resource);
+            s.put(path, resource);
+        }
+        return duplicate;
+    }
+
+    public Resource getResource(String path) {
+        return resources.get(path);
+    }
+
+    private String getDirectory(String path) {
+        int n = path.lastIndexOf('/');
+        if (n < 0)
+            return "";
+
+        return path.substring(0, n);
+    }
+
+    public Map<String, Map<String, Resource>> getDirectories() {
+        return directories;
+    }
+
+    public Map<String, Resource> getResources() {
+        return resources;
+    }
+
+    public boolean addDirectory(Map<String, Resource> directory,
+            boolean overwrite) {
+        boolean duplicates = false;
+        if (directory == null)
+            return false;
+
+        for (Map.Entry<String, Resource> entry : directory.entrySet()) {
+            String key = entry.getKey();
+            if (!key.endsWith(".java")) {
+                duplicates |= putResource(key, (Resource) entry.getValue(),
+                        overwrite);
+            }
+        }
+        return duplicates;
+    }
+
+    public Manifest getManifest() throws IOException {
+        if (manifest == null) {
+            Resource manifestResource = getResource("META-INF/MANIFEST.MF");
+            if (manifestResource != null) {
+                InputStream in = manifestResource.openInputStream();
+                manifest = new Manifest(in);
+                in.close();
+            }
+        }
+        return manifest;
+    }
+
+    public boolean exists(String path) {
+        return resources.containsKey(path);
+    }
+
+    public void setManifest(Manifest manifest) {
+        manifestFirst = true;
+        this.manifest = manifest;
+    }
+
+    public void write(File file) throws Exception {
+        try {
+            OutputStream out = new FileOutputStream(file);
+            write(out);
+            out.close();
+            return;
+
+        } catch (Exception t) {
+            file.delete();
+            throw t;
+        }
+    }
+
+    public void write(String file) throws Exception {
+        write(new File(file));
+    }
+
+    public void write(OutputStream out) throws IOException {
+        ZipOutputStream jout = nomanifest ? new ZipOutputStream(out) : new JarOutputStream(out);
+        Set<String> done = new HashSet<String>();
+
+        Set<String> directories = new HashSet<String>();
+        if (doNotTouchManifest) {
+            writeResource(jout, directories, "META-INF/MANIFEST.MF",
+                    getResource("META-INF/MANIFEST.MF"));
+            done.add("META-INF/MANIFEST.MF");
+        } else if (!nomanifest)
+            doManifest(done, jout);
+
+        for (Map.Entry<String, Resource> entry : getResources().entrySet()) {
+            // Skip metainf contents
+            if (!done.contains(entry.getKey()))
+                writeResource(jout, directories, (String) entry.getKey(),
+                        (Resource) entry.getValue());
+        }
+        jout.finish();
+    }
+
+    private void doManifest(Set<String> done, ZipOutputStream jout)
+            throws IOException {
+        if ( nomanifest )
+            return;
+        
+        JarEntry ze = new JarEntry("META-INF/MANIFEST.MF");
+        jout.putNextEntry(ze);
+        writeManifest(jout);
+        jout.closeEntry();
+        done.add(ze.getName());
+    }
+
+    /**
+     * Cleanup the manifest for writing. Cleaning up consists of adding a space
+     * after any \n to prevent the manifest to see this newline as a delimiter.
+     * 
+     * @param out
+     *            Output
+     * @throws IOException
+     */
+
+    public void writeManifest(OutputStream out) throws IOException {
+        writeManifest(getManifest(), out);
+    }
+
+    public static void writeManifest(Manifest manifest, OutputStream out)
+            throws IOException {
+        
+        manifest = clean(manifest);
+        manifest.write(out);
+    }
+
+    private static Manifest clean(Manifest org) {
+
+        Manifest result = new Manifest();
+        for (Map.Entry<?, ?> entry : org.getMainAttributes().entrySet()) {
+            String nice = clean((String) entry.getValue());
+            result.getMainAttributes().put(entry.getKey(), nice);
+        }
+        for (String name : org.getEntries().keySet()) {
+            Attributes attrs = result.getAttributes(name);
+            if (attrs == null) {
+                attrs = new Attributes();
+                result.getEntries().put(name, attrs);
+            }
+
+            for (Map.Entry<?, ?> entry : org.getAttributes(name).entrySet()) {
+                String nice = clean((String) entry.getValue());
+                attrs.put((Attributes.Name) entry.getKey(), nice);
+            }
+        }
+        return result;
+    }
+
+    private static String clean(String s) {
+        if (s.indexOf('\n') < 0)
+            return s;
+
+        StringBuffer sb = new StringBuffer(s);
+        for (int i = 0; i < sb.length(); i++) {
+            if (sb.charAt(i) == '\n')
+                sb.insert(++i, ' ');
+        }
+        return sb.toString();
+    }
+
+    private void writeResource(ZipOutputStream jout, Set<String> directories,
+            String path, Resource resource) throws IOException {
+        if (resource == null)
+            return;
+
+        createDirectories(directories, jout, path);
+        ZipEntry ze = new ZipEntry(path);
+        ze.setMethod(ZipEntry.DEFLATED);
+        long lastModified = resource.lastModified();
+        if (lastModified == 0L) {
+            lastModified = System.currentTimeMillis();
+        }
+        ze.setTime(lastModified);
+        if (resource.getExtra() != null)
+            ze.setExtra(resource.getExtra().getBytes());
+        jout.putNextEntry(ze);
+        try {
+            resource.write(jout);
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Cannot write resource: " + path
+                    + " " + e);
+        }
+        jout.closeEntry();
+    }
+
+    void createDirectories(Set<String> directories, ZipOutputStream zip,
+            String name) throws IOException {
+        int index = name.lastIndexOf('/');
+        if (index > 0) {
+            String path = name.substring(0, index);
+            if (directories.contains(path))
+                return;
+            createDirectories(directories, zip, path);
+            ZipEntry ze = new ZipEntry(path + '/');
+            zip.putNextEntry(ze);
+            zip.closeEntry();
+            directories.add(path);
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Add all the resources in the given jar that match the given filter.
+     * 
+     * @param sub
+     *            the jar
+     * @param filter
+     *            a pattern that should match the resoures in sub to be added
+     */
+    public boolean addAll(Jar sub, Pattern filter) {
+        boolean dupl = false;
+        for (String name : sub.getResources().keySet()) {
+            if ("META-INF/MANIFEST.MF".equals(name))
+                continue;
+
+            if (filter == null || filter.matcher(name).matches())
+                dupl |= putResource(name, sub.getResource(name), true);
+        }
+        return dupl;
+    }
+
+    public void close() {
+        if (zipFile != null)
+            try {
+                zipFile.close();
+            } catch (IOException e) {
+                // Ignore
+            }
+        resources = null;
+        directories = null;
+        manifest = null;
+        source = null;
+    }
+
+    public long lastModified() {
+        return lastModified;
+    }
+
+    public void updateModified(long time, String reason) {
+        if (time > lastModified) {
+            lastModified = time;
+            lastModifiedReason = reason;
+        }
+    }
+
+    public void setReporter(Reporter reporter) {
+        this.reporter = reporter;
+    }
+
+    public boolean hasDirectory(String path) {
+        return directories.get(path) != null;
+    }
+
+    public List<String> getPackages() {
+        List<String> list = new ArrayList<String>(directories.size());
+
+        for (Iterator<String> i = directories.keySet().iterator(); i.hasNext();) {
+            String path = i.next();
+            String pack = path.replace('/', '.');
+            list.add(pack);
+        }
+        return list;
+    }
+
+    public File getSource() {
+        return source;
+    }
+
+    public boolean addAll(Jar src) {
+        return addAll(src, null);
+    }
+
+    public boolean rename(String oldPath, String newPath) {
+        Resource resource = remove(oldPath);
+        if (resource == null)
+            return false;
+
+        return putResource(newPath, resource);
+    }
+
+    public Resource remove(String path) {
+        Resource resource = resources.remove(path);
+        String dir = getDirectory(path);
+        Map<String, Resource> mdir = directories.get(dir);
+        // must be != null
+        mdir.remove(path);
+        return resource;
+    }
+
+    /**
+     * Make sure nobody touches the manifest! If the bundle is signed, we do not
+     * want anybody to touch the manifest after the digests have been
+     * calculated.
+     */
+    public void setDoNotTouchManifest() {
+        doNotTouchManifest = true;
+    }
+
+    public void setNoManifest(boolean b) {
+        nomanifest = b;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/JarResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/JarResource.java
new file mode 100644
index 0000000..b633de1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/JarResource.java
@@ -0,0 +1,42 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+
+public class JarResource implements Resource {
+	Jar		jar;
+	String extra;
+	
+	public JarResource(Jar jar ) {
+		this.jar = jar;
+	}
+	
+	public String getExtra() {
+		return extra;
+	}
+
+	public long lastModified() {
+		return jar.lastModified();
+	}
+
+
+	public void write(OutputStream out) throws IOException {
+		jar.write(out);
+	}
+	
+	public InputStream openInputStream() throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		write(out);
+		out.close();
+		ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+		return in;
+	}
+
+	public void setExtra(String extra) {
+		this.extra = extra;
+	}
+	
+	public Jar getJar() { 
+	    return jar;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Macro.java b/bundleplugin/src/main/java/aQute/lib/osgi/Macro.java
new file mode 100644
index 0000000..12ab273
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Macro.java
@@ -0,0 +1,841 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.text.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.libg.sed.*;
+import aQute.libg.version.*;
+
+/**
+ * Provide a macro processor. This processor can replace variables in strings
+ * based on a properties and a domain. The domain can implement functions that
+ * start with a "_" and take args[], the names of these functions are available
+ * as functions in the macro processor (without the _). Macros can nest to any
+ * depth but may not contain loops.
+ * 
+ */
+public class Macro implements Replacer {
+    Properties properties;
+    Processor  domain;
+    Object     targets[];
+    boolean    flattening;
+
+    public Macro(Properties properties, Processor domain, Object... targets) {
+        this.properties = properties;
+        this.domain = domain;
+        this.targets = targets;
+        if (targets != null) {
+            for (Object o : targets) {
+                assert o != null;
+            }
+        }
+    }
+
+    public Macro(Processor processor) {
+        this(new Properties(), processor);
+    }
+
+    public String process(String line) {
+        return process(line, null);
+    }
+
+    String process(String line, Link link) {
+        StringBuffer sb = new StringBuffer();
+        process(line, 0, '\u0000', '\u0000', sb, link);
+        return sb.toString();
+    }
+
+    int process(CharSequence org, int index, char begin, char end,
+            StringBuffer result, Link link) {
+        StringBuilder line = new StringBuilder(org);
+        int nesting = 1;
+
+        StringBuffer variable = new StringBuffer();
+        outer: while (index < line.length()) {
+            char c1 = line.charAt(index++);
+            if (c1 == end) {
+                if (--nesting == 0) {
+                    result.append(replace(variable.toString(), link));
+                    return index;
+                }
+            } else if (c1 == begin)
+                nesting++;
+            else if (c1 == '\\' && index < line.length() - 1
+                    && line.charAt(index) == '$') {
+                // remove the escape backslash and interpret the dollar as a
+                // literal
+                index++;
+                variable.append('$');
+                continue outer;
+            } else if (c1 == '$' && index < line.length() - 2) {
+                char c2 = line.charAt(index);
+                char terminator = getTerminator(c2);
+                if (terminator != 0) {
+                    index = process(line, index + 1, c2, terminator, variable,
+                            link);
+                    continue outer;
+                }
+            }
+            variable.append(c1);
+        }
+        result.append(variable);
+        return index;
+    }
+
+    public static char getTerminator(char c) {
+        switch (c) {
+        case '(':
+            return ')';
+        case '[':
+            return ']';
+        case '{':
+            return '}';
+        case '<':
+            return '>';
+        case '\u00ab': // Guillemet double << >>
+            return '\u00bb';
+        case '\u2039': // Guillemet single
+            return '\u203a';
+        }
+        return 0;
+    }
+
+    protected String replace(String key, Link link) {
+        if (link != null && link.contains(key))
+            return "${infinite:" + link.toString() + "}";
+
+        if (key != null) {
+            key = key.trim();
+            if (key.length() > 0) {
+                String value = (String) properties.getProperty(key);
+                if (value != null)
+                    return process(value, new Link(link, key));
+
+                value = doCommands(key);
+                if (value != null)
+                    return process(value, new Link(link, key));
+
+                if (key != null && key.trim().length() > 0) {
+                    value = System.getProperty(key);
+                    if (value != null)
+                        return value;
+                }
+                if (!flattening)
+                    domain.warning("No translation found for macro: " + key);
+            } else {
+                domain.warning("Found empty macro key");
+            }
+        } else {
+            domain.warning("Found null macro key");
+        }
+        return "${" + key + "}";
+    }
+
+    /**
+     * Parse the key as a command. A command consist of parameters separated by
+     * ':'.
+     * 
+     * @param key
+     * @return
+     */
+    static Pattern commands = Pattern.compile("(?<!\\\\);");
+
+    private String doCommands(String key) {
+        String[] args = commands.split(key);
+        if (args == null || args.length == 0)
+            return null;
+
+        for (int i = 0; i < args.length; i++)
+            if (args[i].indexOf('\\') >= 0)
+                args[i] = args[i].replaceAll("\\\\;", ";");
+
+        Processor rover = domain;
+        while (rover != null) {
+            String result = doCommand(rover, args[0], args);
+            if (result != null)
+                return result;
+
+            rover = rover.getParent();
+        }
+
+        for (int i = 0; targets != null && i < targets.length; i++) {
+            String result = doCommand(targets[i], args[0], args);
+            if (result != null)
+                return result;
+        }
+
+        return doCommand(this, args[0], args);
+    }
+
+    private String doCommand(Object target, String method, String[] args) {
+        if (target == null)
+            ; // System.out.println("Huh? Target should never be null " +
+                // domain);
+        else {
+            String cname = "_" + method.replaceAll("-", "_");
+            try {
+                Method m = target.getClass().getMethod(cname,
+                        new Class[] { String[].class });
+                return (String) m.invoke(target, new Object[] { args });
+            } catch (NoSuchMethodException e) {
+                // Ignore
+            } catch (InvocationTargetException e) {
+                domain.warning("Exception in replace: " + e.getCause());
+                e.printStackTrace();
+            } catch (Exception e) {
+                domain.warning("Exception in replace: " + e + " method="
+                        + method);
+                e.printStackTrace();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return a unique list where the duplicates are removed.
+     * 
+     * @param args
+     * @return
+     */
+    static String _uniqHelp = "${uniq;<list> ...}";
+
+    public String _uniq(String args[]) {
+        verifyCommand(args, _uniqHelp, null, 1, Integer.MAX_VALUE);
+        Set<String> set = new LinkedHashSet<String>();
+        for (int i = 1; i < args.length; i++) {
+            Processor.split(args[i], set);
+        }
+        return Processor.join(set, ",");
+    }
+
+    public String _filter(String args[]) {
+        return filter(args, false);
+    }
+
+    public String _filterout(String args[]) {
+        return filter(args, true);
+
+    }
+
+    static String _filterHelp = "${%s;<list>;<regex>}";
+
+    String filter(String[] args, boolean include) {
+        verifyCommand(args, String.format(_filterHelp, args[0]), null, 3, 3);
+
+        Collection<String> list = new ArrayList<String>(Processor
+                .split(args[1]));
+        Pattern pattern = Pattern.compile(args[2]);
+
+        for (Iterator<String> i = list.iterator(); i.hasNext();) {
+            if (pattern.matcher(i.next()).matches() == include)
+                i.remove();
+        }
+        return Processor.join(list);
+    }
+
+    static String _sortHelp = "${sort;<list>...}";
+
+    public String _sort(String args[]) {
+        verifyCommand(args, _sortHelp, null, 2, Integer.MAX_VALUE);
+
+        List<String> result = new ArrayList<String>();
+        for (int i = 1; i < args.length; i++) {
+            Processor.split(args[i], result);
+        }
+        Collections.sort(result);
+        return Processor.join(result);
+    }
+
+    static String _joinHelp = "${join;<list>...}";
+
+    public String _join(String args[]) {
+
+        verifyCommand(args, _joinHelp, null, 1, Integer.MAX_VALUE);
+
+        List<String> result = new ArrayList<String>();
+        for (int i = 1; i < args.length; i++) {
+            Processor.split(args[i], result);
+        }
+        return Processor.join(result);
+    }
+
+    static String _ifHelp = "${if;<condition>;<iftrue> [;<iffalse>] }";
+
+    public String _if(String args[]) {
+        verifyCommand(args, _ifHelp, null, 3, 4);
+        String condition = args[1].trim();
+        if (condition.length() != 0)
+            return args[2];
+        if (args.length > 3)
+            return args[3];
+        else
+            return "";
+    }
+
+    public String _now(String args[]) {
+        return new Date().toString();
+    }
+
+    public static String _fmodifiedHelp = "${fmodified;<list of filenames>...}, return latest modification date";
+
+    public String _fmodified(String args[]) throws Exception {
+        verifyCommand(args, _fmodifiedHelp, null, 2, Integer.MAX_VALUE);
+
+        long time = 0;
+        Collection<String> names = new ArrayList<String>();
+        for (int i = 1; i < args.length; i++) {
+            Processor.split(args[i], names);
+        }
+        for (String name : names) {
+            File f = new File(name);
+            if (f.exists() && f.lastModified() > time)
+                time = f.lastModified();
+        }
+        return "" + time;
+    }
+
+    public String _long2date(String args[]) {
+        try {
+            return new Date(Long.parseLong(args[1])).toString();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "not a valid long";
+    }
+
+    public String _literal(String args[]) {
+        if (args.length != 2)
+            throw new RuntimeException(
+                    "Need a value for the ${literal;<value>} macro");
+        return "${" + args[1] + "}";
+    }
+
+    public String _def(String args[]) {
+        if (args.length != 2)
+            throw new RuntimeException(
+                    "Need a value for the ${def;<value>} macro");
+
+        String value = properties.getProperty(args[1]);
+        if (value == null)
+            return "";
+        else
+            return value;
+    }
+
+    /**
+     * 
+     * replace ; <list> ; regex ; replace
+     * 
+     * @param args
+     * @return
+     */
+    public String _replace(String args[]) {
+        if (args.length != 4) {
+            domain.warning("Invalid nr of arguments to replace "
+                    + Arrays.asList(args));
+            return null;
+        }
+
+        String list[] = args[1].split("\\s*,\\s*");
+        StringBuffer sb = new StringBuffer();
+        String del = "";
+        for (int i = 0; i < list.length; i++) {
+            String element = list[i].trim();
+            if (!element.equals("")) {
+                sb.append(del);
+                sb.append(element.replaceAll(args[2], args[3]));
+                del = ", ";
+            }
+        }
+
+        return sb.toString();
+    }
+
+    public String _warning(String args[]) {
+        for (int i = 1; i < args.length; i++) {
+            domain.warning(process(args[i]));
+        }
+        return "";
+    }
+
+    public String _error(String args[]) {
+        for (int i = 1; i < args.length; i++) {
+            domain.error(process(args[i]));
+        }
+        return "";
+    }
+
+    /**
+     * toclassname ; <path>.class ( , <path>.class ) *
+     * 
+     * @param args
+     * @return
+     */
+    static String _toclassnameHelp = "${classname;<list of class names>}, convert class paths to FQN class names ";
+
+    public String _toclassname(String args[]) {
+        verifyCommand(args, _toclassnameHelp, null, 2, 2);
+        Collection<String> paths = Processor.split(args[1]);
+
+        List<String> names = new ArrayList<String>(paths.size());
+        for (String path : paths) {
+            if (path.endsWith(".class")) {
+                String name = path.substring(0, path.length() - 6).replace('/',
+                        '.');
+                names.add(name);
+            } else if (path.endsWith(".java")) {
+                String name = path.substring(0, path.length() - 5).replace('/',
+                        '.');
+                names.add(name);
+            } else {
+                domain
+                        .warning("in toclassname, "
+                                + args[1]
+                                + " is not a class path because it does not end in .class");
+            }
+        }
+        return Processor.join(names, ",");
+    }
+
+    /**
+     * toclassname ; <path>.class ( , <path>.class ) *
+     * 
+     * @param args
+     * @return
+     */
+
+    static String _toclasspathHelp = "${toclasspath;<list>[;boolean]}, convert a list of class names to paths";
+
+    public String _toclasspath(String args[]) {
+        verifyCommand(args, _toclasspathHelp, null, 2, 3);
+        boolean cl= true;
+        if (args.length>2)
+            cl = new Boolean(args[2]);
+        
+        Collection<String> names = Processor.split(args[1]);
+        Collection<String> paths = new ArrayList<String>(names.size());
+        for (String name : names) {
+            String path = name.replace('.', '/') + (cl ? ".class" : "");
+            paths.add(path);
+        }
+        return Processor.join(paths, ",");
+    }
+
+    public String _dir(String args[]) {
+        if (args.length < 2) {
+            domain.warning("Need at least one file name for ${dir;...}");
+            return null;
+        } else {
+            String del = "";
+            StringBuffer sb = new StringBuffer();
+            for (int i = 1; i < args.length; i++) {
+                File f = new File(args[i]).getAbsoluteFile();
+                if (f.exists() && f.getParentFile().exists()) {
+                    sb.append(del);
+                    sb.append(f.getParentFile().getAbsolutePath());
+                    del = ",";
+                }
+            }
+            return sb.toString();
+        }
+
+    }
+
+    public String _basename(String args[]) {
+        if (args.length < 2) {
+            domain.warning("Need at least one file name for ${basename;...}");
+            return null;
+        } else {
+            String del = "";
+            StringBuffer sb = new StringBuffer();
+            for (int i = 1; i < args.length; i++) {
+                File f = new File(args[i]).getAbsoluteFile();
+                if (f.exists() && f.getParentFile().exists()) {
+                    sb.append(del);
+                    sb.append(f.getName());
+                    del = ",";
+                }
+            }
+            return sb.toString();
+        }
+
+    }
+
+    public String _isfile(String args[]) {
+        if (args.length < 2) {
+            domain.warning("Need at least one file name for ${isfile;...}");
+            return null;
+        } else {
+            boolean isfile = true;
+            for (int i = 1; i < args.length; i++) {
+                File f = new File(args[i]).getAbsoluteFile();
+                isfile &= f.isFile();
+            }
+            return isfile ? "true" : "false";
+        }
+
+    }
+
+    public String _isdir(String args[]) {
+        if (args.length < 2) {
+            domain.warning("Need at least one file name for ${isdir;...}");
+            return null;
+        } else {
+            boolean isdir = true;
+            for (int i = 1; i < args.length; i++) {
+                File f = new File(args[i]).getAbsoluteFile();
+                isdir &= f.isDirectory();
+            }
+            return isdir ? "true" : "false";
+        }
+
+    }
+
+    public String _tstamp(String args[]) {
+        String format = "yyyyMMddHHmm";
+        long now = System.currentTimeMillis();
+
+        if (args.length > 1) {
+            format = args[1];
+            if (args.length > 2) {
+                now = Long.parseLong(args[2]);
+                if (args.length > 3) {
+                    domain.warning("Too many arguments for tstamp: "
+                            + Arrays.toString(args));
+                }
+            }
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat(format);
+        return sdf.format(new Date(now));
+    }
+
+    /**
+     * Wildcard a directory. The lists can contain Instruction that are matched
+     * against the given directory
+     * 
+     * ${wc;<dir>;<list>(;<list>)*}
+     * 
+     * @author aqute
+     * 
+     */
+
+    public String _lsr(String args[]) {
+        return ls(args, true);
+    }
+
+    public String _lsa(String args[]) {
+        return ls(args, false);
+    }
+
+    String ls(String args[], boolean relative) {
+        if (args.length < 2)
+            throw new IllegalArgumentException(
+                    "the ${ls} macro must at least have a directory as parameter");
+
+        File dir = new File(args[1]);
+        if (!dir.isAbsolute())
+            throw new IllegalArgumentException(
+                    "the ${ls} macro directory parameter is not absolute: "
+                            + dir);
+
+        if (!dir.exists())
+            throw new IllegalArgumentException(
+                    "the ${ls} macro directory parameter does not exist: "
+                            + dir);
+
+        if (!dir.isDirectory())
+            throw new IllegalArgumentException(
+                    "the ${ls} macro directory parameter points to a file instead of a directory: "
+                            + dir);
+
+        String[] files = dir.list();
+        List<String> result;
+
+        if (args.length < 3) {
+            result = Arrays.asList(files);
+        } else
+            result = new ArrayList<String>();
+
+        for (int i = 2; i < args.length; i++) {
+            String parts[] = args[i].split("\\s*,\\s*");
+            for (String pattern : parts) {
+                // So make it in to an instruction
+                Instruction instr = Instruction.getPattern(pattern);
+
+                // For each project, match it against the instruction
+                for (int f = 0; f < files.length; f++) {
+                    if (files[f] != null) {
+                        if (instr.matches(files[f])) {
+                            if (!instr.isNegated()) {
+                                if (relative)
+                                    result.add(files[f]);
+                                else
+                                    result.add(new File(dir, files[f])
+                                            .getAbsolutePath());
+                            }
+                            files[f] = null;
+                        }
+                    }
+                }
+            }
+        }
+        return Processor.join(result, ",");
+    }
+
+    public String _currenttime(String args[]) {
+        return Long.toString(System.currentTimeMillis());
+    }
+
+    /**
+     * Modify a version to set a version policy. Thed policy is a mask that is
+     * mapped to a version.
+     * 
+     * <pre>
+     * +           increment
+     * -           decrement
+     * =           maintain
+     * &tilde;           discard
+     * 
+     * ==+      = maintain major, minor, increment micro, discard qualifier
+     * &tilde;&tilde;&tilde;=     = just get the qualifier
+     * version=&quot;[${version;==;${@}},${version;=+;${@}})&quot;
+     * </pre>
+     * 
+     * 
+     * 
+     * 
+     * @param args
+     * @return
+     */
+    static String  _versionHelp      = "${version;<mask>;<version>}, modify a version\n"
+                                             + "<mask> ::= [ M [ M [ M [ MQ ]]]\n"
+                                             + "M ::= '+' | '-' | MQ\n"
+                                             + "MQ ::= '~' | '='";
+    static Pattern _versionPattern[] = new Pattern[] { null, null,
+            Pattern.compile("[-+=~]{0,3}[=~]?"), Verifier.VERSION };
+
+    public String _version(String args[]) {
+        verifyCommand(args, _versionHelp, null, 3, 3);
+
+        String mask = args[1];
+
+        Version version = new Version(args[2]);
+        StringBuilder sb = new StringBuilder();
+        String del = "";
+
+        for (int i = 0; i < mask.length(); i++) {
+            char c = mask.charAt(i);
+            String result = null;
+            if (c != '~') {
+                if (i == 3) {
+                    result = version.getQualifier();
+                } else if (Character.isDigit(c)) {
+                	// Handle masks like +00, =+0
+                	result = String.valueOf(c);
+                } else {
+                    int x = version.get(i);
+                    switch (c) {
+                    case '+':
+                        x++;
+                        break;
+                    case '-':
+                        x--;
+                        break;
+                    case '=':
+                        break;
+                    }
+                    result = Integer.toString(x);
+                }
+                if (result != null) {
+                    sb.append(del);
+                    del = ".";
+                    sb.append(result);
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * System command. Execute a command and insert the result.
+     * 
+     * @param args
+     * @param help
+     * @param patterns
+     * @param low
+     * @param high
+     */
+    public String _system(String args[]) throws Exception {
+        verifyCommand(args,
+                "${system;<command>[;<in>]}, execute a system command", null,
+                2, 3);
+        String command = args[1];
+        String input = null;
+
+        if (args.length > 2) {
+            input = args[2];
+        }
+
+        Process process = Runtime.getRuntime().exec(command, null,
+                domain.getBase());
+        if (input != null) {
+            process.getOutputStream().write(input.getBytes("UTF-8"));
+        }
+        process.getOutputStream().close();
+
+        String s = getString(process.getInputStream());
+        process.getInputStream().close();
+        int exitValue = process.waitFor();
+        if (exitValue != 0) {
+            domain.error("System command " + command + " failed with "
+                    + exitValue);
+        }
+        return s.trim();
+    }
+
+    /**
+     * Get the contents of a file.
+     * 
+     * @param in
+     * @return
+     * @throws IOException
+     */
+
+    public String _cat(String args[]) throws IOException {
+        verifyCommand(args, "${cat;<in>}, get the content of a file", null, 2,
+                2);
+        File f = domain.getFile(args[1]);
+        if (f.isFile()) {
+            InputStream in = new FileInputStream(f);
+            return getString(in);
+        } else if (f.isDirectory()) {
+            return Arrays.toString(f.list());
+        } else {
+            try {
+                URL url = new URL(args[1]);
+                InputStream in = url.openStream();
+                return getString(in);
+            } catch (MalformedURLException mfue) {
+                // Ignore here
+            }
+            return null;
+        }
+    }
+
+    public static String getString(InputStream in) throws IOException {
+        try {
+            StringBuilder sb = new StringBuilder();
+            BufferedReader rdr = new BufferedReader(new InputStreamReader(in));
+            String line = null;
+            while ((line = rdr.readLine()) != null) {
+                sb.append(line);
+                sb.append("\n");
+            }
+            return sb.toString();
+        } finally {
+            in.close();
+        }
+    }
+
+    public static void verifyCommand(String args[], String help,
+            Pattern[] patterns, int low, int high) {
+        String message = "";
+        if (args.length > high) {
+            message = "too many arguments";
+        } else if (args.length < low) {
+            message = "too few arguments";
+        } else {
+            for (int i = 0; patterns != null && i < patterns.length
+                    && i < args.length - 1; i++) {
+                if (patterns[i] != null
+                        && !patterns[i].matcher(args[i + 1]).matches()) {
+                    message += String.format(
+                            "Argument %s (%s) does not match %s\n", i, args[i],
+                            patterns[i].pattern());
+                }
+            }
+        }
+        if (message.length() != 0) {
+            StringBuilder sb = new StringBuilder();
+            String del = "${";
+            for (String arg : args) {
+                sb.append(del);
+                sb.append(arg);
+                del = ";";
+            }
+            sb.append("}, is not understood. ");
+            sb.append(message);
+            throw new IllegalArgumentException(sb.toString());
+        }
+    }
+
+    // Helper class to track expansion of variables
+    // on the stack.
+    static class Link {
+        Link   previous;
+        String key;
+
+        public Link(Link previous, String key) {
+            this.previous = previous;
+            this.key = key;
+        }
+
+        public boolean contains(String key) {
+            if (this.key.equals(key))
+                return true;
+
+            if (previous == null)
+                return false;
+
+            return previous.contains(key);
+        }
+
+        public String toString() {
+            StringBuffer sb = new StringBuffer();
+            String del = "[";
+            for (Link r = this; r != null; r = r.previous) {
+                sb.append(del);
+                sb.append(r.key);
+                del = ",";
+            }
+            sb.append("]");
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Take all the properties and translate them to actual values. This method
+     * takes the set properties and traverse them over all entries, including
+     * the default properties for that properties. The values no longer contain
+     * macros.
+     * 
+     * @return A new Properties with the flattened values
+     */
+    public Properties getFlattenedProperties() {
+        // Some macros only work in a lower processor, so we
+        // do not report unknown macros while flattening
+        flattening = true;
+        try {
+            Properties flattened = new Properties();
+            for (Enumeration<?> e = properties.propertyNames(); e
+                    .hasMoreElements();) {
+                String key = (String) e.nextElement();
+                if (!key.startsWith("_"))
+                    if ( key.startsWith("-"))
+                        flattened.put(key, properties.getProperty(key));
+                    else
+                        flattened.put(key, process(properties.getProperty(key)));
+            }
+            return flattened;
+        } finally {
+            flattening = false;
+        }
+    };
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/OpCodes.java b/bundleplugin/src/main/java/aQute/lib/osgi/OpCodes.java
new file mode 100644
index 0000000..f0d3134
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/OpCodes.java
@@ -0,0 +1,1196 @@
+package aQute.lib.osgi;
+
+public class OpCodes {
+	final static short	nop				= 0x00;			// [No change] performs
+														// no
+	// operation
+	final static short	aconst_null		= 0x01;			// ? null pushes a null
+	// reference onto the stack
+	final static short	iconst_m1		= 0x02;			// ? -1 loads the int
+														// value -1
+	// onto the stack
+	final static short	iconst_0		= 0x03;			// ? 0 loads the int
+														// value 0
+	// onto the stack
+	final static short	iconst_1		= 0x04;			// ? 1 loads the int
+														// value 1
+	// onto the stack
+	final static short	iconst_2		= 0x05;			// ? 2 loads the int
+														// value 2
+	// onto the stack
+	final static short	iconst_3		= 0x06;			// ? 3 loads the int
+														// value 3
+	// onto the stack
+	final static short	iconst_4		= 0x07;			// ? 4 loads the int
+														// value 4
+	// onto the stack
+	final static short	iconst_5		= 0x08;			// ? 5 loads the int
+														// value 5
+	// onto the stack
+	final static short	lconst_0		= 0x09;			// ? 0L pushes the long
+														// 0 onto
+	// the stack
+	final static short	bipush			= 0x10;			// byte ? value pushes a
+														// byte
+	// onto the stack as an integer
+	// value
+	final static short	sipush			= 0x11;			// byte1, byte2 ? value
+														// pushes a
+	// signed integer (byte1 << 8 +
+	// byte2) onto the stack
+	final static short	ldc				= 0x12;			// index ? value pushes
+														// a
+	// constant #index from a
+	// constant pool (String, int,
+	// float or class type) onto the
+	// stack
+	final static short	ldc_w			= 0x13;			// indexbyte1,
+														// indexbyte2 ?
+	// value pushes a constant
+	// #index from a constant pool
+	// (String, int, float or class
+	// type) onto the stack (wide
+	// index is constructed as
+	// indexbyte1 << 8 + indexbyte2)
+	final static short	ldc2_w			= 0x14;			// indexbyte1,
+														// indexbyte2 ?
+	// value pushes a constant
+	// #index from a constant pool
+	// (double or long) onto the
+	// stack (wide index is
+	// constructed as indexbyte1 <<
+	// 8 + indexbyte2)
+	final static short	iload			= 0x15;			// index ? value loads
+														// an int
+	// value from a variable #index
+	final static short	lload			= 0x16;			// index ? value load a
+														// long
+	// value from a local variable
+	// #index
+	final static short	fload			= 0x17;			// index ? value loads a
+														// float
+	// value from a local variable
+	// #index
+	final static short	dload			= 0x18;			// index ? value loads a
+														// double
+	// value from a local variable
+	// #index
+	final static short	aload			= 0x19;			// index ? objectref
+														// loads a
+	// reference onto the stack from
+	// a local variable #index
+	final static short	lload_2			= 0x20;			// ? value load a long
+														// value
+	// from a local variable 2
+	final static short	lload_3			= 0x21;			// ? value load a long
+														// value
+	// from a local variable 3
+	final static short	fload_0			= 0x22;			// ? value loads a float
+														// value
+	// from local variable 0
+	final static short	fload_1			= 0x23;			// ? value loads a float
+														// value
+	// from local variable 1
+	final static short	fload_2			= 0x24;			// ? value loads a float
+														// value
+	// from local variable 2
+	final static short	fload_3			= 0x25;			// ? value loads a float
+														// value
+	// from local variable 3
+	final static short	dload_0			= 0x26;			// ? value loads a
+														// double from
+	// local variable 0
+	final static short	dload_1			= 0x27;			// ? value loads a
+														// double from
+	// local variable 1
+	final static short	dload_2			= 0x28;			// ? value loads a
+														// double from
+	// local variable 2
+	final static short	dload_3			= 0x29;			// ? value loads a
+														// double from
+	// local variable 3
+	final static short	faload			= 0x30;			// arrayref, index ?
+														// value loads
+	// a float from an array
+	final static short	daload			= 0x31;			// arrayref, index ?
+														// value loads
+	// a double from an array
+	final static short	aaload			= 0x32;			// arrayref, index ?
+														// value loads
+	// onto the stack a reference
+	// from an array
+	final static short	baload			= 0x33;			// arrayref, index ?
+														// value loads
+	// a byte or Boolean value from
+	// an array
+	final static short	caload			= 0x34;			// arrayref, index ?
+														// value loads
+	// a char from an array
+	final static short	saload			= 0x35;			// arrayref, index ?
+														// value load
+	// short from array
+	final static short	istore			= 0x36;			// index value ? store
+														// int value
+	// into variable #index
+	final static short	lstore			= 0x37;			// index value ? store a
+														// long
+	// value in a local variable
+	// #index
+	final static short	fstore			= 0x38;			// index value ? stores
+														// a float
+	// value into a local variable
+	// #index
+	final static short	dstore			= 0x39;			// index value ? stores
+														// a double
+	// value into a local variable
+	// #index
+	final static short	lstore_1		= 0x40;			// value ? store a long
+														// value in
+	// a local variable 1
+	final static short	lstore_2		= 0x41;			// value ? store a long
+														// value in
+	// a local variable 2
+	final static short	lstore_3		= 0x42;			// value ? store a long
+														// value in
+	// a local variable 3
+	final static short	fstore_0		= 0x43;			// value ? stores a
+														// float value
+	// into local variable 0
+	final static short	fstore_1		= 0x44;			// value ? stores a
+														// float value
+	// into local variable 1
+	final static short	fstore_2		= 0x45;			// value ? stores a
+														// float value
+	// into local variable 2
+	final static short	fstore_3		= 0x46;			// value ? stores a
+														// float value
+	// into local variable 3
+	final static short	dstore_0		= 0x47;			// value ? stores a
+														// double into
+	// local variable 0
+	final static short	dstore_1		= 0x48;			// value ? stores a
+														// double into
+	// local variable 1
+	final static short	dstore_2		= 0x49;			// value ? stores a
+														// double into
+	// local variable 2
+	final static short	lastore			= 0x50;			// arrayref, index,
+														// value ?
+	// store a long to an array
+	final static short	fastore			= 0x51;			// arreyref, index,
+														// value ?
+	// stores a float in an array
+	final static short	dastore			= 0x52;			// arrayref, index,
+														// value ?
+	// stores a double into an array
+	final static short	aastore			= 0x53;			// arrayref, index,
+														// value ?
+	// stores into a reference to an
+	// array
+	final static short	bastore			= 0x54;			// arrayref, index,
+														// value ?
+	// stores a byte or Boolean
+	// value into an array
+	final static short	castore			= 0x55;			// arrayref, index,
+														// value ?
+	// stores a char into an array
+	final static short	sastore			= 0x56;			// arrayref, index,
+														// value ?
+	// store short to array
+	final static short	pop				= 0x57;			// value ? discards the
+														// top
+	// value on the stack
+	final static short	pop2			= 0x58;			// {value2, value1} ?
+														// discards
+	// the top two values on the
+	// stack (or one value, if it is
+	// a double or long)
+	final static short	dup				= 0x59;			// value ? value, value
+	// duplicates the value on top
+	// of the stack
+	final static short	iadd			= 0x60;			// value1, value2 ?
+														// result adds
+	// two ints together
+	final static short	ladd			= 0x61;			// value1, value2 ?
+														// result add
+	// two longs
+	final static short	fadd			= 0x62;			// value1, value2 ?
+														// result adds
+	// two floats
+	final static short	dadd			= 0x63;			// value1, value2 ?
+														// result adds
+	// two doubles
+	final static short	isub			= 0x64;			// value1, value2 ?
+														// result int
+	// subtract
+	final static short	lsub			= 0x65;			// value1, value2 ?
+														// result
+	// subtract two longs
+	final static short	fsub			= 0x66;			// value1, value2 ?
+														// result
+	// subtracts two floats
+	final static short	dsub			= 0x67;			// value1, value2 ?
+														// result
+	// subtracts a double from
+	// another
+	final static short	imul			= 0x68;			// value1, value2 ?
+														// result
+	// multiply two integers
+	final static short	lmul			= 0x69;			// value1, value2 ?
+														// result
+	// multiplies two longs
+	final static short	irem			= 0x70;			// value1, value2 ?
+														// result
+	// logical int remainder
+	final static short	lrem			= 0x71;			// value1, value2 ?
+														// result
+	// remainder of division of two
+	// longs
+	final static short	frem			= 0x72;			// value1, value2 ?
+														// result gets
+	// the remainder from a division
+	// between two floats
+	final static short	drem			= 0x73;			// value1, value2 ?
+														// result gets
+	// the remainder from a division
+	// between two doubles
+	final static short	ineg			= 0x74;			// value ? result negate
+														// int
+	final static short	lneg			= 0x75;			// value ? result
+														// negates a long
+	final static short	fneg			= 0x76;			// value ? result
+														// negates a
+	// float
+	final static short	dneg			= 0x77;			// value ? result
+														// negates a
+	// double
+	final static short	ishl			= 0x78;			// value1, value2 ?
+														// result int
+	// shift left
+	final static short	lshl			= 0x79;			// value1, value2 ?
+														// result
+	// bitwise shift left of a long
+	// value1 by value2 positions
+	final static short	ior				= 0x80;			// value1, value2 ?
+														// result
+	// logical int or
+	final static short	lor				= 0x81;			// value1, value2 ?
+														// result
+	// bitwise or of two longs
+	final static short	ixor			= 0x82;			// value1, value2 ?
+														// result int
+	// xor
+	final static short	lxor			= 0x83;			// value1, value2 ?
+														// result
+	// bitwise exclusive or of two
+	// longs
+	final static short	iinc			= 0x84;			// index, const [No
+														// change]
+	// increment local variable
+	// #index by signed byte const
+	final static short	i2l				= 0x85;			// value ? result
+														// converts an
+	// int into a long
+	final static short	i2f				= 0x86;			// value ? result
+														// converts an
+	// int into a float
+	final static short	i2d				= 0x87;			// value ? result
+														// converts an
+	// int into a double
+	final static short	l2i				= 0x88;			// value ? result
+														// converts a
+	// long to an int
+	final static short	l2f				= 0x89;			// value ? result
+														// converts a
+	// long to a float
+	final static short	d2f				= 0x90;			// value ? result
+														// converts a
+	// double to a float
+	final static short	i2b				= 0x91;			// value ? result
+														// converts an
+	// int into a byte
+	final static short	i2c				= 0x92;			// value ? result
+														// converts an
+	// int into a character
+	final static short	i2s				= 0x93;			// value ? result
+														// converts an
+	// int into a short
+	final static short	lcmp			= 0x94;			// value1, value2 ?
+														// result
+	// compares two longs values
+	final static short	fcmpl			= 0x95;			// value1, value2 ?
+														// result
+	// compares two floats
+	final static short	fcmpg			= 0x96;			// value1, value2 ?
+														// result
+	// compares two floats
+	final static short	dcmpl			= 0x97;			// value1, value2 ?
+														// result
+	// compares two doubles
+	final static short	dcmpg			= 0x98;			// value1, value2 ?
+														// result
+	// compares two doubles
+	final static short	ifeq			= 0x99;			// branchbyte1,
+														// branchbyte2
+	// value ? if value is 0, branch
+	// to instruction at
+	// branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	lconst_1		= 0x0a;			// ? 1L pushes the long
+														// 1 onto
+	// the stack
+	final static short	fconst_0		= 0x0b;			// ? 0.0f pushes 0.0f on
+														// the
+	// stack
+	final static short	fconst_1		= 0x0c;			// ? 1.0f pushes 1.0f on
+														// the
+	// stack
+	final static short	fconst_2		= 0x0d;			// ? 2.0f pushes 2.0f on
+														// the
+	// stack
+	final static short	dconst_0		= 0x0e;			// ? 0.0 pushes the
+														// constant 0.0
+	// onto the stack
+	final static short	dconst_1		= 0x0f;			// ? 1.0 pushes the
+														// constant 1.0
+	// onto the stack
+	final static short	iload_0			= 0x1a;			// ? value loads an int
+														// value
+	// from variable 0
+	final static short	iload_1			= 0x1b;			// ? value loads an int
+														// value
+	// from variable 1
+	final static short	iload_2			= 0x1c;			// ? value loads an int
+														// value
+	// from variable 2
+	final static short	iload_3			= 0x1d;			// ? value loads an int
+														// value
+	// from variable 3
+	final static short	lload_0			= 0x1e;			// ? value load a long
+														// value
+	// from a local variable 0
+	final static short	lload_1			= 0x1f;			// ? value load a long
+														// value
+	// from a local variable 1
+	final static short	aload_0			= 0x2a;			// ? objectref loads a
+														// reference
+	// onto the stack from local
+	// variable 0
+	final static short	aload_1			= 0x2b;			// ? objectref loads a
+														// reference
+	// onto the stack from local
+	// variable 1
+	final static short	aload_2			= 0x2c;			// ? objectref loads a
+														// reference
+	// onto the stack from local
+	// variable 2
+	final static short	aload_3			= 0x2d;			// ? objectref loads a
+														// reference
+	// onto the stack from local
+	// variable 3
+	final static short	iaload			= 0x2e;			// arrayref, index ?
+														// value loads
+	// an int from an array
+	final static short	laload			= 0x2f;			// arrayref, index ?
+														// value load
+	// a long from an array
+	final static short	astore			= 0x3a;			// index objectref ?
+														// stores a
+	// reference into a local
+	// variable #index
+	final static short	istore_0		= 0x3b;			// value ? store int
+														// value into
+	// variable 0
+	final static short	istore_1		= 0x3c;			// value ? store int
+														// value into
+	// variable 1
+	final static short	istore_2		= 0x3d;			// value ? store int
+														// value into
+	// variable 2
+	final static short	istore_3		= 0x3e;			// value ? store int
+														// value into
+	// variable 3
+	final static short	lstore_0		= 0x3f;			// value ? store a long
+														// value in
+	// a local variable 0
+	final static short	dstore_3		= 0x4a;			// value ? stores a
+														// double into
+	// local variable 3
+	final static short	astore_0		= 0x4b;			// objectref ? stores a
+	// reference into local variable
+	// 0
+	final static short	astore_1		= 0x4c;			// objectref ? stores a
+	// reference into local variable
+	// 1
+	final static short	astore_2		= 0x4d;			// objectref ? stores a
+	// reference into local variable
+	// 2
+	final static short	astore_3		= 0x4e;			// objectref ? stores a
+	// reference into local variable
+	// 3
+	final static short	iastore			= 0x4f;			// arrayref, index,
+														// value ?
+	// stores an int into an array
+	final static short	dup_x1			= 0x5a;			// value2, value1 ?
+														// value1,
+	// value2, value1 inserts a copy
+	// of the top value into the
+	// stack two values from the top
+	final static short	dup_x2			= 0x5b;			// value3, value2,
+														// value1 ?
+	// value1, value3, value2,
+	// value1 inserts a copy of the
+	// top value into the stack two
+	// (if value2 is double or long
+	// it takes up the entry of
+	// value3, too) or three values
+	// (if value2 is neither double
+	// nor long) from the top
+	final static short	dup2			= 0x5c;			// {value2, value1} ?
+														// {value2,
+	// value1}, {value2, value1}
+	// duplicate top two stack words
+	// (two values, if value1 is not
+	// double nor long; a single
+	// value, if value1 is double or
+	// long)
+	final static short	dup2_x1			= 0x5d;			// value3, {value2,
+														// value1} ?
+	// {value2, value1}, value3,
+	// {value2, value1} duplicate
+	// two words and insert beneath
+	// third word (see explanation
+	// above)
+	final static short	dup2_x2			= 0x5e;			// {value4, value3},
+														// {value2,
+	// value1} ? {value2, value1},
+	// {value4, value3}, {value2,
+	// value1} duplicate two words
+	// and insert beneath fourth
+	// word
+	final static short	swap			= 0x5f;			// value2, value1 ?
+														// value1,
+	// value2 swaps two top words on
+	// the stack (note that value1
+	// and value2 must not be double
+	// or long)
+	final static short	fmul			= 0x6a;			// value1, value2 ?
+														// result
+	// multiplies two floats
+	final static short	dmul			= 0x6b;			// value1, value2 ?
+														// result
+	// multiplies two doubles
+	final static short	idiv			= 0x6c;			// value1, value2 ?
+														// result
+	// divides two integers
+	final static short	ldiv			= 0x6d;			// value1, value2 ?
+														// result
+	// divide two longs
+	final static short	fdiv			= 0x6e;			// value1, value2 ?
+														// result
+	// divides two floats
+	final static short	ddiv			= 0x6f;			// value1, value2 ?
+														// result
+	// divides two doubles
+	final static short	ishr			= 0x7a;			// value1, value2 ?
+														// result int
+	// shift right
+	final static short	lshr			= 0x7b;			// value1, value2 ?
+														// result
+	// bitwise shift right of a long
+	// value1 by value2 positions
+	final static short	iushr			= 0x7c;			// value1, value2 ?
+														// result int
+	// shift right
+	final static short	lushr			= 0x7d;			// value1, value2 ?
+														// result
+	// bitwise shift right of a long
+	// value1 by value2 positions,
+	// unsigned
+	final static short	iand			= 0x7e;			// value1, value2 ?
+														// result
+	// performs a logical and on two
+	// integers
+	final static short	land			= 0x7f;			// value1, value2 ?
+														// result
+	// bitwise and of two longs
+	final static short	l2d				= 0x8a;			// value ? result
+														// converts a
+	// long to a double
+	final static short	f2i				= 0x8b;			// value ? result
+														// converts a
+	// float to an int
+	final static short	f2l				= 0x8c;			// value ? result
+														// converts a
+	// float to a long
+	final static short	f2d				= 0x8d;			// value ? result
+														// converts a
+	// float to a double
+	final static short	d2i				= 0x8e;			// value ? result
+														// converts a
+	// double to an int
+	final static short	d2l				= 0x8f;			// value ? result
+														// converts a
+	// double to a long
+	final static short	ifne			= 0x9a;			// branchbyte1,
+														// branchbyte2
+	// value ? if value is not 0,
+	// branch to instruction at
+	// branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	iflt			= 0x9b;			// branchbyte1,
+														// branchbyte2
+	// value ? if value is less than
+	// 0, branch to instruction at
+	// branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	ifge			= 0x9c;			// branchbyte1,
+														// branchbyte2
+	// value ? if value is greater
+	// than or equal to 0, branch to
+	// instruction at branchoffset
+	// (signed short constructed
+	// from unsigned bytes
+	// branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	ifgt			= 0x9d;			// branchbyte1,
+														// branchbyte2
+	// value ? if value is greater
+	// than 0, branch to instruction
+	// at branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	ifle			= 0x9e;			// branchbyte1,
+														// branchbyte2
+	// value ? if value is less than
+	// or equal to 0, branch to
+	// instruction at branchoffset
+	// (signed short constructed
+	// from unsigned bytes
+	// branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	if_icmpeq		= 0x9f;			// branchbyte1,
+														// branchbyte2
+	// value1, value2 ? if ints are
+	// equal, branch to instruction
+	// at branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	if_icmpne		= 0xa0;			// branchbyte1,
+														// branchbyte2
+	// value1, value2 ? if ints are
+	// not equal, branch to
+	// instruction at branchoffset
+	// (signed short constructed
+	// from unsigned bytes
+	// branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	if_icmplt		= 0xa1;			// branchbyte1,
+														// branchbyte2
+	// value1, value2 ? if value1 is
+	// less than value2, branch to
+	// instruction at branchoffset
+	// (signed short constructed
+	// from unsigned bytes
+	// branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	if_icmpge		= 0xa2;			// branchbyte1,
+														// branchbyte2
+	// value1, value2 ? if value1 is
+	// greater than or equal to
+	// value2, branch to instruction
+	// at branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	if_icmpgt		= 0xa3;			// branchbyte1,
+														// branchbyte2
+	// value1, value2 ? if value1 is
+	// greater than value2, branch
+	// to instruction at
+	// branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	if_icmple		= 0xa4;			// branchbyte1,
+														// branchbyte2
+	// value1, value2 ? if value1 is
+	// less than or equal to value2,
+	// branch to instruction at
+	// branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	if_acmpeq		= 0xa5;			// branchbyte1,
+														// branchbyte2
+	// value1, value2 ? if
+	// references are equal, branch
+	// to instruction at
+	// branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	if_acmpne		= 0xa6;			// branchbyte1,
+														// branchbyte2
+	// value1, value2 ? if
+	// references are not equal,
+	// branch to instruction at
+	// branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	goto_			= 0xa7;			// branchbyte1,
+														// branchbyte2 [no
+	// change] goes to another
+	// instruction at branchoffset
+	// (signed short constructed
+	// from unsigned bytes
+	// branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	jsr				= 0xa8;			// branchbyte1,
+														// branchbyte2 ?
+	// address jump to subroutine at
+	// branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2) and place the
+	// return address on the stack
+	final static short	ret				= 0xa9;			// index [No change]
+														// continue
+	// execution from address taken
+	// from a local variable #index
+	// (the asymmetry with jsr is
+	// intentional)
+	final static short	tableswitch		= 0xaa;			// [0-3 bytes padding],
+	// defaultbyte1, defaultbyte2,
+	// defaultbyte3, defaultbyte4,
+	// lowbyte1, lowbyte2, lowbyte3,
+	// lowbyte4, highbyte1,
+	// highbyte2, highbyte3,
+	// highbyte4, jump offsets...
+	// index ? continue execution
+	// from an address in the table
+	// at offset index
+	final static short	lookupswitch	= 0xab;			// <0-3 bytes padding>,
+	// defaultbyte1, defaultbyte2,
+	// defaultbyte3, defaultbyte4,
+	// npairs1, npairs2, npairs3,
+	// npairs4, match-offset
+	// pairs... key ? a target
+	// address is looked up from a
+	// table using a key and
+	// execution continues from the
+	// instruction at that address
+	final static short	ireturn			= 0xac;			// value ? [empty]
+														// returns an
+	// integer from a method
+	final static short	lreturn			= 0xad;			// value ? [empty]
+														// returns a
+	// long value
+	final static short	freturn			= 0xae;			// value ? [empty]
+														// returns a
+	// float
+	final static short	dreturn			= 0xaf;			// value ? [empty]
+														// returns a
+	// double from a method
+	final static short	areturn			= 0xb0;			// objectref ? [empty]
+														// returns a
+	// reference from a method
+	final static short	return_			= 0xb1;			// ? [empty] return void
+														// from
+	// method
+	final static short	getstatic		= 0xb2;			// index1, index2 ?
+														// value gets a
+	// static field value of a
+	// class, where the field is
+	// identified by field reference
+	// in the constant pool index
+	// (index1 << 8 + index2)
+	final static short	putstatic		= 0xb3;			// indexbyte1,
+														// indexbyte2 value
+	// ? set static field to value
+	// in a class, where the field
+	// is identified by a field
+	// reference index in constant
+	// pool (indexbyte1 << 8 +
+	// indexbyte2)
+	final static short	getfield		= 0xb4;			// index1, index2
+														// objectref ?
+	// value gets a field value of
+	// an object objectref, where
+	// the field is identified by
+	// field reference in the
+	// constant pool index (index1
+	// << 8 + index2)
+	final static short	putfield		= 0xb5;			// indexbyte1,
+														// indexbyte2
+	// objectref, value ? set field
+	// to value in an object
+	// objectref, where the field is
+	// identified by a field
+	// reference index in constant
+	// pool (indexbyte1 << 8 +
+	// indexbyte2)
+	final static short	invokevirtual	= 0xb6;			// indexbyte1,
+														// indexbyte2
+	// objectref, [arg1, arg2, ...]
+	// ? invoke virtual method on
+	// object objectref, where the
+	// method is identified by
+	// method reference index in
+	// constant pool (indexbyte1 <<
+	// 8 + indexbyte2)
+	final static short	invokespecial	= 0xb7;			// indexbyte1,
+														// indexbyte2
+	// objectref, [arg1, arg2, ...]
+	// ? invoke instance method on
+	// object objectref, where the
+	// method is identified by
+	// method reference index in
+	// constant pool (indexbyte1 <<
+	// 8 + indexbyte2)
+	final static short	invokestatic	= 0xb8;			// indexbyte1,
+														// indexbyte2 [arg1,
+	// arg2, ...] ? invoke a static
+	// method, where the method is
+	// identified by method
+	// reference index in constant
+	// pool (indexbyte1 << 8 +
+	// indexbyte2)
+	final static short	invokeinterface	= 0xb9;			// indexbyte1,
+														// indexbyte2,
+	// count, 0 objectref, [arg1,
+	// arg2, ...] ? invokes an
+	// interface method on object
+	// objectref, where the
+	// interface method is
+	// identified by method
+	// reference index in constant
+	// pool (indexbyte1 << 8 +
+	// indexbyte2)
+	final static short	xxxunusedxxx	= 0xba;			// this opcode is
+														// reserved "for
+	// historical reasons"
+	final static short	new_			= 0xbb;			// indexbyte1,
+														// indexbyte2 ?
+	// objectref creates new object
+	// of type identified by class
+	// reference in constant pool
+	// index (indexbyte1 << 8 +
+	// indexbyte2)
+	final static short	newarray		= 0xbc;			// atype count ?
+														// arrayref
+	// creates new array with count
+	// elements of primitive type
+	// identified by atype
+	final static short	anewarray		= 0xbd;			// indexbyte1,
+														// indexbyte2 count
+	// ? arrayref creates a new
+	// array of references of length
+	// count and component type
+	// identified by the class
+	// reference index (indexbyte1
+	// << 8 + indexbyte2) in the
+	// constant pool
+	final static short	arraylength		= 0xbe;			// arrayref ? length
+														// gets the
+	// length of an array
+	final static short	athrow			= 0xbf;			// objectref ? [empty],
+	// objectref throws an error or
+	// exception (notice that the
+	// rest of the stack is cleared,
+	// leaving only a reference to
+	// the Throwable)
+	final static short	checkcast		= 0xc0;			// indexbyte1,
+														// indexbyte2
+	// objectref ? objectref checks
+	// whether an objectref is of a
+	// certain type, the class
+	// reference of which is in the
+	// constant pool at index
+	// (indexbyte1 << 8 +
+	// indexbyte2)
+	final static short	instanceof_		= 0xc1;			// indexbyte1,
+														// indexbyte2
+	// objectref ? result determines
+	// if an object objectref is of
+	// a given type, identified by
+	// class reference index in
+	// constant pool (indexbyte1 <<
+	// 8 + indexbyte2)
+	final static short	monitorenter	= 0xc2;			// objectref ? enter
+														// monitor for
+	// object ("grab the lock" -
+	// start of synchronized()
+	// section)
+	final static short	monitorexit		= 0xc3;			// objectref ? exit
+														// monitor for
+	// object ("release the lock" -
+	// end of synchronized()
+	// section)
+	final static short	wide			= 0xc4;			// opcode, indexbyte1,
+	// indexbyte2
+	final static short	multianewarray	= 0xc5;			// indexbyte1,
+														// indexbyte2,
+	// dimensions count1,
+	// [count2,...] ? arrayref
+	// create a new array of
+	// dimensions dimensions with
+	// elements of type identified
+	// by class reference in
+	// constant pool index
+	// (indexbyte1 << 8 +
+	// indexbyte2); the sizes of
+	// each dimension is identified
+	// by count1, [count2, etc]
+	final static short	ifnull			= 0xc6;			// branchbyte1,
+														// branchbyte2
+	// value ? if value is null,
+	// branch to instruction at
+	// branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	ifnonnull		= 0xc7;			// branchbyte1,
+														// branchbyte2
+	// value ? if value is not null,
+	// branch to instruction at
+	// branchoffset (signed short
+	// constructed from unsigned
+	// bytes branchbyte1 << 8 +
+	// branchbyte2)
+	final static short	goto_w			= 0xc8;			// branchbyte1,
+														// branchbyte2,
+	// branchbyte3, branchbyte4 [no
+	// change] goes to another
+	// instruction at branchoffset
+	// (signed int constructed from
+	// unsigned bytes branchbyte1 <<
+	// 24 + branchbyte2 << 16 +
+	// branchbyte3 << 8 +
+	// branchbyte4)
+	final static short	jsr_w			= 0xc9;			// branchbyte1,
+														// branchbyte2,
+	// branchbyte3, branchbyte4 ?
+	// address jump to subroutine at
+	// branchoffset (signed int
+	// constructed from unsigned
+	// bytes branchbyte1 << 24 +
+	// branchbyte2 << 16 +
+	// branchbyte3 << 8 +
+	// branchbyte4) and place the
+	// return address on the stack
+	final static short	breakpoint		= 0xca;			// reserved for
+														// breakpoints in
+	// Java debuggers; should not
+	// appear in any class file
+	final static short	impdep1			= 0xfe;			// reserved for
+	// implementation-dependent
+	// operations within debuggers;
+	// should not appear in any
+	// class file
+	final static short	impdep2			= 0xff;			// reserved for
+	// implementation-dependent
+	// operations within debuggers;
+	// should not appear in any
+	// class file
+
+	final static byte	OFFSETS[]		= new byte[256];
+
+	static {
+		OFFSETS[bipush] = 1; // byte ? value pushes a byte onto the
+		// stack as an integer value
+		OFFSETS[sipush] = 2; // byte1, byte2 ? value pushes a signed
+		// integer (byte1 << 8 + byte2) onto the
+		// stack
+		OFFSETS[ldc] = 1; // index ? value pushes a constant
+		// #index from a constant pool (String,
+		// int, float or class type) onto the
+		// stack
+		OFFSETS[ldc_w] = 2; // indexbyte1, indexbyte2 ? value pushes
+		// a constant #index from a constant
+		// pool (String, int, float or class
+		// type) onto the stack (wide index is
+		// constructed as indexbyte1 << 8 +
+		// indexbyte2)
+		OFFSETS[ldc2_w] = 2; // indexbyte1, indexbyte2 ? value pushes
+		// a constant #index from a constant
+		// pool (double or long) onto the stack
+		// (wide index is constructed as
+		// indexbyte1 << 8 + indexbyte2)
+		OFFSETS[iload] = 1; // index ? value loads an int value from
+		// a variable #index
+		OFFSETS[lload] = 1; // index ? value load a long value from
+		// a local variable #index
+		OFFSETS[fload] = 1; // index ? value loads a float value
+		// from a local variable #index
+		OFFSETS[dload] = 1; // index ? value loads a double value
+		// from a local variable #index
+		OFFSETS[aload] = 1; // index ? objectref loads a reference
+		// onto the stack from a local variable
+		// #index
+		OFFSETS[istore] = 1; // index value ? store int value into
+		// variable #index
+		OFFSETS[lstore] = 1; // index value ? store a long value in a
+		// local variable #index
+		OFFSETS[fstore] = 1; // index value ? stores a float value
+		// into a local variable #index
+		OFFSETS[dstore] = 1; // index value ? stores a double value
+		// into a local variable #index
+		OFFSETS[iinc] = 2; // index, const [No change] increment
+		// local variable #index by signed byte
+		// const
+		OFFSETS[ifeq] = 2; // branchbyte1, branchbyte2 value ? if
+		// value is 0, branch to instruction at
+		// branchoffset (signed short
+		// constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[astore] = 1; // index objectref ? stores a reference
+		// into a local variable #index
+		OFFSETS[ifne] = 2; // branchbyte1, branchbyte2 value ? if
+		// value is not 0, branch to instruction
+		// at branchoffset (signed short
+		// constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[iflt] = 2; // branchbyte1, branchbyte2 value ? if
+		// value is less than 0, branch to
+		// instruction at branchoffset (signed
+		// short constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[ifge] = 2; // branchbyte1, branchbyte2 value ? if
+		// value is greater than or equal to 0,
+		// branch to instruction at branchoffset
+		// (signed short constructed from
+		// unsigned bytes branchbyte1 << 8 +
+		// branchbyte2)
+		OFFSETS[ifgt] = 2; // branchbyte1, branchbyte2 value ? if
+		// value is greater than 0, branch to
+		// instruction at branchoffset (signed
+		// short constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[ifle] = 2; // branchbyte1, branchbyte2 value ? if
+		// value is less than or equal to 0,
+		// branch to instruction at branchoffset
+		// (signed short constructed from
+		// unsigned bytes branchbyte1 << 8 +
+		// branchbyte2)
+		OFFSETS[if_icmpeq] = 2; // branchbyte1, branchbyte2 value1,
+		// value2 ? if ints are equal,
+		// branch to instruction at
+		// branchoffset (signed short
+		// constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[if_icmpne] = 2; // branchbyte1, branchbyte2 value1,
+		// value2 ? if ints are not equal,
+		// branch to instruction at
+		// branchoffset (signed short
+		// constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[if_icmplt] = 2; // branchbyte1, branchbyte2 value1,
+		// value2 ? if value1 is less than
+		// value2, branch to instruction at
+		// branchoffset (signed short
+		// constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[if_icmpge] = 2; // branchbyte1, branchbyte2 value1,
+		// value2 ? if value1 is greater
+		// than or equal to value2, branch
+		// to instruction at branchoffset
+		// (signed short constructed from
+		// unsigned bytes branchbyte1 << 8 +
+		// branchbyte2)
+		OFFSETS[if_icmpgt] = 2; // branchbyte1, branchbyte2 value1,
+		// value2 ? if value1 is greater
+		// than value2, branch to
+		// instruction at branchoffset
+		// (signed short constructed from
+		// unsigned bytes branchbyte1 << 8 +
+		// branchbyte2)
+		OFFSETS[if_icmple] = 2; // branchbyte1, branchbyte2 value1,
+		// value2 ? if value1 is less than
+		// or equal to value2, branch to
+		// instruction at branchoffset
+		// (signed short constructed from
+		// unsigned bytes branchbyte1 << 8 +
+		// branchbyte2)
+		OFFSETS[if_acmpeq] = 2; // branchbyte1, branchbyte2 value1,
+		// value2 ? if references are equal,
+		// branch to instruction at
+		// branchoffset (signed short
+		// constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[if_acmpne] = 2; // branchbyte1, branchbyte2 value1,
+		// value2 ? if references are not
+		// equal, branch to instruction at
+		// branchoffset (signed short
+		// constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[goto_] = 2; // branchbyte1, branchbyte2 [no change]
+		// goes to another instruction at
+		// branchoffset (signed short
+		// constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[jsr] = 2; // branchbyte1, branchbyte2 ? address
+		// jump to subroutine at branchoffset
+		// (signed short constructed from
+		// unsigned bytes branchbyte1 << 8 +
+		// branchbyte2) and place the return
+		// address on the stack
+		OFFSETS[ret] = 1; // index [No change] continue execution
+		// from address taken from a local
+		// variable #index (the asymmetry with
+		// jsr is intentional)
+		OFFSETS[tableswitch] = -1; // [0-3 bytes padding],
+		// defaultbyte1, defaultbyte2,
+		// defaultbyte3, defaultbyte4,
+		// lowbyte1, lowbyte2, lowbyte3,
+		// lowbyte4, highbyte1,
+		// highbyte2, highbyte3,
+		// highbyte4, jump offsets...
+		// index ? continue execution
+		// from an address in the table
+		// at offset index
+		OFFSETS[lookupswitch] = -1; // <0-3 bytes padding>,
+		// defaultbyte1, defaultbyte2,
+		// defaultbyte3, defaultbyte4,
+		// npairs1, npairs2, npairs3,
+		// npairs4, match-offset
+		// pairs... key ? a target
+		// address is looked up from a
+		// table using a key and
+		// execution continues from the
+		// instruction at that address
+		OFFSETS[getstatic] = 2; // index1, index2 ? value gets a
+		// static field value of a class,
+		// where the field is identified by
+		// field reference in the constant
+		// pool index (index1 << 8 + index2)
+		OFFSETS[putstatic] = 2; // indexbyte1, indexbyte2 value ?
+		// set static field to value in a
+		// class, where the field is
+		// identified by a field reference
+		// index in constant pool
+		// (indexbyte1 << 8 + indexbyte2)
+		OFFSETS[getfield] = 2; // index1, index2 objectref ? value
+		// gets a field value of an object
+		// objectref, where the field is
+		// identified by field reference in
+		// the constant pool index (index1
+		// << 8 + index2)
+		OFFSETS[putfield] = 2; // indexbyte1, indexbyte2 objectref,
+		// value ? set field to value in an
+		// object objectref, where the field
+		// is identified by a field
+		// reference index in constant pool
+		// (indexbyte1 << 8 + indexbyte2)
+		OFFSETS[invokevirtual] = 2; // indexbyte1, indexbyte2
+		// objectref, [arg1, arg2, ...]
+		// ? invoke virtual method on
+		// object objectref, where the
+		// method is identified by
+		// method reference index in
+		// constant pool (indexbyte1 <<
+		// 8 + indexbyte2)
+		OFFSETS[invokespecial] = 2; // indexbyte1, indexbyte2
+		// objectref, [arg1, arg2, ...]
+		// ? invoke instance method on
+		// object objectref, where the
+		// method is identified by
+		// method reference index in
+		// constant pool (indexbyte1 <<
+		// 8 + indexbyte2)
+		OFFSETS[invokestatic] = 2; // indexbyte1, indexbyte2 [arg1,
+		// arg2, ...] ? invoke a static
+		// method, where the method is
+		// identified by method
+		// reference index in constant
+		// pool (indexbyte1 << 8 +
+		// indexbyte2)
+		OFFSETS[invokeinterface] = 2; // indexbyte1, indexbyte2,
+		// count, 0 objectref,
+		// [arg1, arg2, ...] ?
+		// invokes an interface
+		// method on object
+		// objectref, where the
+		// interface method is
+		// identified by method
+		// reference index in
+		// constant pool (indexbyte1
+		// << 8 + indexbyte2)
+		OFFSETS[new_] = 2; // indexbyte1, indexbyte2 ? objectref
+		// creates new object of type identified
+		// by class reference in constant pool
+		// index (indexbyte1 << 8 + indexbyte2)
+		OFFSETS[newarray] = 1; // atype count ? arrayref creates
+		// new array with count elements of
+		// primitive type identified by
+		// atype
+		OFFSETS[anewarray] = 2; // indexbyte1, indexbyte2 count ?
+		// arrayref creates a new array of
+		// references of length count and
+		// component type identified by the
+		// class reference index (indexbyte1
+		// << 8 + indexbyte2) in the
+		// constant pool
+		OFFSETS[checkcast] = 2; // indexbyte1, indexbyte2 objectref
+		// ? objectref checks whether an
+		// objectref is of a certain type,
+		// the class reference of which is
+		// in the constant pool at index
+		// (indexbyte1 << 8 + indexbyte2)
+		OFFSETS[instanceof_] = 2; // indexbyte1, indexbyte2 objectref
+		// ? result determines if an object
+		// objectref is of a given type,
+		// identified by class reference
+		// index in constant pool
+		// (indexbyte1 << 8 + indexbyte2)
+		OFFSETS[wide] = 3; // opcode, indexbyte1, indexbyte2
+		OFFSETS[multianewarray] = 3; // indexbyte1, indexbyte2,
+		// dimensions count1,
+		// [count2,...] ? arrayref
+		// create a new array of
+		// dimensions dimensions with
+		// elements of type identified
+		// by class reference in
+		// constant pool index
+		// (indexbyte1 << 8 +
+		// indexbyte2); the sizes of
+		// each dimension is identified
+		// by count1, [count2, etc]
+		OFFSETS[ifnull] = 2; // branchbyte1, branchbyte2 value ? if
+		// value is null, branch to instruction
+		// at branchoffset (signed short
+		// constructed from unsigned bytes
+		// branchbyte1 << 8 + branchbyte2)
+		OFFSETS[ifnonnull] = 2; // branchbyte1, branchbyte2 value ?
+		// if value is not null, branch to
+		// instruction at branchoffset
+		// (signed short constructed from
+		// unsigned bytes branchbyte1 << 8 +
+		// branchbyte2)
+		OFFSETS[goto_w] = 4; // branchbyte1, branchbyte2,
+		// branchbyte3, branchbyte4 [no change]
+		// goes to another instruction at
+		// branchoffset (signed int constructed
+		// from unsigned bytes branchbyte1 << 24
+		// + branchbyte2 << 16 + branchbyte3 <<
+		// 8 + branchbyte4)
+		OFFSETS[jsr_w] = 4; // branchbyte1, branchbyte2,
+		// branchbyte3, branchbyte4 ? address
+		// jump to subroutine at branchoffset
+		// (signed int constructed from unsigned
+		// bytes branchbyte1 << 24 + branchbyte2
+		// << 16 + branchbyte3 << 8 +
+		// branchbyte4) and place the return
+		// address on the stack
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/PreprocessResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/PreprocessResource.java
new file mode 100644
index 0000000..8299af8
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/PreprocessResource.java
@@ -0,0 +1,37 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+
+public class PreprocessResource extends AbstractResource {
+    final Resource  resource;
+    final Processor processor;
+
+    public PreprocessResource(Processor processor, Resource r) {
+        super(r.lastModified());
+        this.processor = processor;
+        this.resource = r;
+        extra = resource.getExtra();
+    }
+
+    protected byte[] getBytes() throws IOException {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(2000);
+        OutputStreamWriter osw = new OutputStreamWriter(bout);
+        PrintWriter pw = new PrintWriter(osw);
+        InputStream in = resource.openInputStream();
+        try {
+            BufferedReader rdr = new BufferedReader(new InputStreamReader(in));
+            String line = rdr.readLine();
+            while (line != null) {
+                line = processor.getReplacer().process(line);
+                pw.println(line);
+                line = rdr.readLine();
+            }
+            pw.flush();
+            byte [] data= bout.toByteArray();
+            return data;
+                
+        } finally {
+            in.close();
+        }        
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java b/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java
new file mode 100644
index 0000000..459b498
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java
@@ -0,0 +1,1039 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.bnd.make.*;
+import aQute.bnd.service.*;
+import aQute.libg.header.*;
+import aQute.libg.reporter.*;
+
+public class Processor implements Reporter, Constants, Closeable {
+    // TODO handle include files out of date
+    public static String    DEFAULT_PLUGINS = "";                            // "aQute.lib.spring.SpringComponent";
+    // TODO make splitter skip eagerly whitespace so trim is not necessary
+    public static String    LIST_SPLITTER   = "\\\\?\\s*,\\s*";
+    private List<String>    errors          = new ArrayList<String>();
+    private List<String>    warnings        = new ArrayList<String>();
+    boolean                 pedantic;
+    boolean                 trace;
+    boolean                 exceptions;
+    boolean                 fileMustExist   = true;
+
+    List<Object>            plugins;
+    private File            base            = new File("").getAbsoluteFile();
+    private List<Closeable> toBeClosed      = newList();
+
+    final Properties        properties;
+    private Macro           replacer;
+    private long            lastModified;
+    private File            propertiesFile;
+    private boolean         fixup           = true;
+    long                    modified;
+    Processor               parent;
+    Set<File>               included;
+    CL                      pluginLoader;
+    Collection<String>      filter;
+
+    public Processor() {
+        properties = new Properties();
+    }
+
+    public Processor(Properties parent) {
+        properties = new Properties(parent);
+    }
+
+    public Processor(Processor parent) {
+        this(parent.properties);
+        this.parent = parent;
+    }
+
+    public void setParent(Processor processor) {
+        this.parent = processor;
+    }
+
+    public Processor getParent() {
+        return parent;
+    }
+
+    public Processor getTop() {
+        if (parent == null)
+            return this;
+        else
+            return parent.getTop();
+    }
+
+    public void getInfo(Processor processor, String prefix) {
+        if (isFailOk())
+            addAll(warnings, processor.getErrors(), prefix);
+        else
+            addAll(errors, processor.getErrors(), prefix);
+        addAll(warnings, processor.getWarnings(), prefix);
+
+        processor.errors.clear();
+        processor.warnings.clear();
+    }
+
+    public void getInfo(Processor processor) {
+        getInfo(processor, "");
+    }
+
+    private <T> void addAll(List<String> to, List<? extends T> from,
+            String prefix) {
+        for (T x : from) {
+            to.add(prefix + x);
+        }
+    }
+
+    public void warning(String string, Object... args) {
+        String s = String.format(string, args);
+        if (!warnings.contains(s))
+            warnings.add(s);
+    }
+
+    public void error(String string, Object... args) {
+        if (isFailOk())
+            warning(string, args);
+        else {
+            String s = String.format(string, args);
+            if (!errors.contains(s))
+                errors.add(s);
+        }
+    }
+
+    public void error(String string, Throwable t, Object... args) {
+        if (isFailOk())
+            warning(string + ": " + t, args);
+        else {
+            String s = String.format(string, args);
+            if (!errors.contains(s))
+                errors.add(s);
+        }
+        if (exceptions)
+            t.printStackTrace();
+    }
+
+    public List<String> getWarnings() {
+        return warnings;
+    }
+
+    public List<String> getErrors() {
+        return errors;
+    }
+
+    public Map<String, Map<String, String>> parseHeader(String value) {
+        return parseHeader(value, this);
+    }
+
+    /**
+     * Standard OSGi header parser.
+     * 
+     * @param value
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    static public Map<String, Map<String, String>> parseHeader(String value,
+            Processor logger) {
+        return OSGiHeader.parseHeader(value, logger);
+    }
+
+    Map<String, Map<String, String>> getClauses(String header) {
+        return parseHeader(getProperty(header));
+    }
+
+    public void addClose(Closeable jar) {
+        toBeClosed.add(jar);
+    }
+
+    /**
+     * Remove all entries from a map that start with a specific prefix
+     * 
+     * @param <T>
+     * @param source
+     * @param prefix
+     * @return
+     */
+    static <T> Map<String, T> removeKeys(Map<String, T> source, String prefix) {
+        Map<String, T> temp = new TreeMap<String, T>(source);
+        for (Iterator<String> p = temp.keySet().iterator(); p.hasNext();) {
+            String pack = (String) p.next();
+            if (pack.startsWith(prefix))
+                p.remove();
+        }
+        return temp;
+    }
+
+    public void progress(String s, Object... args) {
+        // System.out.println(s);
+    }
+
+    public boolean isPedantic() {
+        return pedantic;
+    }
+
+    public void setPedantic(boolean pedantic) { // System.out.println("Set
+        // pedantic: " + pedantic + " "
+        // + this );
+        this.pedantic = pedantic;
+    }
+
+    public static File getFile(File base, String file) {
+        File f = new File(file);
+        if (f.isAbsolute())
+            return f;
+        int n;
+
+        f = base.getAbsoluteFile();
+        while ((n = file.indexOf('/')) > 0) {
+            String first = file.substring(0, n);
+            file = file.substring(n + 1);
+            if (first.equals(".."))
+                f = f.getParentFile();
+            else
+                f = new File(f, first);
+        }
+        return new File(f, file).getAbsoluteFile();
+    }
+
+    public File getFile(String file) {
+        return getFile(base, file);
+    }
+
+    /**
+     * Return a list of plugins that implement the given class.
+     * 
+     * @param clazz
+     *            Each returned plugin implements this class/interface
+     * @return A list of plugins
+     */
+    public <T> List<T> getPlugins(Class<T> clazz) {
+        List<T> l = new ArrayList<T>();
+        List<Object> all = getPlugins();
+        for (Object plugin : all) {
+            if (clazz.isInstance(plugin))
+                l.add(clazz.cast(plugin));
+        }
+        return l;
+    }
+
+    /**
+     * Return a list of plugins. Plugins are defined with the -plugin command.
+     * They are class names, optionally associated with attributes. Plugins can
+     * implement the Plugin interface to see these attributes.
+     * 
+     * Any object can be a plugin.
+     * 
+     * @return
+     */
+    protected List<Object> getPlugins() {
+      //  if (parent != null) {
+      //      List<Object> val = parent.getPlugins();
+      //      getInfo(parent);
+      //      return val;
+      //  }
+        if (this.plugins != null)
+            return this.plugins;
+
+        String spe = getProperty(Analyzer.PLUGIN, DEFAULT_PLUGINS);
+        Map<String, Map<String, String>> plugins = parseHeader(spe);
+        List<Object> list = new ArrayList<Object>();
+
+        // Add the default plugins. Only if non is specified
+        // will they be removed.
+        list.add(new MakeBnd());
+        list.add(new MakeCopy());
+        list.add(new ServiceComponent());
+
+        for (Map.Entry<String, Map<String, String>> entry : plugins.entrySet()) {
+            String key = (String) entry.getKey();
+            if (key.equals(NONE))
+                return this.plugins = newList();
+
+            try {
+                CL loader = getLoader();
+                String path = entry.getValue().get(PATH_DIRECTIVE);
+                if (path != null) {
+                    File f = getFile(path).getAbsoluteFile();
+                    loader.add(f.toURL());
+                }
+
+                trace("Using plugin %s", key);
+
+                // Plugins could use the same class with different
+                // parameters so we could have duplicate names Remove
+                // the ! added by the parser to make each name unique.
+                key = removeDuplicateMarker(key);
+
+                Class<?> c = (Class<?>) loader.loadClass(key);
+                Object plugin = c.newInstance();
+                if (plugin instanceof Plugin) {
+                    ((Plugin) plugin).setProperties(entry.getValue());
+                    ((Plugin) plugin).setReporter(this);
+                }
+                list.add(plugin);
+            } catch (Exception e) {
+                
+                error("Problem loading the plugin: " + key + " exception: " + e);
+            }
+        }
+        return this.plugins = list;
+    }
+
+    public boolean isFailOk() {
+        String v = getProperty(Analyzer.FAIL_OK, null);
+        return v != null && v.equalsIgnoreCase("true");
+    }
+
+    public File getBase() {
+        return base;
+    }
+
+    public void setBase(File base) {
+        this.base = base;
+    }
+
+    public void clear() {
+        errors.clear();
+        warnings.clear();
+    }
+
+    public void trace(String msg, Object... parms) {
+        if (trace) {
+            System.out.printf("# " + msg + "\n", parms);
+        }
+    }
+
+    public <T> List<T> newList() {
+        return new ArrayList<T>();
+    }
+
+    public <T> Set<T> newSet() {
+        return new TreeSet<T>();
+    }
+
+    public static <K, V> Map<K, V> newMap() {
+        return new LinkedHashMap<K, V>();
+    }
+
+    public static <K, V> Map<K, V> newHashMap() {
+        return new HashMap<K, V>();
+    }
+
+    public <T> List<T> newList(Collection<T> t) {
+        return new ArrayList<T>(t);
+    }
+
+    public <T> Set<T> newSet(Collection<T> t) {
+        return new TreeSet<T>(t);
+    }
+
+    public <K, V> Map<K, V> newMap(Map<K, V> t) {
+        return new LinkedHashMap<K, V>(t);
+    }
+
+    public void close() {
+        for (Closeable c : toBeClosed) {
+            try {
+                c.close();
+            } catch (IOException e) {
+                // Who cares?
+            }
+        }
+        toBeClosed = null;
+    }
+
+    public String _basedir(String args[]) {
+        if (base == null)
+            throw new IllegalArgumentException("No base dir set");
+
+        return base.getAbsolutePath();
+    }
+
+    /**
+     * Property handling ...
+     * 
+     * @return
+     */
+
+    public Properties getProperties() {
+        if (fixup) {
+            fixup = false;
+            begin();
+        }
+
+        return properties;
+    }
+
+    public String getProperty(String key) {
+        return getProperty(key, null);
+    }
+
+    public void mergeProperties(File file, boolean override) {
+        if (file.isFile()) {
+            try {
+                Properties properties = loadProperties(file);
+                mergeProperties(properties, override);
+            } catch (Exception e) {
+                error("Error loading properties file: " + file);
+            }
+        } else {
+            if (!file.exists())
+                error("Properties file does not exist: " + file);
+            else
+                error("Properties file must a file, not a directory: " + file);
+        }
+    }
+
+    public void mergeProperties(Properties properties, boolean override) {
+        for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) {
+            String key = (String) e.nextElement();
+            String value = properties.getProperty(key);
+            if (override || !getProperties().containsKey(key))
+                setProperty(key, value);
+        }
+    }
+
+    public void setProperties(Properties properties) {
+        doIncludes(getBase(), properties, new HashSet<String>());
+        this.properties.putAll(properties);
+    }
+
+    public void addProperties(File file) throws Exception {
+        addIncluded(file);
+        Properties p = loadProperties(file);
+        setProperties(p);
+    }
+
+    public synchronized void addIncluded(File file) {
+        if (included == null)
+            included = new HashSet<File>();
+        included.add(file);
+    }
+
+    /**
+     * Inspect the properties and if you find -includes parse the line included
+     * manifest files or properties files. The files are relative from the given
+     * base, this is normally the base for the analyzer.
+     * 
+     * @param ubase
+     * @param p
+     * @param done
+     * @throws IOException
+     */
+    private void doIncludes(File ubase, Properties p, Set<String> done) {
+        String includes = p.getProperty(INCLUDE);
+        if (includes != null) {
+            includes = getReplacer().process(includes);
+            p.remove(INCLUDE);
+            Collection<String> clauses = parseHeader(includes).keySet();
+
+            for (String value : clauses) {
+                boolean fileMustExist = true;
+                boolean overwrite = true;
+                while (true) {
+                    if (value.startsWith("-")) {
+                        fileMustExist = false;
+                        value = value.substring(1).trim();
+                    } else if (value.startsWith("~")) {
+                        // Overwrite properties!
+                        overwrite = false;
+                        value = value.substring(1).trim();
+                    } else
+                        break;
+                }
+                try {
+                    File file = getFile(ubase, value).getAbsoluteFile();
+                    if (file.isFile()) {
+                        if (included != null && included.contains(file)) {
+                            error("Cyclic include of " + file);
+                        } else {
+                            addIncluded(file);
+                            updateModified(file.lastModified(), "Include "
+                                    + value);
+                            InputStream in = new FileInputStream(file);
+                            Properties sub;
+                            if (file.getName().toLowerCase().endsWith(".mf")) {
+                                sub = getManifestAsProperties(in);
+                            } else
+                                sub = loadProperties(in, file.getAbsolutePath());
+                            in.close();
+
+                            doIncludes(file.getParentFile(), sub, done);
+                            // make sure we do not override properties
+                            if (!overwrite)
+                                sub.keySet().removeAll(p.keySet());
+                            p.putAll(sub);
+                        }
+                    } else {
+                        if (fileMustExist)
+                            error("Included file "
+                                    + file
+                                    + (file.exists() ? " does not exist"
+                                            : " is directory"));
+                    }
+                } catch (IOException e) {
+                    if (fileMustExist)
+                        error("Error in processing included file: " + value, e);
+                }
+            }
+        }
+    }
+
+    public void unsetProperty(String string) {
+        getProperties().remove(string);
+
+    }
+
+    public boolean refresh() {
+        if (propertiesFile == null)
+            return false;
+
+        boolean changed = false;
+        if (included != null) {
+            for (File file : included) {
+
+                if (file.lastModified() > modified) {
+                    changed = true;
+                    break;
+                }
+            }
+        }
+
+        // System.out.println("Modified " + modified + " file: "
+        // + propertiesFile.lastModified() + " diff "
+        // + (modified - propertiesFile.lastModified()));
+
+        // Date last = new Date(propertiesFile.lastModified());
+        // Date current = new Date(modified);
+        changed |= modified < propertiesFile.lastModified();
+        if (changed) {
+            included = null;
+            properties.clear();
+            plugins = null;
+            setProperties(propertiesFile, base);
+            propertiesChanged();
+            return true;
+        }
+        return false;
+    }
+
+    public void propertiesChanged() {
+    }
+
+    /**
+     * Set the properties by file. Setting the properties this way will also set
+     * the base for this analyzer. After reading the properties, this will call
+     * setProperties(Properties) which will handle the includes.
+     * 
+     * @param propertiesFile
+     * @throws FileNotFoundException
+     * @throws IOException
+     */
+    public void setProperties(File propertiesFile) throws IOException {
+        propertiesFile = propertiesFile.getAbsoluteFile();
+        setProperties(propertiesFile, propertiesFile.getParentFile());
+    }
+
+    public void setProperties(File propertiesFile, File base) {
+        this.propertiesFile = propertiesFile.getAbsoluteFile();
+        setBase(base);
+        try {
+            if (propertiesFile.isFile()) {
+                // System.out.println("Loading properties " + propertiesFile);
+                long modified = propertiesFile.lastModified();
+                if (modified > System.currentTimeMillis() + 100) {
+                    System.out.println("Huh? This is in the future "
+                            + propertiesFile);
+                    this.modified = System.currentTimeMillis();
+                } else
+                    this.modified = modified;
+
+                included = null;
+                Properties p = loadProperties(propertiesFile);
+                setProperties(p);
+            } else {
+                if (fileMustExist) {
+                    error("No such properties file: " + propertiesFile);
+                }
+            }
+        } catch (IOException e) {
+            error("Could not load properties " + propertiesFile);
+        }
+    }
+
+    protected void begin() {
+        if (isTrue(getProperty(PEDANTIC)))
+            setPedantic(true);
+    }
+
+    public static boolean isTrue(String value) {
+        return "true".equalsIgnoreCase(value);
+    }
+
+    /**
+     * Get a property with a proper default
+     * 
+     * @param headerName
+     * @param deflt
+     * @return
+     */
+    public String getProperty(String key, String deflt) {
+        String value;
+
+        if (filter != null && filter.contains(key)) {
+            value = (String) getProperties().get(key);
+        } else
+            value = getProperties().getProperty(key);
+
+        if (value != null)
+            return getReplacer().process(value);
+        else if (deflt != null)
+            return getReplacer().process(deflt);
+        else
+            return null;
+    }
+
+    /**
+     * Helper to load a properties file from disk.
+     * 
+     * @param file
+     * @return
+     * @throws IOException
+     */
+    public Properties loadProperties(File file) throws IOException {
+        updateModified(file.lastModified(), "Properties file: " + file);
+        InputStream in = new FileInputStream(file);
+        Properties p = loadProperties(in, file.getAbsolutePath());
+        in.close();
+        return p;
+    }
+
+    Properties loadProperties(InputStream in, String name) throws IOException {
+        int n = name.lastIndexOf('/');
+        if (n > 0)
+            name = name.substring(0, n);
+        if (name.length() == 0)
+            name = ".";
+
+        try {
+            Properties p = new Properties();
+            p.load(in);
+            return replaceAll(p, "\\$\\{\\.\\}", name);
+        } catch (Exception e) {
+            error("Error during loading properties file: " + name + ", error:"
+                    + e);
+            return new Properties();
+        }
+    }
+
+    /**
+     * Replace a string in all the values of the map. This can be used to
+     * preassign variables that change. I.e. the base directory ${.} for a
+     * loaded properties
+     */
+
+    public static Properties replaceAll(Properties p, String pattern,
+            String replacement) {
+        Properties result = new Properties();
+        for (Iterator<Map.Entry<Object, Object>> i = p.entrySet().iterator(); i
+                .hasNext();) {
+            Map.Entry<Object, Object> entry = i.next();
+            String key = (String) entry.getKey();
+            String value = (String) entry.getValue();
+            value = value.replaceAll(pattern, replacement);
+            result.put(key, value);
+        }
+        return result;
+    }
+
+    /**
+     * Merge the attributes of two maps, where the first map can contain
+     * wildcarded names. The idea is that the first map contains patterns (for
+     * example *) with a set of attributes. These patterns are matched against
+     * the found packages in actual. If they match, the result is set with the
+     * merged set of attributes. It is expected that the instructions are
+     * ordered so that the instructor can define which pattern matches first.
+     * Attributes in the instructions override any attributes from the actual.<br/>
+     * 
+     * A pattern is a modified regexp so it looks like globbing. The * becomes a .*
+     * just like the ? becomes a .?. '.' are replaced with \\. Additionally, if
+     * the pattern starts with an exclamation mark, it will remove that matches
+     * for that pattern (- the !) from the working set. So the following
+     * patterns should work:
+     * <ul>
+     * <li>com.foo.bar</li>
+     * <li>com.foo.*</li>
+     * <li>com.foo.???</li>
+     * <li>com.*.[^b][^a][^r]</li>
+     * <li>!com.foo.* (throws away any match for com.foo.*)</li>
+     * </ul>
+     * Enough rope to hang the average developer I would say.
+     * 
+     * 
+     * @param instructions
+     *            the instructions with patterns. A
+     * @param actual
+     *            the actual found packages
+     */
+
+    public static Map<String, Map<String, String>> merge(String type,
+            Map<String, Map<String, String>> instructions,
+            Map<String, Map<String, String>> actual, Set<String> superfluous,
+            Map<String, Map<String, String>> ignored) {
+        Map<String, Map<String, String>> toVisit = new HashMap<String, Map<String, String>>(
+                actual); // we do not want to ruin our
+        // original
+        Map<String, Map<String, String>> result = newMap();
+        for (Iterator<String> i = instructions.keySet().iterator(); i.hasNext();) {
+            String instruction = i.next();
+            String originalInstruction = instruction;
+
+            Map<String, String> instructedAttributes = instructions
+                    .get(instruction);
+
+            // Check if we have a fixed (starts with '=') or a
+            // duplicate name. A fixed name is added to the output without
+            // checking against the contents. Duplicates are marked
+            // at the end. In that case we do not pick up any contained
+            // information but just add them to the output including the
+            // marker.
+            if (instruction.startsWith("=")) {
+                result.put(instruction.substring(1), instructedAttributes);
+                superfluous.remove(originalInstruction);
+                continue;
+            }
+            if (isDuplicate(instruction)) {
+                result.put(instruction, instructedAttributes);
+                superfluous.remove(originalInstruction);
+                continue;
+            }
+
+            Instruction instr = Instruction.getPattern(instruction);
+
+            for (Iterator<String> p = toVisit.keySet().iterator(); p.hasNext();) {
+                String packageName = p.next();
+
+                if (instr.matches(packageName)) {
+                    superfluous.remove(originalInstruction);
+                    if (!instr.isNegated()) {
+                        Map<String, String> newAttributes = new HashMap<String, String>();
+                        newAttributes.putAll(actual.get(packageName));
+                        newAttributes.putAll(instructedAttributes);
+                        result.put(packageName, newAttributes);
+                    } else if (ignored != null) {
+                        ignored.put(packageName, new HashMap<String, String>());
+                    }
+                    p.remove(); // Can never match again for another pattern
+                }
+            }
+
+        }
+        return result;
+    }
+
+    /**
+     * Print a standard Map based OSGi header.
+     * 
+     * @param exports
+     *            map { name => Map { attribute|directive => value } }
+     * @return the clauses
+     */
+    public static String printClauses(Map<String, Map<String, String>> exports,
+            String allowedDirectives) {
+        return printClauses(exports, allowedDirectives, false);
+    }
+
+    public static String printClauses(Map<String, Map<String, String>> exports,
+            String allowedDirectives, boolean checkMultipleVersions) {
+        StringBuffer sb = new StringBuffer();
+        String del = "";
+        for (Iterator<String> i = exports.keySet().iterator(); i.hasNext();) {
+            String name = i.next();
+            Map<String, String> clause = exports.get(name);
+
+            // We allow names to be duplicated in the input
+            // by ending them with '~'. This is necessary to use
+            // the package names as keys. However, we remove these
+            // suffixes in the output so that you can set multiple
+            // exports with different attributes.
+            String outname = removeDuplicateMarker(name);
+            sb.append(del);
+            sb.append(outname);
+            printClause(clause, allowedDirectives, sb);
+            del = ",";
+        }
+        return sb.toString();
+    }
+
+    public static void printClause(Map<String, String> map,
+            String allowedDirectives, StringBuffer sb) {
+
+        for (Iterator<String> j = map.keySet().iterator(); j.hasNext();) {
+            String key = j.next();
+
+            // Skip directives we do not recognize
+            if (!key.startsWith("x-")
+                    && key.endsWith(":")
+                    && (allowedDirectives == null || allowedDirectives
+                            .indexOf(key) < 0))
+                continue;
+
+            String value = ((String) map.get(key)).trim();
+            sb.append(";");
+            sb.append(key);
+            sb.append("=");
+
+            boolean clean = (value.length() >= 2 && value.charAt(0) == '"' && value
+                    .charAt(value.length() - 1) == '"')
+                    || Verifier.TOKEN.matcher(value).matches();
+            if (!clean)
+                sb.append("\"");
+            sb.append(value);
+            if (!clean)
+                sb.append("\"");
+        }
+    }
+
+    public Macro getReplacer() {
+        if (replacer == null)
+            return replacer = new Macro(getProperties(), this,
+                    getMacroDomains());
+        else
+            return replacer;
+    }
+
+    /**
+     * This should be overridden by subclasses to add extra macro command
+     * domains on the search list.
+     * 
+     * @return
+     */
+    protected Object[] getMacroDomains() {
+        return new Object[] {};
+    }
+
+    /**
+     * Return the properties but expand all macros. This always returns a new
+     * Properties object that can be used in any way.
+     * 
+     * @return
+     */
+    public Properties getFlattenedProperties() {
+        return getReplacer().getFlattenedProperties();
+
+    }
+
+    public void updateModified(long time, String reason) {
+        if (time > lastModified) {
+            lastModified = time;
+        }
+    }
+
+    public long lastModified() {
+        return lastModified;
+    }
+
+    /**
+     * Add or override a new property.
+     * 
+     * @param key
+     * @param value
+     */
+    public void setProperty(String key, String value) {
+        checkheader: for (int i = 0; i < headers.length; i++) {
+            if (headers[i].equalsIgnoreCase(value)) {
+                value = headers[i];
+                break checkheader;
+            }
+        }
+        getProperties().put(key, value);
+    }
+
+    /**
+     * Read a manifest but return a properties object.
+     * 
+     * @param in
+     * @return
+     * @throws IOException
+     */
+    public static Properties getManifestAsProperties(InputStream in)
+            throws IOException {
+        Properties p = new Properties();
+        Manifest manifest = new Manifest(in);
+        for (Iterator<Object> it = manifest.getMainAttributes().keySet()
+                .iterator(); it.hasNext();) {
+            Attributes.Name key = (Attributes.Name) it.next();
+            String value = manifest.getMainAttributes().getValue(key);
+            p.put(key.toString(), value);
+        }
+        return p;
+    }
+
+    public File getPropertiesFile() {
+        return propertiesFile;
+    }
+
+    public void setFileMustExist(boolean mustexist) {
+        fileMustExist = mustexist;
+    }
+
+    static public String read(InputStream in) throws Exception {
+        InputStreamReader ir = new InputStreamReader(in);
+        StringBuilder sb = new StringBuilder();
+
+        try {
+            char chars[] = new char[1000];
+            int size = ir.read(chars);
+            while (size > 0) {
+                sb.append(chars, 0, size);
+                size = ir.read(chars);
+            }
+        } finally {
+            ir.close();
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Join a list.
+     * 
+     * @param args
+     * @return
+     */
+    public static String join(Collection<?> list, String delimeter) {
+        if (list == null)
+            return "";
+        StringBuilder sb = new StringBuilder();
+        String del = "";
+        for (Object item : list) {
+            sb.append(del);
+            sb.append(item);
+            del = delimeter;
+        }
+        return sb.toString();
+    }
+    
+    public static String join(Object[] list, String delimeter) {
+        if (list == null)
+            return "";
+        StringBuilder sb = new StringBuilder();
+        String del = "";
+        for (Object item : list) {
+            sb.append(del);
+            sb.append(item);
+            del = delimeter;
+        }
+        return sb.toString();
+    }
+
+    public static String join(Collection<?> list) {
+        return join(list, ",");
+    }
+
+    public static void split(String s, Collection<String> set) {
+
+        String elements[] = s.trim().split(LIST_SPLITTER);
+        for (String element : elements) {
+            if (element.length() > 0)
+                set.add(element);
+        }
+    }
+
+    public static Collection<String> split(String s) {
+        return split(s, LIST_SPLITTER);
+    }
+
+    public static Collection<String> split(String s, String splitter) {
+        if (s != null)
+            s = s.trim();
+        if (s == null || s.trim().length() == 0)
+            return Collections.emptyList();
+
+        return Arrays.asList(s.split(splitter));
+    }
+
+    public boolean isExceptions() {
+        return exceptions;
+    }
+
+    public void setExceptions(boolean exceptions) {
+        this.exceptions = exceptions;
+    }
+
+    /**
+     * Make the file short if it is inside our base directory, otherwise long.
+     * 
+     * @param f
+     * @return
+     */
+    public String normalize(String f) {
+        if (f.startsWith(base.getAbsolutePath() + "/"))
+            return f.substring(base.getAbsolutePath().length() + 1);
+        else
+            return f;
+    }
+
+    public String normalize(File f) {
+        return normalize(f.getAbsolutePath());
+    }
+
+    public static String removeDuplicateMarker(String key) {
+        int i = key.length() - 1;
+        while (i >= 0 && key.charAt(i) == DUPLICATE_MARKER)
+            --i;
+
+        return key.substring(0, i + 1);
+    }
+
+    public static boolean isDuplicate(String name) {
+        return name.length() > 0
+                && name.charAt(name.length() - 1) == DUPLICATE_MARKER;
+    }
+
+    public void setTrace(boolean x) {
+        trace = x;
+    }
+
+    static class CL extends URLClassLoader {
+
+        CL() {
+            super(new URL[0], Processor.class.getClassLoader());
+        }
+
+        void add(URL url) {
+            URL urls[] = getURLs();
+            for (URL u : urls) {
+                if (u.equals(url))
+                    return;
+            }
+            super.addURL(url);
+        }
+
+    }
+
+    private CL getLoader() {
+        if (pluginLoader == null)
+            pluginLoader = new CL();
+        return pluginLoader;
+    }
+
+    public boolean exists() {
+        return base != null && base.exists();
+    }
+
+    public boolean isOk() {
+        return isFailOk() || (getErrors().size() == 0);
+    }
+
+    public boolean isPerfect() {
+        return getErrors().size() == 0 && getWarnings().size() == 0;
+    }
+
+    public void setForceLocal(Collection<String> local) {
+        filter = local;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Resource.java b/bundleplugin/src/main/java/aQute/lib/osgi/Resource.java
new file mode 100644
index 0000000..d619f47
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Resource.java
@@ -0,0 +1,13 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+
+public interface Resource {
+	InputStream openInputStream() throws IOException ;
+	void write(OutputStream out) throws IOException;
+	long lastModified();
+	void setExtra(String extra);
+	String getExtra();	
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/URLResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/URLResource.java
new file mode 100644
index 0000000..f43ac91
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/URLResource.java
@@ -0,0 +1,39 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.net.*;
+
+public class URLResource implements Resource {
+	URL	url;
+	String	extra;
+	
+	public URLResource(URL url) {
+		this.url = url;
+	}
+
+	public InputStream openInputStream() throws IOException {
+		return url.openStream();
+	}
+
+	public String toString() {
+		return ":" + url.getPath() + ":";
+	}
+
+	public void write(OutputStream out) throws IOException {
+		FileResource.copy(this, out);
+	}
+
+	public long lastModified() {
+		return -1;
+	}
+
+	public String getExtra() {
+		return extra;
+	}
+
+	public void setExtra(String extra) {
+		this.extra = extra;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Verifier.java b/bundleplugin/src/main/java/aQute/lib/osgi/Verifier.java
new file mode 100644
index 0000000..85b36d4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Verifier.java
@@ -0,0 +1,792 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.libg.qtokens.*;
+
+public class Verifier extends Analyzer {
+
+    Jar                              dot;
+    Manifest                         manifest;
+    Map<String, Map<String, String>> referred              = newHashMap();
+    Map<String, Map<String, String>> contained             = newHashMap();
+    Map<String, Set<String>>         uses                  = newHashMap();
+    Map<String, Map<String, String>> mimports;
+    Map<String, Map<String, String>> mdynimports;
+    Map<String, Map<String, String>> mexports;
+    List<Jar>                        bundleClasspath;
+    Map<String, Map<String, String>> ignore                = newHashMap();                                                         // Packages
+    // to
+    // ignore
+
+    Map<String, Clazz>               classSpace;
+    boolean                          r3;
+    boolean                          usesRequire;
+    boolean                          fragment;
+    Attributes                       main;
+
+    final static Pattern             EENAME                = Pattern
+                                                                   .compile("CDC-1\\.0/Foundation-1\\.0"
+                                                                           + "|CDC-1\\.1/Foundation-1\\.1"
+                                                                           + "|OSGi/Minimum-1\\.[1-9]"
+                                                                           + "|JRE-1\\.1"
+                                                                           + "|J2SE-1\\.2"
+                                                                           + "|J2SE-1\\.3"
+                                                                           + "|J2SE-1\\.4"
+                                                                           + "|J2SE-1\\.5"
+                                                                           + "|JavaSE-1\\.6"
+                                                                           + "|JavaSE-1\\.7"
+                                                                           + "|PersonalJava-1\\.1"
+                                                                           + "|PersonalJava-1\\.2"
+                                                                           + "|CDC-1\\.0/PersonalBasis-1\\.0"
+                                                                           + "|CDC-1\\.0/PersonalJava-1\\.0");
+
+    final static Pattern             BUNDLEMANIFESTVERSION = Pattern
+                                                                   .compile("2");
+    public final static String       SYMBOLICNAME_STRING   = "[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*";
+    public final static Pattern      SYMBOLICNAME          = Pattern
+                                                                   .compile(SYMBOLICNAME_STRING);
+
+    public final static String       VERSION_STRING        = "[0-9]+(\\.[0-9]+(\\.[0-9]+(\\.[0-9A-Za-z_-]+)?)?)?";
+    public final static Pattern      VERSION               = Pattern
+                                                                   .compile(VERSION_STRING);
+    final static Pattern             FILTEROP              = Pattern
+                                                                   .compile("=|<=|>=|~=");
+    public final static Pattern             VERSIONRANGE          = Pattern
+                                                                   .compile("((\\(|\\[)"
+                                                                           + VERSION_STRING
+                                                                           + ","
+                                                                           + VERSION_STRING
+                                                                           + "(\\]|\\)))|"
+                                                                           + VERSION_STRING);
+    final static Pattern             FILE                  = Pattern
+                                                                   .compile("/?[^/\"\n\r\u0000]+(/[^/\"\n\r\u0000]+)*");
+    final static Pattern             WILDCARDPACKAGE       = Pattern
+                                                                   .compile("((\\p{Alnum}|_)+(\\.(\\p{Alnum}|_)+)*(\\.\\*)?)|\\*");
+    public final static Pattern      ISO639                = Pattern
+                                                                   .compile("[A-Z][A-Z]");
+    public final static Pattern      HEADER_PATTERN        = Pattern
+                                                                   .compile("[A-Za-z0-9][-a-zA-Z0-9_]+");
+    public final static Pattern      TOKEN                 = Pattern
+                                                                   .compile("[-a-zA-Z0-9_]+");
+
+    public final static Pattern      NUMBERPATTERN         = Pattern
+                                                                   .compile("\\d+");
+    public final static Pattern      PATHPATTERN           = Pattern
+                                                                   .compile(".*");
+    public final static Pattern      FQNPATTERN            = Pattern
+                                                                   .compile(".*");
+    public final static Pattern      URLPATTERN            = Pattern
+                                                                   .compile(".*");
+    public final static Pattern      ANYPATTERN            = Pattern
+                                                                   .compile(".*");
+    public final static Pattern      FILTERPATTERN         = Pattern
+                                                                   .compile(".*");
+    public final static Pattern TRUEORFALSEPATTERN = Pattern.compile("true|false|TRUE|FALSE");
+    public static final Pattern WILDCARDNAMEPATTERN = Pattern.compile(".*");
+    
+    public final static String EES[] = {
+        "CDC-1.0/Foundation-1.0",
+        "CDC-1.1/Foundation-1.1",
+        "OSGi/Minimum-1.0",
+        "OSGi/Minimum-1.1",
+        "OSGi/Minimum-1.2",
+        "JRE-1.1",
+        "J2SE-1.2",
+        "J2SE-1.3",
+        "J2SE-1.4",
+        "J2SE-1.5",
+        "JavaSE-1.6",
+        "JavaSE-1.7",
+        "PersonalJava-1.1",
+        "PersonalJava-1.2",
+        "CDC-1.0/PersonalBasis-1.0",
+        "CDC-1.0/PersonalJava-1.0"
+        };
+    
+    public final static String       OSNAMES[]             = {
+            "AIX", // IBM
+            "DigitalUnix", // Compaq
+            "Embos", // Segger Embedded Software Solutions
+            "Epoc32", // SymbianOS Symbian OS
+            "FreeBSD", // Free BSD
+            "HPUX", // hp-ux Hewlett Packard
+            "IRIX", // Silicon Graphics
+            "Linux", // Open source
+            "MacOS", // Apple
+            "NetBSD", // Open source
+            "Netware", // Novell
+            "OpenBSD", // Open source
+            "OS2", // OS/2 IBM
+            "QNX", // procnto QNX
+            "Solaris", // Sun (almost an alias of SunOS)
+            "SunOS", // Sun Microsystems
+            "VxWorks", // WindRiver Systems
+            "Windows95", "Win32", "Windows98", "WindowsNT", "WindowsCE",
+            "Windows2000", // Win2000
+            "Windows2003", // Win2003
+            "WindowsXP", "WindowsVista",                  };
+
+    public final static String       PROCESSORNAMES[]      = { "68k", // Motorola
+            // 68000
+            "ARM_LE", // Intel Strong ARM. Deprecated because it does not
+            // specify the endianness. See the following two rows.
+            "arm_le", // Intel Strong ARM Little Endian mode
+            "arm_be", // Intel String ARM Big Endian mode
+            "Alpha", //
+            "ia64n",// Hewlett Packard 64 bit
+            "ia64w",// Hewlett Packard 32 bit mode
+            "Ignite", // psc1k PTSC
+            "Mips", // SGI
+            "PArisc", // Hewlett Packard
+            "PowerPC", // power ppc Motorola/IBM Power PC
+            "Sh4", // Hitachi
+            "Sparc", // SUN
+            "S390", // IBM Mainframe 31 bit
+            "S390x", // IBM Mainframe 64-bit
+            "V850E", // NEC V850E
+            "x86", // pentium i386
+            "i486", // i586 i686 Intel& AMD 32 bit
+            "x86-64",                                     };
+
+    Properties                       properties;
+
+    public Verifier(Jar jar) throws Exception {
+        this(jar, null);
+    }
+
+    public Verifier(Jar jar, Properties properties) throws Exception {
+        this.dot = jar;
+        this.properties = properties;
+        this.manifest = jar.getManifest();
+        if (manifest == null) {
+            manifest = new Manifest();
+            error("This file contains no manifest and is therefore not a bundle");
+        }
+        main = this.manifest.getMainAttributes();
+        verifyHeaders(main);
+        r3 = getHeader(Analyzer.BUNDLE_MANIFESTVERSION) == null;
+        usesRequire = getHeader(Analyzer.REQUIRE_BUNDLE) != null;
+        fragment = getHeader(Analyzer.FRAGMENT_HOST) != null;
+
+        bundleClasspath = getBundleClassPath();
+        mimports = parseHeader(manifest.getMainAttributes().getValue(
+                Analyzer.IMPORT_PACKAGE));
+        mdynimports = parseHeader(manifest.getMainAttributes().getValue(
+                Analyzer.DYNAMICIMPORT_PACKAGE));
+        mexports = parseHeader(manifest.getMainAttributes().getValue(
+                Analyzer.EXPORT_PACKAGE));
+
+        ignore = parseHeader(manifest.getMainAttributes().getValue(
+                Analyzer.IGNORE_PACKAGE));
+    }
+
+    public Verifier() {
+        // TODO Auto-generated constructor stub
+    }
+
+    private void verifyHeaders(Attributes main) {
+        for (Object element : main.keySet()) {
+            Attributes.Name header = (Attributes.Name) element;
+            String h = header.toString();
+            if (!HEADER_PATTERN.matcher(h).matches())
+                error("Invalid Manifest header: " + h + ", pattern="
+                        + HEADER_PATTERN);
+        }
+    }
+
+    private List<Jar> getBundleClassPath() {
+        List<Jar> list = newList();
+        String bcp = getHeader(Analyzer.BUNDLE_CLASSPATH);
+        if (bcp == null) {
+            list.add(dot);
+        } else {
+            Map<String, Map<String, String>> entries = parseHeader(bcp);
+            for (String jarOrDir : entries.keySet()) {
+                if (jarOrDir.equals(".")) {
+                    list.add(dot);
+                } else {
+                    if (jarOrDir.equals("/"))
+                        jarOrDir = "";
+                    if (jarOrDir.endsWith("/")) {
+                        error("Bundle-Classpath directory must not end with a slash: "
+                                + jarOrDir);
+                        jarOrDir = jarOrDir.substring(0, jarOrDir.length() - 1);
+                    }
+
+                    Resource resource = dot.getResource(jarOrDir);
+                    if (resource != null) {
+                        try {
+                            Jar sub = new Jar(jarOrDir);
+                            addClose(sub);
+                            EmbeddedResource.build(sub, resource);
+                            if (!jarOrDir.endsWith(".jar"))
+                                warning("Valid JAR file on Bundle-Classpath does not have .jar extension: "
+                                        + jarOrDir);
+                            list.add(sub);
+                        } catch (Exception e) {
+                            error("Invalid embedded JAR file on Bundle-Classpath: "
+                                    + jarOrDir + ", " + e);
+                        }
+                    } else if (dot.getDirectories().containsKey(jarOrDir)) {
+                        if (r3)
+                            error("R3 bundles do not support directories on the Bundle-ClassPath: "
+                                    + jarOrDir);
+
+                        try {
+                            Jar sub = new Jar(jarOrDir);
+                            addClose(sub);
+                            for (Map.Entry<String, Resource> entry : dot
+                                    .getResources().entrySet()) {
+                                if (entry.getKey().startsWith(jarOrDir))
+                                    sub.putResource(entry.getKey().substring(
+                                            jarOrDir.length() + 1), entry
+                                            .getValue());
+                            }
+                            list.add(sub);
+                        } catch (Exception e) {
+                            error("Invalid embedded directory file on Bundle-Classpath: "
+                                    + jarOrDir + ", " + e);
+                        }
+                    } else {
+                        error("Cannot find a file or directory for Bundle-Classpath entry: "
+                                + jarOrDir);
+                    }
+                }
+            }
+        }
+        return list;
+    }
+
+    /*
+     * Bundle-NativeCode ::= nativecode ( ',' nativecode )* ( ’,’ optional) ?
+     * nativecode ::= path ( ';' path )* // See 1.4.2 ( ';' parameter )+
+     * optional ::= ’*’
+     */
+    public void verifyNative() {
+        String nc = getHeader("Bundle-NativeCode");
+        doNative(nc);
+    }
+
+    public void doNative(String nc) {
+        if (nc != null) {
+            QuotedTokenizer qt = new QuotedTokenizer(nc, ",;=", false);
+            char del;
+            do {
+                do {
+                    String name = qt.nextToken();
+                    if (name == null) {
+                        error("Can not parse name from bundle native code header: "
+                                + nc);
+                        return;
+                    }
+                    del = qt.getSeparator();
+                    if (del == ';') {
+                        if (dot != null && !dot.exists(name)) {
+                            error("Native library not found in JAR: " + name);
+                        }
+                    } else {
+                        String value = null;
+                        if (del == '=')
+                            value = qt.nextToken();
+
+                        String key = name.toLowerCase();
+                        if (key.equals("osname")) {
+                            // ...
+                        } else if (key.equals("osversion")) {
+                            // verify version range
+                            verify(value, VERSIONRANGE);
+                        } else if (key.equals("language")) {
+                            verify(value, ISO639);
+                        } else if (key.equals("processor")) {
+                            // verify(value, PROCESSORS);
+                        } else if (key.equals("selection-filter")) {
+                            // verify syntax filter
+                            verifyFilter(value);
+                        } else if (name.equals("*") && value == null) {
+                            // Wildcard must be at end.
+                            if (qt.nextToken() != null)
+                                error("Bundle-Native code header may only END in wildcard: nc");
+                        } else {
+                            warning("Unknown attribute in native code: " + name
+                                    + "=" + value);
+                        }
+                        del = qt.getSeparator();
+                    }
+                } while (del == ';');
+            } while (del == ',');
+        }
+    }
+
+    public void verifyFilter(String value) {
+        try {
+            verifyFilter(value, 0);
+        } catch (Exception e) {
+            error("Not a valid filter: " + value + e.getMessage());
+        }
+    }
+
+    private void verifyActivator() {
+        String bactivator = getHeader("Bundle-Activator");
+        if (bactivator != null) {
+            Clazz cl = loadClass(bactivator);
+            if (cl == null) {
+                int n = bactivator.lastIndexOf('.');
+                if (n > 0) {
+                    String pack = bactivator.substring(0, n);
+                    if (mimports.containsKey(pack))
+                        return;
+                    error("Bundle-Activator not found on the bundle class path nor in imports: "
+                            + bactivator);
+                } else
+                    error("Activator uses default package and is not local (default package can not be imported): "
+                            + bactivator);
+            }
+        }
+    }
+
+    private Clazz loadClass(String className) {
+        String path = className.replace('.', '/') + ".class";
+        return (Clazz) classSpace.get(path);
+    }
+
+    private void verifyComponent() {
+        String serviceComponent = getHeader("Service-Component");
+        if (serviceComponent != null) {
+            Map<String, Map<String, String>> map = parseHeader(serviceComponent);
+            for (String component : map.keySet()) {
+                if (component.indexOf("*")<0 && !dot.exists(component)) {
+                    error("Service-Component entry can not be located in JAR: "
+                            + component);
+                } else {
+                    // validate component ...
+                }
+            }
+        }
+    }
+
+    public void info() {
+        System.out.println("Refers                           : " + referred);
+        System.out.println("Contains                         : " + contained);
+        System.out.println("Manifest Imports                 : " + mimports);
+        System.out.println("Manifest Exports                 : " + mexports);
+    }
+
+    /**
+     * Invalid exports are exports mentioned in the manifest but not found on
+     * the classpath. This can be calculated with: exports - contains.
+     * 
+     * Unfortunately, we also must take duplicate names into account. These
+     * duplicates are of course no erroneous.
+     */
+    private void verifyInvalidExports() {
+        Set<String> invalidExport = newSet(mexports.keySet());
+        invalidExport.removeAll(contained.keySet());
+
+        // We might have duplicate names that are marked for it. These
+        // should not be counted. Should we test them against the contained
+        // set? Hmm. If someone wants to hang himself by using duplicates than
+        // I guess he can go ahead ... This is not a recommended practice
+        for (Iterator<String> i = invalidExport.iterator(); i.hasNext();) {
+            String pack = i.next();
+            if (isDuplicate(pack))
+                i.remove();
+        }
+
+        if (!invalidExport.isEmpty())
+            error("Exporting packages that are not on the Bundle-Classpath"
+                    + bundleClasspath + ": " + invalidExport);
+    }
+
+    /**
+     * Invalid imports are imports that we never refer to. They can be
+     * calculated by removing the refered packages from the imported packages.
+     * This leaves packages that the manifest imported but that we never use.
+     */
+    private void verifyInvalidImports() {
+        Set<String> invalidImport = newSet(mimports.keySet());
+        invalidImport.removeAll(referred.keySet());
+        // TODO Added this line but not sure why it worked before ...
+        invalidImport.removeAll(contained.keySet());
+        String bactivator = getHeader(Analyzer.BUNDLE_ACTIVATOR);
+        if (bactivator != null) {
+            int n = bactivator.lastIndexOf('.');
+            if (n > 0) {
+                invalidImport.remove(bactivator.substring(0, n));
+            }
+        }
+        if (isPedantic() && !invalidImport.isEmpty())
+            warning("Importing packages that are never refered to by any class on the Bundle-Classpath"
+                    + bundleClasspath + ": " + invalidImport);
+    }
+
+    /**
+     * Check for unresolved imports. These are referals that are not imported by
+     * the manifest and that are not part of our bundle classpath. The are
+     * calculated by removing all the imported packages and contained from the
+     * refered packages.
+     */
+    private void verifyUnresolvedReferences() {
+        Set<String> unresolvedReferences = new TreeSet<String>(referred
+                .keySet());
+        unresolvedReferences.removeAll(mimports.keySet());
+        unresolvedReferences.removeAll(contained.keySet());
+
+        // Remove any java.** packages.
+        for (Iterator<String> p = unresolvedReferences.iterator(); p.hasNext();) {
+            String pack = p.next();
+            if (pack.startsWith("java.") || ignore.containsKey(pack))
+                p.remove();
+            else {
+                // Remove any dynamic imports
+                if (isDynamicImport(pack))
+                    p.remove();
+            }
+        }
+
+        if (!unresolvedReferences.isEmpty()) {
+            // Now we want to know the
+            // classes that are the culprits
+            Set<String> culprits = new HashSet<String>();
+            for (Clazz clazz : classSpace.values()) {
+                if (hasOverlap(unresolvedReferences, clazz.imports.keySet()))
+                    culprits.add(clazz.getPath());
+            }
+
+            error("Unresolved references to " + unresolvedReferences
+                    + " by class(es) on the Bundle-Classpath" + bundleClasspath
+                    + ": " + culprits);
+        }
+    }
+
+    /**
+     * @param p
+     * @param pack
+     */
+    private boolean isDynamicImport(String pack) {
+        for (String pattern : mdynimports.keySet()) {
+            // Wildcard?
+            if (pattern.equals("*"))
+                return true; // All packages can be dynamically imported
+
+            if (pattern.endsWith(".*")) {
+                pattern = pattern.substring(0, pattern.length() - 2);
+                if (pack.startsWith(pattern)
+                        && (pack.length() == pattern.length() || pack
+                                .charAt(pattern.length()) == '.'))
+                    return true;
+            } else {
+                if (pack.equals(pattern))
+                    return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean hasOverlap(Set<?> a, Set<?> b) {
+        for (Iterator<?> i = a.iterator(); i.hasNext();) {
+            if (b.contains(i.next()))
+                return true;
+        }
+        return false;
+    }
+
+    public void verify() throws IOException {
+        if (classSpace == null)
+            classSpace = analyzeBundleClasspath(dot,
+                    parseHeader(getHeader(Analyzer.BUNDLE_CLASSPATH)),
+                    contained, referred, uses);
+        verifyManifestFirst();
+        verifyActivator();
+        verifyComponent();
+        verifyNative();
+        verifyInvalidExports();
+        verifyInvalidImports();
+        verifyUnresolvedReferences();
+        verifySymbolicName();
+        verifyListHeader("Bundle-RequiredExecutionEnvironment", EENAME, false);
+        verifyHeader("Bundle-ManifestVersion", BUNDLEMANIFESTVERSION, false);
+        verifyHeader("Bundle-Version", VERSION, true);
+        verifyListHeader("Bundle-Classpath", FILE, false);
+        verifyDynamicImportPackage();
+        verifyBundleClasspath();
+        if (usesRequire) {
+            if (!getErrors().isEmpty()) {
+                getWarnings()
+                        .add(
+                                0,
+                                "Bundle uses Require Bundle, this can generate false errors because then not enough information is available without the required bundles");
+            }
+        }
+    }
+
+    public void verifyBundleClasspath() {
+        Map<String, Map<String, String>> bcp = parseHeader(getHeader(Analyzer.BUNDLE_CLASSPATH));
+        if (bcp.isEmpty() || bcp.containsKey("."))
+            return;
+
+        for (String path : dot.getResources().keySet()) {
+            if (path.endsWith(".class")) {
+                warning("The Bundle-Classpath does not contain the actual bundle JAR (as specified with '.' in the Bundle-Classpath) but the JAR does contain classes. Is this intentional?");
+                return;
+            }
+        }
+    }
+
+    /**
+     * <pre>
+     *          DynamicImport-Package ::= dynamic-description
+     *              ( ',' dynamic-description )*
+     *              
+     *          dynamic-description::= wildcard-names ( ';' parameter )*
+     *          wildcard-names ::= wildcard-name ( ';' wildcard-name )*
+     *          wildcard-name ::= package-name 
+     *                         | ( package-name '.*' ) // See 1.4.2
+     *                         | '*'
+     * </pre>
+     */
+    private void verifyDynamicImportPackage() {
+        verifyListHeader("DynamicImport-Package", WILDCARDPACKAGE, true);
+        String dynamicImportPackage = getHeader("DynamicImport-Package");
+        if (dynamicImportPackage == null)
+            return;
+
+        Map<String, Map<String, String>> map = parseHeader(dynamicImportPackage);
+        for (String name : map.keySet()) {
+            name = name.trim();
+            if (!verify(name, WILDCARDPACKAGE))
+                error("DynamicImport-Package header contains an invalid package name: "
+                        + name);
+
+            Map<String, String> sub = map.get(name);
+            if (r3 && sub.size() != 0) {
+                error("DynamicPackage-Import has attributes on import: "
+                        + name
+                        + ". This is however, an <=R3 bundle and attributes on this header were introduced in R4. ");
+            }
+        }
+    }
+
+    private void verifyManifestFirst() {
+        if (!dot.manifestFirst) {
+            error("Invalid JAR stream: Manifest should come first to be compatible with JarInputStream, it was not");
+        }
+    }
+
+    private void verifySymbolicName() {
+        Map<String, Map<String, String>> bsn = parseHeader(getHeader(Analyzer.BUNDLE_SYMBOLICNAME));
+        if (!bsn.isEmpty()) {
+            if (bsn.size() > 1)
+                error("More than one BSN specified " + bsn);
+
+            String name = (String) bsn.keySet().iterator().next();
+            if (!SYMBOLICNAME.matcher(name).matches()) {
+                error("Symbolic Name has invalid format: " + name);
+            }
+        }
+    }
+
+    /**
+     * <pre>
+     *         filter ::= ’(’ filter-comp ’)’
+     *         filter-comp ::= and | or | not | operation
+     *         and ::= ’&amp;’ filter-list
+     *         or ::= ’|’ filter-list
+     *         not ::= ’!’ filter
+     *         filter-list ::= filter | filter filter-list
+     *         operation ::= simple | present | substring
+     *         simple ::= attr filter-type value
+     *         filter-type ::= equal | approx | greater | less
+     *         equal ::= ’=’
+     *         approx ::= ’&tilde;=’
+     *         greater ::= ’&gt;=’
+     *         less ::= ’&lt;=’
+     *         present ::= attr ’=*’
+     *         substring ::= attr ’=’ initial any final
+     *         inital ::= () | value
+     *         any ::= ’*’ star-value
+     *         star-value ::= () | value ’*’ star-value
+     *         final ::= () | value
+     *         value ::= &lt;see text&gt;
+     * </pre>
+     * 
+     * @param expr
+     * @param index
+     * @return
+     */
+
+    int verifyFilter(String expr, int index) {
+        try {
+            while (Character.isWhitespace(expr.charAt(index)))
+                index++;
+
+            if (expr.charAt(index) != '(')
+                throw new IllegalArgumentException(
+                        "Filter mismatch: expected ( at position " + index
+                                + " : " + expr);
+
+            index++;
+            while (Character.isWhitespace(expr.charAt(index)))
+                index++;
+
+            switch (expr.charAt(index)) {
+            case '!':
+            case '&':
+            case '|':
+                return verifyFilterSubExpression(expr, index) + 1;
+
+            default:
+                return verifyFilterOperation(expr, index) + 1;
+            }
+        } catch (IndexOutOfBoundsException e) {
+            throw new IllegalArgumentException(
+                    "Filter mismatch: early EOF from " + index);
+        }
+    }
+
+    private int verifyFilterOperation(String expr, int index) {
+        StringBuffer sb = new StringBuffer();
+        while ("=><~()".indexOf(expr.charAt(index)) < 0) {
+            sb.append(expr.charAt(index++));
+        }
+        String attr = sb.toString().trim();
+        if (attr.length() == 0)
+            throw new IllegalArgumentException(
+                    "Filter mismatch: attr at index " + index + " is 0");
+        sb = new StringBuffer();
+        while ("=><~".indexOf(expr.charAt(index)) >= 0) {
+            sb.append(expr.charAt(index++));
+        }
+        String operator = sb.toString();
+        if (!verify(operator, FILTEROP))
+            throw new IllegalArgumentException(
+                    "Filter error, illegal operator " + operator + " at index "
+                            + index);
+
+        sb = new StringBuffer();
+        while (")".indexOf(expr.charAt(index)) < 0) {
+            switch (expr.charAt(index)) {
+            case '\\':
+                if (expr.charAt(index + 1) == '*'
+                        || expr.charAt(index + 1) == ')')
+                    index++;
+                else
+                    throw new IllegalArgumentException(
+                            "Filter error, illegal use of backslash at index "
+                                    + index
+                                    + ". Backslash may only be used before * or (");
+            }
+            sb.append(expr.charAt(index++));
+        }
+        return index;
+    }
+
+    private int verifyFilterSubExpression(String expr, int index) {
+        do {
+            index = verifyFilter(expr, index + 1);
+            while (Character.isWhitespace(expr.charAt(index)))
+                index++;
+            if (expr.charAt(index) != ')')
+                throw new IllegalArgumentException(
+                        "Filter mismatch: expected ) at position " + index
+                                + " : " + expr);
+            index++;
+        } while (expr.charAt(index) == '(');
+        return index;
+    }
+
+    private String getHeader(String string) {
+        return main.getValue(string);
+    }
+
+    @SuppressWarnings("unchecked")
+    private boolean verifyHeader(String name, Pattern regex, boolean error) {
+        String value = manifest.getMainAttributes().getValue(name);
+        if (value == null)
+            return false;
+
+        QuotedTokenizer st = new QuotedTokenizer(value.trim(), ",");
+        for (Iterator<String> i = st.getTokenSet().iterator(); i.hasNext();) {
+            if (!verify((String) i.next(), regex)) {
+                String msg = "Invalid value for " + name + ", " + value
+                        + " does not match " + regex.pattern();
+                if (error)
+                    error(msg);
+                else
+                    warning(msg);
+            }
+        }
+        return true;
+    }
+
+    private boolean verify(String value, Pattern regex) {
+        return regex.matcher(value).matches();
+    }
+
+    private boolean verifyListHeader(String name, Pattern regex, boolean error) {
+        String value = manifest.getMainAttributes().getValue(name);
+        if (value == null)
+            return false;
+
+        Map<String, Map<String, String>> map = parseHeader(value);
+        for (String header : map.keySet()) {
+            if (!regex.matcher(header).matches()) {
+                String msg = "Invalid value for " + name + ", " + value
+                        + " does not match " + regex.pattern();
+                if (error)
+                    error(msg);
+                else
+                    warning(msg);
+            }
+        }
+        return true;
+    }
+
+    public String getProperty(String key, String deflt) {
+        if (properties == null)
+            return deflt;
+        return properties.getProperty(key, deflt);
+    }
+
+    public void setClassSpace(Map<String, Clazz> classspace,
+            Map<String, Map<String, String>> contained,
+            Map<String, Map<String, String>> referred,
+            Map<String, Set<String>> uses) {
+        this.classSpace = classspace;
+        this.contained = contained;
+        this.referred = referred;
+        this.uses = uses;
+    }
+
+    public static boolean isVersion(String version) {
+        return VERSION.matcher(version).matches();
+    }
+
+    public static boolean isIdentifier(String value) {
+        if ( value.length() < 1 ) 
+            return false;
+        
+        if ( !Character.isJavaIdentifierStart(value.charAt(0)))
+                return false;
+        
+        for ( int i = 1; i<value.length(); i++ ) {
+            if ( !Character.isJavaIdentifierPart(value.charAt(i)))
+                return false;
+        }
+        return true;
+    }
+
+    public static boolean isMember(String value, String[] matches) {
+        for ( String match : matches ) {
+            if ( match.equals(value) )
+                return true;
+        }
+        return false;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/ZipResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/ZipResource.java
new file mode 100644
index 0000000..890dbdc
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/ZipResource.java
@@ -0,0 +1,82 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+import java.util.zip.*;
+
+public class ZipResource implements Resource {
+    ZipFile  zip;
+    ZipEntry entry;
+    long     lastModified;
+    String   extra;
+
+    ZipResource(ZipFile zip, ZipEntry entry, long lastModified) {
+        this.zip = zip;
+        this.entry = entry;
+        this.lastModified = lastModified;
+        byte[] data = entry.getExtra();
+        if (data != null)
+            this.extra = new String(data);
+    }
+
+    public InputStream openInputStream() throws IOException {
+        return zip.getInputStream(entry);
+    }
+
+    public String toString() {
+        return ":" + entry.getName() + ":";
+    }
+
+    public static ZipFile build(Jar jar, File file) throws ZipException,
+            IOException {
+        return build(jar, file, null);
+    }
+
+    public static ZipFile build(Jar jar, File file, Pattern pattern)
+            throws ZipException, IOException {
+
+        try {
+            ZipFile zip = new ZipFile(file);
+            nextEntry: for (Enumeration<? extends ZipEntry> e = zip.entries(); e
+                    .hasMoreElements();) {
+                ZipEntry entry = e.nextElement();
+                if (pattern != null) {
+                    Matcher m = pattern.matcher(entry.getName());
+                    if (!m.matches())
+                        continue nextEntry;
+                }
+                if (!entry.isDirectory()) {
+                    long time = entry.getTime();
+                    if (time <= 0)
+                        time = file.lastModified();
+                    jar.putResource(entry.getName(), new ZipResource(zip,
+                            entry, time), true);
+                }
+            }
+            return zip;
+        } catch (FileNotFoundException e) {
+            throw new IllegalArgumentException("Problem opening JAR: "
+                    + file.getAbsolutePath());
+        }
+    }
+
+    public void write(OutputStream out) throws IOException {
+        FileResource.copy(this, out);
+    }
+
+    public long lastModified() {
+        return lastModified;
+    }
+
+    public String getExtra() {
+        return extra;
+    }
+
+    public void setExtra(String extra) {
+        this.extra = extra;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/eclipse/EclipseClasspath.java b/bundleplugin/src/main/java/aQute/lib/osgi/eclipse/EclipseClasspath.java
new file mode 100644
index 0000000..7aa947f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/eclipse/EclipseClasspath.java
@@ -0,0 +1,250 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.lib.osgi.eclipse;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.xml.parsers.*;
+
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+import aQute.libg.reporter.*;
+
+/**
+ * Parse the Eclipse project information for the classpath. Unfortunately, it is
+ * impossible to read the variables. They are ignored but that can cause
+ * problems.
+ * 
+ * @version $Revision: 1.1 $
+ */
+public class EclipseClasspath {
+    static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
+                                                                 .newInstance();
+    DocumentBuilder               db;
+    File                          project;
+    File                          workspace;
+    Set<File>                     sources                = new LinkedHashSet<File>();
+    Set<File>                     allSources                = new LinkedHashSet<File>();
+    
+    Set<File>                     classpath              = new LinkedHashSet<File>();
+    List<File>                    dependents             = new ArrayList<File>();
+    File                          output;
+    boolean                       recurse                = true;
+    Set<File>                     exports                = new LinkedHashSet<File>();
+    Map<String, String>           properties             = new HashMap<String, String>();
+    Reporter                      reporter;
+    int                           options;
+    Set<File>                     bootclasspath          = new LinkedHashSet<File>();
+
+    public final static int       DO_VARIABLES           = 1;
+
+    /**
+     * Parse an Eclipse project structure to discover the classpath.
+     * 
+     * @param workspace
+     *            Points to workspace
+     * @param project
+     *            Points to project
+     * @throws ParserConfigurationException
+     * @throws SAXException
+     * @throws IOException
+     */
+
+    public EclipseClasspath(Reporter reporter, File workspace, File project,
+            int options) throws Exception {
+        this.project = project.getCanonicalFile();
+        this.workspace = workspace.getCanonicalFile();
+        this.reporter = reporter;
+        db = documentBuilderFactory.newDocumentBuilder();
+        parse(this.project, true);
+        db = null;
+    }
+
+    public EclipseClasspath(Reporter reporter, File workspace, File project)
+            throws Exception {
+        this(reporter, workspace, project, 0);
+    }
+
+    /**
+     * Recursive routine to parse the files. If a sub project is detected, it is
+     * parsed before the parsing continues. This should give the right order.
+     * 
+     * @param project
+     *            Project directory
+     * @param top
+     *            If this is the top project
+     * @throws ParserConfigurationException
+     * @throws SAXException
+     * @throws IOException
+     */
+    void parse(File project, boolean top) throws ParserConfigurationException,
+            SAXException, IOException {
+        File file = new File(project, ".classpath");
+        if (!file.exists())
+            throw new FileNotFoundException(".classpath file not found: "
+                    + file.getAbsolutePath());
+
+        Document doc = db.parse(file);
+        NodeList nodelist = doc.getDocumentElement().getElementsByTagName(
+                "classpathentry");
+
+        if (nodelist == null)
+            throw new IllegalArgumentException(
+                    "Can not find classpathentry in classpath file");
+
+        for (int i = 0; i < nodelist.getLength(); i++) {
+            Node node = nodelist.item(i);
+            NamedNodeMap attrs = node.getAttributes();
+            String kind = get(attrs, "kind");
+            if ("src".equals(kind)) {
+                String path = get(attrs, "path");
+                // TODO boolean exported = "true".equalsIgnoreCase(get(attrs,
+                // "exported"));
+                if (path.startsWith("/")) {
+                    // We have another project
+                    File subProject = getFile(workspace, project, path);
+                    if (recurse)
+                        parse(subProject, false);
+                    dependents.add(subProject.getCanonicalFile());
+                } else {
+                    File src = getFile(workspace, project, path);
+                    allSources.add(src);
+                    if (top) {
+                        // We only want the sources for our own project
+                        // or we'll compile all at once. Not a good idea
+                        // because project settings can differ.
+                        sources.add(src);
+                    }
+                }
+            } else if ("lib".equals(kind)) {
+                String path = get(attrs, "path");
+                boolean exported = "true".equalsIgnoreCase(get(attrs,
+                        "exported"));
+                if (top || exported) {
+                    File jar = getFile(workspace, project, path);
+                    if (jar.getName().startsWith("ee."))
+                        bootclasspath.add(jar);
+                    else
+                        classpath.add(jar);
+                    if (exported)
+                        exports.add(jar);
+                }
+            } else if ("output".equals(kind)) {
+                String path = get(attrs, "path");
+                path = path.replace('/', File.separatorChar);
+                output = getFile(workspace, project, path);
+                classpath.add(output);
+                exports.add(output);
+            } else if ("var".equals(kind)) {
+                boolean exported = "true".equalsIgnoreCase(get(attrs,
+                        "exported"));
+                File lib = replaceVar(get(attrs, "path"));
+                File slib = replaceVar(get(attrs, "sourcepath"));
+                if (lib != null) {
+                    classpath.add(lib);
+                    if (exported)
+                        exports.add(lib);
+                }
+                if (slib != null)
+                    sources.add(slib);
+            } else if ("con".equals(kind)) {
+                // Should do something useful ...
+            }
+        }
+    }
+
+    private File getFile(File abs, File relative, String opath) {
+        String path = opath.replace('/', File.separatorChar);
+        File result = new File(path);
+        if (result.isAbsolute() && result.isFile()) {
+            return result;
+        }
+        if (path.startsWith(File.separator)) {
+            result = abs;
+            path = path.substring(1);
+        } else
+            result = relative;
+
+        StringTokenizer st = new StringTokenizer(path, File.separator);
+        while (st.hasMoreTokens()) {
+            String token = st.nextToken();
+            result = new File(result, token);
+        }
+
+        if (!result.exists())
+            System.err.println("File not found: project=" + project
+                    + " workspace=" + workspace + " path=" + opath + " file="
+                    + result);
+        return result;
+    }
+
+    static Pattern PATH = Pattern.compile("([A-Z_]+)/(.*)");
+
+    private File replaceVar(String path) {
+        if ((options & DO_VARIABLES) == 0)
+            return null;
+
+        Matcher m = PATH.matcher(path);
+        if (m.matches()) {
+            String var = m.group(1);
+            String remainder = m.group(2);
+            String base = (String) properties.get(var);
+            if (base != null) {
+                File b = new File(base);
+                File f = new File(b, remainder.replace('/', File.separatorChar));
+                return f;
+            } else
+                reporter.error("Can't find replacement variable for: " + path);
+        } else
+            reporter.error("Cant split variable path: " + path);
+        return null;
+    }
+
+    private String get(NamedNodeMap map, String name) {
+        Node node = map.getNamedItem(name);
+        if (node == null)
+            return null;
+
+        return node.getNodeValue();
+    }
+
+    public Set<File> getClasspath() {
+        return classpath;
+    }
+
+    public Set<File> getSourcepath() {
+        return sources;
+    }
+
+    public File getOutput() {
+        return output;
+    }
+
+    public List<File> getDependents() {
+        return dependents;
+    }
+
+    public void setRecurse(boolean recurse) {
+        this.recurse = recurse;
+    }
+
+    public Set<File> getExports() {
+        return exports;
+    }
+
+    public void setProperties(Map<String, String> map) {
+        this.properties = map;
+    }
+
+    public Set<File> getBootclasspath() {
+        return bootclasspath;
+    }
+
+    public Set<File> getAllSources() {
+        return allSources;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/generics/Create.java b/bundleplugin/src/main/java/aQute/libg/generics/Create.java
new file mode 100644
index 0000000..2843760
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/generics/Create.java
@@ -0,0 +1,40 @@
+package aQute.libg.generics;
+
+import java.util.*;
+
+public class Create {
+    
+    public static <K,V>  Map<K, V> map() {
+        return new LinkedHashMap<K,V>();
+    }
+
+    public static <T>  List<T> list() {
+        return new ArrayList<T>();
+    }
+
+    public static <T>  Set<T> set() {
+        return new HashSet<T>();
+    }
+
+    public static <T>  List<T> list(T[] source) {
+        return new ArrayList<T>(Arrays.asList(source));
+    }
+
+    public static <T>  Set<T> set(T[]source) {
+        return new HashSet<T>(Arrays.asList(source));
+    }
+
+    public static <K,V>  Map<K, V> copy(Map<K,V> source) {
+        return new LinkedHashMap<K,V>(source);
+    }
+
+    public static <T>  List<T> copy(List<T> source) {
+        return new ArrayList<T>(source);
+    }
+
+    public static <T>  Set<T> copy(Set<T> source) {
+        return new HashSet<T>(source);
+    }
+
+    
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/header/OSGiHeader.java b/bundleplugin/src/main/java/aQute/libg/header/OSGiHeader.java
new file mode 100644
index 0000000..5632034
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/header/OSGiHeader.java
@@ -0,0 +1,145 @@
+package aQute.libg.header;
+
+import java.util.*;
+
+import aQute.libg.generics.*;
+import aQute.libg.qtokens.*;
+import aQute.libg.reporter.*;
+
+public class OSGiHeader {
+
+    static public Map<String, Map<String, String>> parseHeader(String value) {
+        return parseHeader(value, null);
+    }
+
+    /**
+     * 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
+     *            A string
+     * @return a Map<String,Map<String,String>>
+     */
+    static public Map<String, Map<String, String>> parseHeader(String value,
+            Reporter logger) {
+        if (value == null || value.trim().length() == 0)
+            return Create.map();
+
+        Map<String, Map<String, String>> result = Create.map();
+        QuotedTokenizer qt = new QuotedTokenizer(value, ";=,");
+        char del = 0;
+        do {
+            boolean hadAttribute = false;
+            Map<String, String> clause = Create.map();
+            List<String> aliases = Create.list();
+            String name = qt.nextToken(",;");
+
+            del = qt.getSeparator();
+            if (name == null || name.length() == 0) {
+                if (logger != null && logger.isPedantic()) {
+                    logger
+                            .warning("Empty clause, usually caused by repeating a comma without any name field or by having spaces after the backslash of a property file: "
+                                    + value);
+                }
+                if (name == null)
+                    break;
+            } else {
+                name = name.trim();
+
+                aliases.add(name);
+                while (del == ';') {
+                    String adname = qt.nextToken();
+                    if ((del = qt.getSeparator()) != '=') {
+                        if (hadAttribute)
+                            if (logger != null) {
+                                logger
+                                        .error("Header contains name field after attribute or directive: "
+                                                + adname
+                                                + " from "
+                                                + value
+                                                + ". Name fields must be consecutive, separated by a ';' like a;b;c;x=3;y=4");
+                            }
+                        if (adname != null && adname.length() > 0)
+                            aliases.add(adname.trim());
+                    } else {
+                        String advalue = qt.nextToken();
+                        if (clause.containsKey(adname)) {
+                            if (logger != null && logger.isPedantic())
+                                logger
+                                        .warning("Duplicate attribute/directive name "
+                                                + adname
+                                                + " in "
+                                                + value
+                                                + ". This attribute/directive will be ignored");
+                        }
+                        if (advalue == null) {
+                            if (logger != null)
+                                logger
+                                        .error("No value after '=' sign for attribute "
+                                                + adname);
+                            advalue = "";
+                        }
+                        clause.put(adname.trim(), advalue.trim());
+                        del = qt.getSeparator();
+                        hadAttribute = true;
+                    }
+                }
+
+                // Check for duplicate names. The aliases list contains
+                // the list of nams, for each check if it exists. If so,
+                // add a number of "~" to make it unique.
+                for (String clauseName : aliases) {
+                    if (result.containsKey(clauseName)) {
+                        if (logger != null && logger.isPedantic())
+                            logger
+                                    .warning("Duplicate name "
+                                            + clauseName
+                                            + " used in header: '"
+                                            + clauseName
+                                            + "'. Duplicate names are specially marked in Bnd with a ~ at the end (which is stripped at printing time).");
+                        while (result.containsKey(clauseName))
+                            clauseName += "~";
+                    }
+                    result.put(clauseName, clause);
+                }
+            }
+        } while (del == ',');
+        return result;
+    }
+
+    public static Map<String, String> parseProperties(String input) {
+        return parseProperties(input, null);
+    }
+
+    public static Map<String, String> parseProperties(String input, Reporter logger) {
+        if (input == null || input.trim().length() == 0)
+            return Create.map();
+
+        Map<String, String> result = Create.map();
+        QuotedTokenizer qt = new QuotedTokenizer(input, "=,");
+        char del = ',';
+
+        while (del == ',') {
+            String key = qt.nextToken(",=");
+            String value = "";
+            del = qt.getSeparator();
+            if (del == '=') {
+                value = qt.nextToken(",=");
+                del = qt.getSeparator();
+            }
+            result.put(key, value);
+        }
+        if (del != 0)
+            if ( logger == null )
+            throw new IllegalArgumentException(
+                    "Invalid syntax for properties: " + input);
+            else
+                logger.error("Invalid syntax for properties: " + input);
+
+        return result;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/qtokens/QuotedTokenizer.java b/bundleplugin/src/main/java/aQute/libg/qtokens/QuotedTokenizer.java
new file mode 100644
index 0000000..43ef7c4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/qtokens/QuotedTokenizer.java
@@ -0,0 +1,118 @@
+package aQute.libg.qtokens;
+
+import java.util.*;
+
+import aQute.libg.generics.*;
+
+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 {
+				    sb.append(c);
+					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<String> getTokenSet() {
+		List<String> list = Create.list();
+		String token = nextToken();
+		while ( token != null ) {
+			list.add(token);
+			token = nextToken();
+		}
+		return list;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/reporter/Reporter.java b/bundleplugin/src/main/java/aQute/libg/reporter/Reporter.java
new file mode 100644
index 0000000..c6179af
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/reporter/Reporter.java
@@ -0,0 +1,15 @@
+package aQute.libg.reporter;
+
+import java.util.*;
+
+
+public interface Reporter {
+	void error(String s, Object ... args);
+	void warning(String s, Object ... args);
+	void progress(String s, Object ... args);
+	void trace(String s, Object ... args);
+	List<String> getWarnings();
+	List<String> getErrors();
+	
+	boolean isPedantic();
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/sed/Replacer.java b/bundleplugin/src/main/java/aQute/libg/sed/Replacer.java
new file mode 100644
index 0000000..fa181f4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sed/Replacer.java
@@ -0,0 +1,5 @@
+package aQute.libg.sed;
+
+public interface Replacer {
+    String process(String line);
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/sed/Sed.java b/bundleplugin/src/main/java/aQute/libg/sed/Sed.java
new file mode 100644
index 0000000..86971bb
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sed/Sed.java
@@ -0,0 +1,82 @@
+package aQute.libg.sed;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+public class Sed {
+    final File                 file;
+    final Replacer             macro;
+    File                       output;
+
+    final Map<Pattern, String> replacements = new LinkedHashMap<Pattern, String>();
+
+    public Sed(Replacer macro, File file) {
+        assert file.isFile();
+        this.file = file;
+        this.macro = macro;
+    }
+
+    public void setOutput(File f) {
+        output = f;
+    }
+
+    public void replace(String pattern, String replacement) {
+        replacements.put(Pattern.compile(pattern), replacement);
+    }
+
+    public void doIt() throws IOException {
+        BufferedReader brdr = new BufferedReader(new FileReader(file));
+        File out;
+        if (output != null)
+            out = output;
+        else
+            out = new File(file.getAbsolutePath() + ".tmp");
+        File bak = new File(file.getAbsolutePath() + ".bak");
+        PrintWriter pw = new PrintWriter(new FileWriter(out));
+        try {
+            String line;
+            while ((line = brdr.readLine()) != null) {
+                for (Pattern p : replacements.keySet()) {
+                    String replace = replacements.get(p);
+                    Matcher m = p.matcher(line);
+
+                    StringBuffer sb = new StringBuffer();
+                    while (m.find()) {
+                        String tmp = setReferences(m, replace);
+                        tmp = macro.process(tmp);
+                        m.appendReplacement(sb, Matcher.quoteReplacement(tmp));
+                    }
+                    m.appendTail(sb);
+
+                    line = sb.toString();
+                }
+                pw.println(line);
+            }
+            pw.close();
+            if (output == null) {
+                file.renameTo(bak);
+                out.renameTo(file);
+            }
+        } finally {
+            brdr.close();
+            pw.close();
+        }
+    }
+
+    private String setReferences(Matcher m, String replace) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < replace.length(); i++) {
+            char c = replace.charAt(i);
+            if (c == '$' && i < replace.length() - 1
+                    && Character.isDigit(replace.charAt(i + 1))) {
+                int n = replace.charAt(i + 1) - '0';
+                if ( n <= m.groupCount() )
+                    sb.append(m.group(n));
+                i++;
+            } else
+                sb.append(c);
+        }
+        return sb.toString();
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/version/Version.java b/bundleplugin/src/main/java/aQute/libg/version/Version.java
new file mode 100644
index 0000000..4f087a0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/version/Version.java
@@ -0,0 +1,148 @@
+package aQute.libg.version;
+
+import java.util.regex.*;
+
+public class Version implements Comparable<Version> {
+    final int                   major;
+    final int                   minor;
+    final int                   micro;
+    final String                qualifier;
+    public final static String  VERSION_STRING = "(\\d+)(\\.(\\d+)(\\.(\\d+)(\\.([-_\\da-zA-Z]+))?)?)?";
+    public final static Pattern VERSION        = Pattern
+                                                       .compile(VERSION_STRING);
+    public final static Version LOWEST         = new Version();
+    public final static Version HIGHEST        = new Version(Integer.MAX_VALUE,
+                                                       Integer.MAX_VALUE,
+                                                       Integer.MAX_VALUE,
+                                                       "\uFFFF");
+
+    public Version() {
+        this(0);
+    }
+
+    public Version(int major, int minor, int micro, String qualifier) {
+        this.major = major;
+        this.minor = minor;
+        this.micro = micro;
+        this.qualifier = qualifier;
+    }
+
+    public Version(int major, int minor, int micro) {
+        this(major, minor, micro, null);
+    }
+
+    public Version(int major, int minor) {
+        this(major, minor, 0, null);
+    }
+
+    public Version(int major) {
+        this(major, 0, 0, null);
+    }
+
+    public Version(String version) {
+        Matcher m = VERSION.matcher(version);
+        if (!m.matches())
+            throw new IllegalArgumentException("Invalid syntax for version: "
+                    + version);
+
+        major = Integer.parseInt(m.group(1));
+        if (m.group(3) != null)
+            minor = Integer.parseInt(m.group(3));
+        else
+            minor = 0;
+
+        if (m.group(5) != null)
+            micro = Integer.parseInt(m.group(5));
+        else
+            micro = 0;
+
+        qualifier = m.group(7);
+    }
+
+    public int getMajor() {
+        return major;
+    }
+
+    public int getMinor() {
+        return minor;
+    }
+
+    public int getMicro() {
+        return micro;
+    }
+
+    public String getQualifier() {
+        return qualifier;
+    }
+
+    public int compareTo(Version other) {
+        if (other == this)
+            return 0;
+
+        if (!(other instanceof Version))
+            throw new IllegalArgumentException(
+                    "Can only compare versions to versions");
+
+        Version o = (Version) other;
+        if (major != o.major)
+            return major - o.major;
+
+        if (minor != o.minor)
+            return minor - o.minor;
+
+        if (micro != o.micro)
+            return micro - o.micro;
+
+        int c = 0;
+        if (qualifier != null)
+            c = 1;
+        if (o.qualifier != null)
+            c += 2;
+
+        switch (c) {
+        case 0:
+            return 0;
+        case 1:
+            return 1;
+        case 2:
+            return -1;
+        }
+        return qualifier.compareTo(o.qualifier);
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(major);
+        sb.append(".");
+        sb.append(minor);
+        sb.append(".");
+        sb.append(micro);
+        if (qualifier != null) {
+            sb.append(".");
+            sb.append(qualifier);
+        }
+        return sb.toString();
+    }
+
+    public boolean equals(Object ot) {
+        if ( ! (ot instanceof Version))
+            return false;
+        
+        return compareTo((Version)ot) == 0;
+    }
+
+    public int hashCode() {
+        return major * 97 ^ minor * 13 ^ micro
+                + (qualifier == null ? 97 : qualifier.hashCode());
+    }
+
+    public int get(int i) {
+        switch(i) {
+        case 0 : return major;
+        case 1 : return minor;
+        case 2 : return micro;
+        default:
+            throw new IllegalArgumentException("Version can only get 0 (major), 1 (minor), or 2 (micro)");
+        }
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/version/VersionRange.java b/bundleplugin/src/main/java/aQute/libg/version/VersionRange.java
new file mode 100644
index 0000000..47e7447
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/version/VersionRange.java
@@ -0,0 +1,85 @@
+package aQute.libg.version;
+
+import java.util.regex.*;
+
+public class VersionRange {
+	Version			high;
+	Version			low;
+	char			start	= '[';
+	char			end		= ']';
+
+	static Pattern	RANGE	= Pattern.compile("(\\(|\\[)\\s*(" +
+									Version.VERSION_STRING + ")\\s*,\\s*(" +
+									Version.VERSION_STRING + ")\\s*(\\)|\\])");
+
+	public VersionRange(String string) {
+		string = string.trim();
+		Matcher m = RANGE.matcher(string);
+		if (m.matches()) {
+			start = m.group(1).charAt(0);
+			String v1 = m.group(2);
+			String v2 = m.group(10);
+			low = new Version(v1);
+			high = new Version(v2);
+			end = m.group(18).charAt(0);
+			if (low.compareTo(high) > 0)
+				throw new IllegalArgumentException(
+						"Low Range is higher than High Range: " + low + "-" +
+								high);
+
+		} else
+			high = low = new Version(string);
+	}
+
+	public boolean isRange() {
+		return high != low;
+	}
+
+	public boolean includeLow() {
+		return start == '[';
+	}
+
+	public boolean includeHigh() {
+		return end == ']';
+	}
+
+	public String toString() {
+		if (high == low)
+			return high.toString();
+
+		StringBuffer sb = new StringBuffer();
+		sb.append(start);
+		sb.append(low);
+		sb.append(',');
+		sb.append(high);
+		sb.append(end);
+		return sb.toString();
+	}
+
+	public Version getLow() {
+		return low;
+	}
+
+	public Version getHigh() {
+		return high;
+	}
+
+	public boolean includes(Version v) {
+		if ( !isRange() ) {
+			return low.compareTo(v) <=0;
+		}
+		if (includeLow()) {
+			if (v.compareTo(low) < 0)
+				return false;
+		} else if (v.compareTo(low) <= 0)
+			return false;
+
+		if (includeHigh()) {
+			if (v.compareTo(high) > 0)
+				return false;
+		} else if (v.compareTo(high) >= 0)
+			return false;
+		
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/scripting/Scripter.java b/bundleplugin/src/main/java/aQute/scripting/Scripter.java
new file mode 100644
index 0000000..5d6a6cd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/scripting/Scripter.java
@@ -0,0 +1,12 @@
+package aQute.service.scripting;
+
+import java.io.Reader;
+import java.util.Map;
+
+public abstract interface Scripter
+{
+  public static final String MIME_TYPE = "mime.type";
+
+  public abstract Object eval(Map<String, Object> paramMap, Reader paramReader)
+    throws Exception;
+}
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundleAllPlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundleAllPlugin.java
index ab36570..28391af 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundleAllPlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundleAllPlugin.java
@@ -24,9 +24,9 @@
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -338,7 +338,7 @@
 
         try
         {
-            Map instructions = new HashMap();
+            Map instructions = new LinkedHashMap();
             instructions.put( Analyzer.IMPORT_PACKAGE, wrapImportPackage );
 
             project.getArtifact().setFile( getFile( artifact ) );
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
index 7d1837e..f24039b 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
@@ -30,9 +30,9 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -167,7 +167,7 @@
      *
      * @parameter
      */
-    private Map instructions = new HashMap();
+    private Map instructions = new LinkedHashMap();
 
     /**
      * Use locally patched version for now.
@@ -245,7 +245,7 @@
     /* transform directives from their XML form to the expected BND syntax (eg. _include becomes -include) */
     protected static Map transformDirectives( Map originalInstructions )
     {
-        Map transformedInstructions = new HashMap();
+        Map transformedInstructions = new LinkedHashMap();
         for ( Iterator i = originalInstructions.entrySet().iterator(); i.hasNext(); )
         {
             Map.Entry e = ( Map.Entry ) i.next();
@@ -638,7 +638,7 @@
 
     private static Map getProperties( Model projectModel, String prefix )
     {
-        Map properties = new HashMap();
+        Map properties = new LinkedHashMap();
         Method methods[] = Model.class.getDeclaredMethods();
         for ( int i = 0; i < methods.length; i++ )
         {
@@ -759,7 +759,7 @@
             return Collections.EMPTY_LIST;
         }
 
-        Collection selectedDependencies = new HashSet( artifacts );
+        Collection selectedDependencies = new LinkedHashSet( artifacts );
         DependencyExcluder excluder = new DependencyExcluder( artifacts );
         excluder.processHeaders( excludeDependencies );
         selectedDependencies.removeAll( excluder.getExcludedArtifacts() );
@@ -905,7 +905,7 @@
 
     private static void addLocalPackages( String sourceDirectory, Analyzer analyzer )
     {
-        Collection packages = new HashSet();
+        Collection packages = new LinkedHashSet();
 
         if ( sourceDirectory != null && new File( sourceDirectory ).isDirectory() )
         {
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/DependencyEmbedder.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/DependencyEmbedder.java
index 3ae83d0..38aca66 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/DependencyEmbedder.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/DependencyEmbedder.java
@@ -21,8 +21,8 @@
 
 import java.io.File;
 import java.util.Collection;
-import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.Map;
 
 import org.apache.maven.artifact.Artifact;
@@ -67,8 +67,8 @@
     {
         super( dependencyArtifacts );
 
-        m_inlinedPaths = new HashSet();
-        m_embeddedArtifacts = new HashSet();
+        m_inlinedPaths = new LinkedHashSet();
+        m_embeddedArtifacts = new LinkedHashSet();
     }
 
 
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/ManifestPlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/ManifestPlugin.java
index b27d850..b078b53 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/ManifestPlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/ManifestPlugin.java
@@ -24,8 +24,8 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -145,7 +145,7 @@
 
     protected Analyzer getAnalyzer( MavenProject project, Jar[] classpath ) throws IOException, MojoExecutionException
     {
-        return getAnalyzer( project, new HashMap(), new Properties(), classpath );
+        return getAnalyzer( project, new LinkedHashMap(), new Properties(), classpath );
     }
 
 
