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;
+}
