diff --git a/bundleplugin/pom.xml b/bundleplugin/pom.xml
index 6318a90..0ec377e 100644
--- a/bundleplugin/pom.xml
+++ b/bundleplugin/pom.xml
@@ -38,6 +38,19 @@
   resources and dependencies. Plus a zillion other features.
   The plugin uses the Bnd tool (http://www.aqute.biz/Code/Bnd)
  </description>
+
+ <build>
+  <plugins>
+   <plugin>
+    <groupId>org.apache.maven.plugins</groupId>
+    <artifactId>maven-compiler-plugin</artifactId>
+    <configuration>
+     <source>1.5</source>
+     <target>1.5</target>
+    </configuration>
+   </plugin>
+  </plugins>
+ </build>
  
  <dependencies>
   <dependency>
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;
+	}
+
+}
