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..c348cec
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Analyzer.java
@@ -0,0 +1,1877 @@
+/* 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());
+
+            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);
+
+            // 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);
+
+        Map<String, Map<String, String>> l = doServiceComponent(getProperty(SERVICE_COMPONENT));
+        if (!l.isEmpty())
+            main.putValue(SERVICE_COMPONENT, printClauses(l, ""));
+        else
+            main.remove(SERVICE_COMPONENT);
+
+        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 (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
+                        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>
+     * @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();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * 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);
+        if (!sc.isEmpty()) {
+            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 (dot.exists(name)) {
+                    // Normal service component
+                    list.put(name, info);
+                } else {
+                    String impl = name;
+                    if (info.containsKey(COMPONENT_IMPLEMENTATION))
+                        impl = info.get(COMPONENT_IMPLEMENTATION);
+
+                    if (!checkClass(impl))
+                        error("Not found Service-Component header: " + name);
+                    else {
+                        // We have a definition, so make an XML resources
+                        Resource resource = createComponentResource(name, info);
+                        dot.putResource("OSGI-INF/" + name + ".xml", resource);
+                        Map<String, String> empty = Collections.emptyMap();
+                        list.put("OSGI-INF/" + name + ".xml", empty);
+                    }
+                }
+            }
+        }
+        return list;
+    }
+
+    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 = getClass().getResourceAsStream("bnd.info");
+                if (in != null) {
+                    bndInfo.load(in);
+                    in.close();
+                }
+            } catch (IOException ioe) {
+                warning("Could not read bnd.info in " + getClass().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 Signer getSigner() {
+    // String sign = getProperty("-sign");
+    // if (sign == null) return null;
+    //
+    // Map parsed = parseHeader(sign);
+    // Signer signer = new Signer();
+    // String password = (String) parsed.get("password");
+    // if (password != null) {
+    // signer.setPassword(password);
+    // }
+    //
+    // String keystore = (String) parsed.get("keystore");
+    // if (keystore != null) {
+    // File f = new File(keystore);
+    // if (!f.isAbsolute()) f = new File(base, keystore);
+    // signer.setKeystore(f);
+    // } else {
+    // error("Signing requires a keystore");
+    // return null;
+    // }
+    //
+    // String alias = (String) parsed.get("alias");
+    // if (alias != null) {
+    // signer.setAlias(alias);
+    // } else {
+    // error("Signing requires an alias for the key");
+    // return null;
+    // }
+    // return signer;
+    // }
+
+    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
+     */
+    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);
+    }
+
+    /**
+     * 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 {
+
+        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 + "'");
+
+        String factory = info.get(COMPONENT_FACTORY);
+        if (factory != null)
+            pw.print(" factory='" + factory + "'");
+
+        String immediate = info.get(COMPONENT_IMMEDIATE);
+        if (immediate != null)
+            pw.print(" immediate='" + immediate + "'");
+
+        String enabled = info.get(COMPONENT_ENABLED);
+        if (enabled != null)
+            pw.print(" enabled='" + enabled + "'");
+
+        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);
+    }
+
+    /**
+     * 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());
+                }
+            }
+        }
+    }
+
+    /**
+     * 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 (!checkClass(interfaceName))
+                    error("Component definition provides a class that is neither imported nor contained: "
+                            + interfaceName);
+            }
+            pw.println("  </service>");
+        }
+    }
+
+    final static Pattern REFERENCE = Pattern.compile("([^(]+)(\\(.+\\))?");
+
+    /**
+     * @param info
+     * @param pw
+     */
+
+    void reference(Map<String, String> info, PrintWriter pw) {
+        Collection<String> dynamic = split(info.get(COMPONENT_DYNAMIC));
+        Collection<String> optional = split(info.get(COMPONENT_OPTIONAL));
+        Collection<String> multiple = 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);
+            }
+
+            // TODO check if the interface is contained or imported
+
+            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 (!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 + "'");
+                // TODO Verify that the methods exist
+
+                // TODO ProSyst requires both a bind and unbind :-(
+                // if ( dynamic.contains(referenceName) )
+                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("/>");
+        }
+    }
+
+    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")) {
+                    parameters = newMap(parameters);
+                    parameters.remove("version");
+                }
+                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 (!(pack.equals(".") || 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..bdc2c7a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
@@ -0,0 +1,1128 @@
+/* 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.security.*;
+import java.security.cert.*;
+import java.security.spec.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+import java.util.zip.*;
+
+import aQute.bnd.make.*;
+import aQute.lib.signing.*;
+
+/**
+ * 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.4 $
+ */
+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;
+
+    List<File>               sourcePath        = new ArrayList<File>();
+    Pattern                  NAME_URL          = Pattern
+                                                       .compile("(.*)(http://.*)");
+
+    Make                     make              = new Make(this);
+    private KeyStore         keystore;
+
+    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);
+            }
+        }
+
+        dot.setManifest(manifest);
+
+        // 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);
+
+        Map<String, Map<String, String>> infos = parseHeader(signing);
+        for (Map.Entry<String, Map<String, String>> entry : infos.entrySet()) {
+            String alias = entry.getKey();
+            String keystoreLocation = entry.getValue().get(
+                    KEYSTORE_LOCATION_DIRECTIVE);
+            String keystoreProvider = entry.getValue().get(
+                    KEYSTORE_PROVIDER_DIRECTIVE);
+            String password = entry.getValue().get(KEYSTORE_PASSWORD_DIRECTIVE);
+            String signpassword = entry.getValue().get(SIGN_PASSWORD_DIRECTIVE);
+            KeyStore keystore = getKeystore(keystoreLocation, keystoreProvider,
+                    password);
+            if (keystore == null) {
+                error(
+                        "Cannot find keystore to sign bundle: location=%s,  provider=%s",
+                        keystoreLocation, keystoreProvider);
+            } else {
+                if (signpassword == null && !"-none".equals(signpassword))
+                    signpassword = password;
+
+                X509Certificate chain[] = getChain(keystore, alias);
+                if (chain == null) {
+                    error(
+                            "Trying to sign bundle but no signing certificate found: %s",
+                            alias);
+                    continue;
+                }
+
+                try {
+                    Key key = keystore.getKey(alias,
+                            (signpassword == null ? null : signpassword
+                                    .toCharArray()));
+                    KeyFactory keyFactory = KeyFactory.getInstance(key
+                            .getAlgorithm());
+                    KeySpec keySpec = keyFactory.getKeySpec(key,
+                            RSAPrivateKeySpec.class);
+                    PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
+
+                    JarSigner signer = new JarSigner(alias, privateKey, chain);
+                    signer.signJar(jar);
+
+                } catch (UnrecoverableKeyException uke) {
+                    error(
+                            "Cannot get key to sign, likely invalid password: %s, for %s : %s",
+                            signpassword, alias, uke);
+                }
+            }
+        }
+    }
+
+    X509Certificate[] getChain(KeyStore keystore, String alias)
+            throws Exception {
+        java.security.cert.Certificate[] chain = keystore
+                .getCertificateChain(alias);
+        X509Certificate certChain[] = new X509Certificate[chain.length];
+
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        for (int count = 0; count < chain.length; count++) {
+            ByteArrayInputStream certIn = new ByteArrayInputStream(chain[count]
+                    .getEncoded());
+            X509Certificate cert = (X509Certificate) cf
+                    .generateCertificate(certIn);
+            certChain[count] = cert;
+        }
+        return certChain;
+    }
+
+    KeyStore getKeystore(String keystoreLocation, String keystoreProvider,
+            String password) throws Exception {
+        if (keystoreLocation == null) {
+            return getKeystore();
+        }
+        if (keystoreProvider == null)
+            keystoreProvider = "JKS";
+
+        KeyStore keystore = KeyStore.getInstance(keystoreProvider);
+        FileInputStream in = new FileInputStream(keystoreLocation);
+        try {
+            keystore.load(in, password == null ? null : password.toCharArray());
+        } finally {
+            in.close();
+        }
+        return keystore;
+    }
+
+    KeyStore getKeystore() throws Exception {
+        if (keystore != null) {
+            return keystore;
+        }
+
+        Map<String, Map<String, String>> header = parseHeader(getProperty(
+                "-keystore", "../cnf/keystore"));
+        if (header.size() == 0) {
+            error("Keystore needed but no -keystore specified");
+            return null;
+        }
+
+        if (header.size() > 1) {
+            warning("Multiple keystores specified, can only specify one: %s",
+                    header);
+        }
+        for (Map.Entry<String, Map<String, String>> entry : header.entrySet()) {
+            return keystore = getKeystore(entry.getKey(), entry.getValue().get(
+                    "provider:"), entry.getValue().get("password:"));
+        }
+        return null;
+    }
+
+    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>());
+
+            // 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:");
+                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>> all = newMap();
+
+        all.putAll(replaceWitInstruction(getHeader(EXPORT_PACKAGE),
+                EXPORT_PACKAGE));
+
+        all.putAll(replaceWitInstruction(getHeader(PRIVATE_PACKAGE),
+                PRIVATE_PACKAGE));
+
+        if (isTrue(getProperty(Constants.UNDERTEST))) {
+            all.putAll(replaceWitInstruction(parseHeader(getProperty(
+                    Constants.TESTPACKAGES, "test;presence:=optional")),
+                    TESTPACKAGES));
+        }
+
+        if (all.isEmpty() && !isResourceOnly()) {
+            warning("Neither Export-Package, Private-Package, -testpackages is set, therefore no packages will be included");
+        }
+
+        doExpand(jar, "Export-Package, Private-Package, or -testpackages", all,
+                true);
+    }
+
+    /**
+     * 
+     * @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-INF/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("Include-Resource");
+        else
+            warning("Please use Include-Resource 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];
+            }
+
+            // 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);
+
+            if (!sourceFile.exists()) {
+                noSuchFile(jar, name, extra, source, destinationPath);
+            } else
+                copy(jar, destinationPath, sourceFile, preprocess, extra);
+        }
+    }
+
+    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) {
+                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);
+                }
+                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()]);
+    }
+
+    protected Builder getSubBuilder() throws Exception {
+        return new Builder(this);
+    }
+
+    /**
+     * 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();
+    }
+
+}
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..f383915
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Clazz.java
@@ -0,0 +1,755 @@
+/* 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;
+
+    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();
+        int super_class = in.readUnsignedShort();
+        zuper = (String) pool[intPool[super_class]];
+        if (zuper != null) {
+            addReference(zuper);
+        }
+        className = (String) pool[intPool[this_class]];
+
+        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()]];
+        }
+        
+        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;
+            }
+
+            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));
+            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().shortValue();
+            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;
+    }
+
+    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) {
+                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];
+        if (attribute_name_index == 560)
+            System.out.println("Index " + attribute_name_index + ":"
+                    + attributeName);
+        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 (attribute_length > 0x7FFFFFFF) {
+                throw new IllegalArgumentException("Attribute > 2Gb");
+            }
+            in.skipBytes((int) attribute_length);
+        }
+    }
+
+    /**
+     * <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>());
+    }
+
+    void parseDescriptor(String prototype) {
+        addReference(prototype);
+        StringTokenizer st = new StringTokenizer(prototype, "(;)", true);
+        while (st.hasMoreTokens()) {
+            if (st.nextToken().equals("(")) {
+                String token = st.nextToken();
+                while (!token.equals(")")) {
+                    addReference(token);
+                    token = st.nextToken();
+                }
+                token = st.nextToken();
+                addReference(token);
+            }
+        }
+    }
+
+    private void addReference(String token) {
+        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('/', '.');
+    }
+}
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..7ec0a94
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Constants.java
@@ -0,0 +1,157 @@
+package aQute.lib.osgi;
+
+import java.util.*;
+import java.util.regex.*;
+
+public interface Constants {
+    public final static String   BUNDLE_CLASSPATH                    = "Bundle-ClassPath";
+    public final static String   BUNDLE_COPYRIGHT                    = "Bundle-Copyright";
+    public final static String   BUNDLE_DESCRIPTION                  = "Bundle-Description";
+    public final static String   BUNDLE_NAME                         = "Bundle-Name";
+    public final static String   BUNDLE_NATIVECODE                   = "Bundle-NativeCode";
+    public final static String   EXPORT_PACKAGE                      = "Export-Package";
+    public final static String   EXPORT_SERVICE                      = "Export-Service";
+    public final static String   IMPORT_PACKAGE                      = "Import-Package";
+    public final static String   DYNAMICIMPORT_PACKAGE               = "DynamicImport-Package";
+    public final static String   IMPORT_SERVICE                      = "Import-Service";
+    public final static String   BUNDLE_VENDOR                       = "Bundle-Vendor";
+    public final static String   BUNDLE_VERSION                      = "Bundle-Version";
+    public final static String   BUNDLE_DOCURL                       = "Bundle-DocURL";
+    public final static String   BUNDLE_CONTACTADDRESS               = "Bundle-ContactAddress";
+    public final static String   BUNDLE_ACTIVATOR                    = "Bundle-Activator";
+    public final static String   BUNDLE_REQUIREDEXECUTIONENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
+    public final static String   BUNDLE_SYMBOLICNAME                 = "Bundle-SymbolicName";
+    public final static String   BUNDLE_LOCALIZATION                 = "Bundle-Localization";
+    public final static String   REQUIRE_BUNDLE                      = "Require-Bundle";
+    public final static String   FRAGMENT_HOST                       = "Fragment-Host";
+    public final static String   BUNDLE_MANIFESTVERSION              = "Bundle-ManifestVersion";
+    public final static String   SERVICE_COMPONENT                   = "Service-Component";
+    public final static String   BUNDLE_LICENSE                      = "Bundle-License";
+    public static final String   PRIVATE_PACKAGE                     = "Private-Package";
+    public static final String   IGNORE_PACKAGE                      = "Ignore-Package";
+    public static final String   INCLUDE_RESOURCE                    = "Include-Resource";
+    public static final String   CONDITIONAL_PACKAGE                 = "Conditional-Package";
+    public static final String   BND_LASTMODIFIED                    = "Bnd-LastModified";
+    public static final String   CREATED_BY                          = "Created-By";
+    public static final String   TOOL                                = "Tool";
+
+    public final static 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                   };
+
+    public static final String   BUILDPATH                           = "-buildpath";
+    public static final String   CONDUIT                             = "-conduit";
+    public static final String   CLASSPATH                           = "-classpath";
+    public static final String   DEPENDSON                           = "-dependson";
+    public static final String   DONOTCOPY                           = "-donotcopy";
+    public static final String   EXPORT_CONTENTS                     = "-exportcontents";
+    public static final String   FAIL_OK                             = "-failok";
+    public static final String   INCLUDE                             = "-include";
+    public static final String   MAKE                                = "-make";
+    public static final String   MANIFEST                            = "-manifest";
+    public static final String   NOEXTRAHEADERS                      = "-noextraheaders";
+    public static final String   NOUSES                              = "-nouses";
+    public static final String   NOPE                                = "-nope";
+    public static final String   PEDANTIC                            = "-pedantic";
+    public static final String   PLUGIN                              = "-plugin";
+    public static final String   POM                                 = "-pom";
+    public static final String   REMOVE_HEADERS                      = "-removeheaders";
+    public static final String   RESOURCEONLY                        = "-resourceonly";
+    public static final String   SOURCES                             = "-sources";
+    public static final String   SOURCEPATH                          = "-sourcepath";
+    public static final String   SUB                                 = "-sub";
+    public static final String   RUNPROPERTIES                       = "-runproperties";
+    public static final String   RUNSYSTEMPACKAGES                   = "-runsystempackages";
+    public static final String   RUNBUNDLES                          = "-runbundles";
+    public static final String   RUNPATH                             = "-runpath";
+    public static final String   RUNVM                               = "-runvm";
+
+    public static final String   REPORTNEWER                         = "-reportnewer";
+    public static final String   TESTPACKAGES                        = "-testpackages";
+    public static final String   TESTREPORT                          = "-testreport";
+    public static final String   UNDERTEST                           = "-undertest";
+    public static final String   VERBOSE                             = "-verbose";
+    public static final String   VERSIONPOLICY                       = "-versionpolicy";
+    public static final String   SIGN                                = "-sign";
+
+    public static final String   options[]                           = {
+            BUILDPATH, CONDUIT, CLASSPATH, DEPENDSON, DONOTCOPY,
+            EXPORT_CONTENTS, FAIL_OK, INCLUDE, MAKE, MANIFEST, NOEXTRAHEADERS,
+            NOUSES, NOPE, PEDANTIC, PLUGIN, POM, REMOVE_HEADERS, RESOURCEONLY,
+            SOURCES, SOURCEPATH, SOURCES, SOURCEPATH, SUB, RUNBUNDLES, RUNPATH,
+            RUNSYSTEMPACKAGES, RUNPROPERTIES, REPORTNEWER, UNDERTEST,
+            TESTPACKAGES, TESTREPORT, VERBOSE                       };
+
+    public static final char     DUPLICATE_MARKER                    = '~';
+
+    public static final String   SPLIT_PACKAGE_DIRECTIVE             = "-split-package:";
+    public static final String   IMPORT_DIRECTIVE                    = "-import:";
+    public static final String   NO_IMPORT_DIRECTIVE                 = "-noimport:";
+    public static final String   REMOVE_ATTRIBUTE_DIRECTIVE          = "-remove-attribute:";
+    public static final String   USES_DIRECTIVE                      = "uses:";
+    public static final String   PRESENCE_DIRECTIVE                  = "presence:";
+
+    public static final String   KEYSTORE_LOCATION_DIRECTIVE         = "keystore:";
+    public static final String   KEYSTORE_PROVIDER_DIRECTIVE         = "provider:";
+    public static final String   KEYSTORE_PASSWORD_DIRECTIVE         = "password:";
+    public static final String   SIGN_PASSWORD_DIRECTIVE             = "sign-password:";
+
+    public static final String   directives[]                        = {
+            SPLIT_PACKAGE_DIRECTIVE, NO_IMPORT_DIRECTIVE, IMPORT_DIRECTIVE,
+            "resolution:", "include:", "uses:", "exclude:", USES_DIRECTIVE,
+            KEYSTORE_LOCATION_DIRECTIVE, KEYSTORE_PROVIDER_DIRECTIVE,
+            KEYSTORE_PASSWORD_DIRECTIVE, SIGN_PASSWORD_DIRECTIVE,
+
+                                                                     // TODO
+                                                                     };
+
+    public static final String   USES_USES                           = "<<USES>>";
+    public static final String   CURRENT_USES                        = "@uses";
+    public static final String   IMPORT_REFERENCE                    = "reference";
+    public static final String   IMPORT_PRIVATE                      = "private";
+    public static final String[] importDirectives                    = {
+            IMPORT_REFERENCE, IMPORT_PRIVATE                        };
+
+    public static final String   COMPONENT_FACTORY                   = "factory:";
+    public static final String   COMPONENT_SERVICEFACTORY            = "servicefactory:";
+    public static final String   COMPONENT_IMMEDIATE                 = "immediate:";
+    public static final String   COMPONENT_ENABLED                   = "enabled:";
+    public static final String   COMPONENT_DYNAMIC                   = "dynamic:";
+    public static final String   COMPONENT_MULTIPLE                  = "multiple:";
+    public static final String   COMPONENT_PROVIDE                   = "provide:";
+    public static final String   COMPONENT_OPTIONAL                  = "optional:";
+    public static final String   COMPONENT_PROPERTIES                = "properties:";
+    public static final String   COMPONENT_IMPLEMENTATION            = "implementation:";
+    public static final String[] componentDirectives                 = new String[] {
+            COMPONENT_FACTORY, COMPONENT_IMMEDIATE, COMPONENT_ENABLED,
+            COMPONENT_DYNAMIC, COMPONENT_MULTIPLE, COMPONENT_PROVIDE,
+            COMPONENT_OPTIONAL, COMPONENT_PROPERTIES, COMPONENT_IMPLEMENTATION, COMPONENT_SERVICEFACTORY };
+
+    // static Map EES = new HashMap();
+    static Set<String>           SET_COMPONENT_DIRECTIVES            = new HashSet<String>(
+                                                                             Arrays
+                                                                                     .asList(componentDirectives));
+
+    static final Pattern         VALID_PROPERTY_TYPES                = Pattern
+                                                                             .compile("(String|Long|Double|Float|Integer|Byte|Character|Boolean|Short)");
+
+    public final static String   DEFAULT_BND_EXTENSION               = ".bnd";
+    public final static String   DEFAULT_JAR_EXTENSION               = ".jar";
+    public final static String   DEFAULT_BAR_EXTENSION               = ".bar";
+    String[]                     METAPACKAGES                        = {
+            "META-INF", "OSGI-INF", "OSGI-OPT"                      };
+
+    int                          STRATEGY_HIGHEST                    = 1;
+    int                          STRATEGY_LOWEST                     = -1;
+
+    final static String          CURRENT_VERSION                     = "@";
+    final static 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..b78cc57
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java
@@ -0,0 +1,113 @@
+/*
+ * $Header: /cvs/xierpa/aQute.util.jar/src/aQute/lib/osgi/Instruction.java,v 1.1 2007-01-03 19:54:32 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/Jar.java b/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
new file mode 100644
index 0000000..fe34cc5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
@@ -0,0 +1,408 @@
+/* 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;
+
+    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 {
+        JarOutputStream jout = new JarOutputStream(out);
+        Set<String> done = new HashSet<String>();
+
+        Set<String> directories = new HashSet<String>();
+        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, JarOutputStream jout)
+            throws IOException {
+        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(JarOutputStream 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, JarOutputStream 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;
+    }
+}
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..6510f63
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Macro.java
@@ -0,0 +1,821 @@
+/* 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.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 {
+    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;
+    }
+
+    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;
+    }
+
+    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 {
+                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>}, convert a list of class names to paths";
+
+    public String _toclasspath(String args[]) {
+        verifyCommand(args, _toclasspathHelp, null, 2, 2);
+
+        Collection<String> names = Processor.split(args[1]);
+        Collection<String> paths = new ArrayList<String>(names.size());
+        for (String name : names) {
+            String path = name.replace('.', '/') + ".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 {
+                    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("_"))
+                    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..f33e722
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java
@@ -0,0 +1,993 @@
+/* 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;
+    
+    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 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
+     */
+    public List<Object> getPlugins() {
+        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());
+
+        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:");
+                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()));
+
+        changed |= modified < propertiesFile.lastModified();
+        if (changed) {
+            included = null;
+            properties.clear();
+            setProperties(propertiesFile, base);
+            propertiesChanged();
+            return true;
+        }
+        return false;
+    }
+
+    public void propertiesChanged() {
+        plugins = null;
+    }
+
+    /**
+     * 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);
+                modified = propertiesFile.lastModified();
+                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 = 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 = newMap();
+        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 {
+                        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(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.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;
+    }
+}
+
+
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..8964432
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Verifier.java
@@ -0,0 +1,671 @@
+/* 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"
+                                                                           + "|JRE-1\\.1"
+                                                                           + "|J2SE-1\\.2"
+                                                                           + "|J2SE-1\\.3"
+                                                                           + "|J2SE-1\\.4"
+                                                                           + "|J2SE-1\\.5"
+                                                                           + "|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("=|<=|>=|~=");
+    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}|_)+)*(\\.\\*)?)|\\*");
+    final static Pattern             ISO639                = Pattern
+                                                                   .compile("[A-Z][A-Z]");
+    public static Pattern            HEADER_PATTERN        = Pattern
+                                                                   .compile("[A-Za-z0-9][-a-zA-Z0-9_]+");
+    public static Pattern            TOKEN                 = Pattern
+                                                                   .compile("[-a-zA-Z0-9_]+");
+
+    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);
+                            EmbeddedResource.build(sub, resource);
+                            
+                            // TODO verify if directory exists and see how to 
+                            // get it in a JAR ...
+                            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 (!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();
+        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");
+            }
+        }
+    }
+
+    /**
+     * <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();
+    }
+
+}
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..38b744f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/ZipResource.java
@@ -0,0 +1,78 @@
+/* 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;
+	}
+
+	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;
+	}
+
+}
