diff --git a/bundleplugin/pom.xml b/bundleplugin/pom.xml
index e29db52..6318a90 100644
--- a/bundleplugin/pom.xml
+++ b/bundleplugin/pom.xml
@@ -43,7 +43,7 @@
   <dependency>
    <groupId>biz.aQute</groupId>
    <artifactId>bndlib</artifactId>
-   <version>0.0.255</version>
+   <version>0.0.295</version>
   </dependency>
   <dependency>
     <groupId>net.sf.kxml</groupId>
@@ -137,4 +137,18 @@
    <scope>test</scope>
   </dependency>
  </dependencies>
+
+ <repositories>
+  <repository>
+   <id>aQute</id>
+   <url>http://www.aQute.biz/repo</url>
+   <releases>
+    <updatePolicy>never</updatePolicy>
+   </releases>
+   <snapshots>
+    <enabled>false</enabled>
+   </snapshots>
+  </repository>
+ </repositories>
+
 </project>
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java b/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
deleted file mode 100644
index 80afa3e..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
+++ /dev/null
@@ -1,776 +0,0 @@
-/* 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.*;
-
-/**
- * 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                     tempJars          = new ArrayList();
-    boolean                  sources           = false;
-    File[]                   sourcePath;
-    Pattern                  NAME_URL          = Pattern
-                                                       .compile("(.*)(http://.*)");
-
-    public Jar build() throws Exception {
-        begin();
-
-        dot = new Jar("dot");
-        doPrebuild(dot, parseHeader(getProperty("-prebuild")));
-        doExpand(dot);
-        doIncludeResources(dot);
-
-        doConditional(dot);
-
-        dot.setManifest(calcManifest());
-        // 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());
-        return dot;
-    }
-
-    void begin() {
-        super.begin();
-        if (getProperty(IMPORT_PACKAGE) == null)
-            setProperty(IMPORT_PACKAGE, "*");
-
-        sources = getProperty(SOURCES) != null;
-    }
-
-    private void doConditional(Jar dot) throws IOException {
-        Map conditionals = getHeader(CONDITIONAL_PACKAGE);
-        if (conditionals != null && conditionals.size() > 0) {
-            int size;
-            do {
-                size = dot.getDirectories().size();
-                analyze();
-                analyzed = false;
-                Map imports = getImports();
-
-                Map filtered = merge(CONDITIONAL_PACKAGE, conditionals,
-                        imports, new HashSet());
-
-                // remove existing packages to prevent merge errors
-                filtered.keySet().removeAll(dot.getPackages());
-                filtered = replaceWithPattern(filtered);
-                doExpand(dot, CONDITIONAL_PACKAGE, filtered);
-            } while (dot.getDirectories().size() > size);
-        }
-    }
-
-    /**
-     * 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 mapOfMap) {
-        for (Iterator e = mapOfMap.entrySet().iterator(); e.hasNext();) {
-            Map.Entry entry = (Map.Entry) e.next();
-            Map attributes = (Map) entry.getValue();
-            if (attributes.containsKey("version")) {
-                attributes.put("version", cleanupVersion((String) attributes
-                        .get("version")));
-            }
-        }
-    }
-
-    /**
-     * 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
-     * @return
-     */
-    static Pattern fuzzyVersion  = Pattern
-                                         .compile(
-                                                 "(\\d+)(\\.(\\d+)(\\.(\\d+))?)?([^a-zA-Z0-9](.*))?",
-                                                 Pattern.DOTALL);
-    static Pattern fuzzyModifier = Pattern.compile("(\\d+[.-])*(.*)",
-                                         Pattern.DOTALL);
-
-    static Pattern nummeric      = Pattern.compile("\\d*");
-
-    static public String cleanupVersion(String version) {
-        Matcher m = fuzzyVersion.matcher(version);
-        if (m.matches()) {
-            StringBuffer result = new StringBuffer();
-            String d1 = m.group(1);
-            String d2 = m.group(3);
-            String d3 = m.group(5);
-            String qualifier = m.group(7);
-
-            if (d1 != null) {
-                result.append(d1);
-                if (d2 != null) {
-                    result.append(".");
-                    result.append(d2);
-                    if (d3 != null) {
-                        result.append(".");
-                        result.append(d3);
-                        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);
-        }
-    }
-
-    /**
-     * 
-     */
-    private void addSources(Jar dot) {
-        if (!sources)
-            return;
-
-        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 cpe = classspace.keySet().iterator(); cpe.hasNext();) {
-            String path = (String) cpe.next();
-            path = path.substring(0, path.length() - ".class".length())
-                    + ".java";
-
-            for (int i = 0; i < sourcePath.length; i++) {
-                File root = sourcePath[i];
-                File f = getFile(root, path);
-                if (f.exists()) {
-                    dot
-                            .putResource("OSGI-OPT/src/" + path,
-                                    new FileResource(f));
-                }
-            }
-        }
-    }
-
-    private void doVerify(Jar dot) throws Exception {
-        Verifier verifier = new Verifier(dot, getProperties());
-        verifier.setPedantic(isPedantic());
-        verifier.verify();
-        errors.addAll(verifier.getErrors());
-        warnings.addAll(verifier.getWarnings());
-    }
-
-    private void doExpand(Jar jar) throws IOException {
-        if (classpath.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 prive = replaceWithPattern(getHeader(Analyzer.PRIVATE_PACKAGE));
-        Map export = replaceWithPattern(getHeader(Analyzer.EXPORT_PACKAGE));
-        if (prive.isEmpty() && export.isEmpty()) {
-            warnings
-                    .add("Neither Export-Package nor Private-Package is set, therefore no packages will be included");
-        }
-        doExpand(jar, EXPORT_PACKAGE, export);
-        doExpand(jar, PRIVATE_PACKAGE, prive);
-    }
-
-    private void doExpand(Jar jar, String name, Map instructions) {
-        Set superfluous = new HashSet(instructions.keySet());
-        for (Iterator c = classpath.iterator(); c.hasNext();) {
-            Jar now = (Jar) c.next();
-            doExpand(jar, instructions, now, superfluous);
-        }
-        if (superfluous.size() > 0) {
-            StringBuffer sb = new StringBuffer();
-            String del = "Instructions for " + name + " that are never used: ";
-            for (Iterator i = superfluous.iterator(); i.hasNext();) {
-                Instruction p = (Instruction) 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 included, Jar classpathEntry,
-            Set superfluous) {
-
-        loop: for (Iterator p = classpathEntry.getDirectories().entrySet()
-                .iterator(); p.hasNext();) {
-            Map.Entry directory = (Map.Entry) p.next();
-            String path = (String) 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 contents = (Map) 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 directives = (Map) 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("Split package generates error: " + pack);
-                            continue loop;
-
-                        case SPLIT_FIRST:
-                            continue loop;
-
-                        default:
-                            // Default is like merge-first, but with a warning
-                            warning("There are split packages, use directive -split-package:=(merge-first|merge-last) on instruction to get rid of this warning: "
-                                    + pack
-                                    + ", classpath: "
-                                    + classpath
-                                    + " from: " + classpathEntry.source);
-                            overwriteResource = false;
-                            break;
-                        }
-                    }
-                    jar.addDirectory(contents, overwriteResource);
-                }
-            }
-        }
-    }
-
-    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 replaceWithPattern(Map header) {
-        Map map = new LinkedHashMap();
-        for (Iterator e = header.entrySet().iterator(); e.hasNext();) {
-            Map.Entry entry = (Map.Entry) e.next();
-            String pattern = (String) entry.getKey();
-            Instruction instr = Instruction.getPattern(pattern);
-            map.put(instr, entry.getValue());
-        }
-        return map;
-    }
-
-    private Instruction matches(Map instructions, String pack,
-            Set superfluousPatterns) {
-        for (Iterator i = instructions.keySet().iterator(); i.hasNext();) {
-            Instruction pattern = (Instruction) i.next();
-            if (pattern.matches(pack)) {
-                superfluousPatterns.remove(pattern);
-                return pattern;
-            }
-        }
-        return null;
-    }
-
-    private Map getHeader(String string) {
-        if (string == null)
-            return new LinkedHashMap();
-        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 {
-        Macro macro = new Macro(getProperties(), this);
-
-        String includes = getProperty("Bundle-Includes");
-        if (includes == null)
-            includes = getProperty("Include-Resource");
-        else
-            warnings
-                    .add("Please use Include-Resource instead of Bundle-Includes");
-
-        if (includes == null)
-            return;
-
-        for (Iterator i = getClauses(includes).iterator(); i.hasNext();) {
-            boolean preprocess = false;
-            String clause = (String) i.next();
-            if (clause.startsWith("{") && clause.endsWith("}")) {
-                preprocess = true;
-                clause = clause.substring(1, clause.length() - 1).trim();
-            }
-
-            Map extra = new HashMap();
-            int n = clause.indexOf(';');
-            if (n > 0) {
-                String attributes = clause.substring(n + 1);
-                String parts[] = attributes.split("\\s*;\\s*");
-                for (int j = 0; j < parts.length; j++) {
-                    String assignment[] = parts[j].split("\\s*=\\s*");
-                    if (assignment.length == 2)
-                        extra.put(assignment[0], assignment[1]);
-                    else
-                        error("Invalid attribute on Include-Resource: "
-                                + clause);
-                }
-                clause = clause.substring(0, n);
-            }
-
-            if (clause.startsWith("@")) {
-                extractFromJar(jar, clause.substring(1));
-            } else {
-                String parts[] = clause.split("\\s*=\\s*");
-
-                String source;
-                File sourceFile;
-                String destinationPath;
-
-                if (parts.length == 1) {
-                    // Just a copy, destination path defined by
-                    // source path.
-                    source = parts[0];
-                    sourceFile = getFile(base, 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(base, 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()) {
-                    Jar src = getJarFromName(source, "Include-Resource "
-                            + source);
-                    if (src != null) {
-                        JarResource jarResource = new JarResource(src);
-                        jar.putResource(destinationPath, jarResource);
-                    } else {
-                        error("Input file does not exist: " + source);
-                    }
-                } else
-                    copy(jar, destinationPath, sourceFile, preprocess ? macro
-                            : null, extra);
-            }
-        }
-    }
-
-    /**
-     * 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);
-            tempJars.add(sub);
-        }
-    }
-
-    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, Macro macro, Map 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], macro, extra);
-            }
-        } else {
-            if (from.exists()) {
-                if (macro != null) {
-                    String content = read(from);
-                    content = macro.process(content);
-                    Resource resource = new EmbeddedResource(content
-                            .getBytes("UTF-8"), from.lastModified());
-
-                    String x = (String) extra.get("extra");
-                    if (x != null)
-                        resource.setExtra(x);
-                    jar.putResource(path, resource);
-                } else
-                    jar.putResource(path, new FileResource(from));
-            } else {
-                error("Input file does not exist: " + from);
-            }
-        }
-    }
-
-    private String read(File from) throws Exception {
-        long size = from.length();
-        byte[] buffer = new byte[(int) size];
-        FileInputStream in = new FileInputStream(from);
-        in.read(buffer);
-        in.close();
-        return new String(buffer, "UTF-8");
-    }
-
-    private String getName(String where) {
-        int n = where.lastIndexOf('/');
-        if (n < 0)
-            return where;
-
-        return where.substring(n + 1);
-    }
-
-    public void setSourcepath(File[] files) {
-        sourcePath = files;
-    }
-
-    /**
-     * 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) {
-                errors
-                        .add("Can not create POM unless Bundle-SymbolicName is set");
-                return;
-            }
-
-            bsn = bsn.trim();
-            int n = bsn.lastIndexOf('.');
-            if (n <= 0) {
-                errors
-                        .add("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 map = parseHeader(licenses);
-                for (Iterator e = map.entrySet().iterator(); e.hasNext();) {
-                    Map.Entry entry = (Map.Entry) e.next();
-                    ps.println("    <license>");
-                    Map values = (Map) 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));
-        }
-    }
-
-    /**
-     * NEW
-     * 
-     */
-    void doPrebuild(Jar dot, Map clauses) {
-        for (Iterator i = clauses.entrySet().iterator(); i.hasNext();) {
-            Map.Entry entry = (Map.Entry) i.next();
-            String name = (String) entry.getKey();
-            Map args = (Map) entry.getValue();
-            File file = getFile(base, name);
-            File dir = file.getParentFile();
-            if (!dir.exists())
-                error("No directory for prebuild: " + file.getAbsolutePath());
-            else {
-                Instruction instr = Instruction.getPattern(file.getName());
-                File[] children = dir.listFiles();
-                for (int c = 0; c < children.length; c++) {
-                    File child = children[c];
-                    if (instr.matches(child.getName()) && !instr.isNegated()) {
-                        try {
-                            progress("Prebuilding "+child);
-                            doPrebuild(dot, child, args);
-                        } catch (Exception e) {
-                            error("Can not build: "+child);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    void doPrebuild(Jar dot, File f, Map args) throws Exception {
-        Builder builder = new Builder();
-        builder.setBase(base);
-        builder.setProperties(f);
-
-        Properties p = new Properties();
-        p.putAll(getProperties());
-        p.keySet().removeAll(builder.getProperties().keySet());
-        builder.getProperties().putAll(p);
-
-        Jar jar = builder.build();
-        String path = (String) args.get("path");
-        if (path != null)
-            path = f.getName();
-
-        dot.putResource(path, new JarResource(jar));
-    }
-
-    /**
-     * 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 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() {
-        for (Iterator j = tempJars.iterator(); j.hasNext();) {
-            Jar jar = (Jar) j.next();
-            jar.close();
-        }
-        super.close();
-    }
-}
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/DependencyEmbedder.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/DependencyEmbedder.java
index 3a89d4e..6e9cf18 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/DependencyEmbedder.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/DependencyEmbedder.java
@@ -30,9 +30,9 @@
 import org.apache.maven.plugin.MojoExecutionException;
 import org.codehaus.plexus.util.StringUtils;
 
-import aQute.lib.header.OSGiHeader;
 import aQute.lib.osgi.Analyzer;
 import aQute.lib.osgi.Instruction;
+import aQute.libg.header.OSGiHeader;
 
 
 /**
