diff --git a/bundleplugin/src/main/java/aQute/lib/base64/Base64.java b/bundleplugin/src/main/java/aQute/lib/base64/Base64.java
new file mode 100644
index 0000000..1210a02
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/base64/Base64.java
@@ -0,0 +1,135 @@
+package aQute.lib.base64;
+
+import java.io.*;
+
+/*
+ * Base 64 converter.
+ * 
+ * TODO Implement string to byte[]
+ */
+public class Base64 {
+	byte[]				data;
+
+	static final String	alphabet	= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+	static byte[]		values		= new byte[128];
+
+	static {
+		for (int i = 0; i < values.length; i++) {
+			values[i] = -1;
+		}
+		// Create reverse index
+		for (int i = 0; i < alphabet.length(); i++) {
+			char c = alphabet.charAt(i);
+			values[c] = (byte) i;
+		}
+	}
+
+	public Base64(byte data[]) {
+		this.data = data;
+	}
+
+	public final static byte[] decodeBase64(String string) {
+		string = string.trim();
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+		int register = 0;
+		int i = 0;
+		int pads = 0;
+
+		byte test[] = new byte[3];
+
+		while (i < string.length()) {
+			char c = string.charAt(i);
+			if (c > 0x7F)
+				throw new IllegalArgumentException(
+						"Invalid base64 character in " + string
+								+ ", character value > 128 ");
+			
+			int v = 0;
+			if ( c == '=' ) {
+				pads++;
+			} else {
+				v = values[c];
+				if ( v < 0 )
+					throw new IllegalArgumentException(
+							"Invalid base64 character in " + string + ", " + c );
+			}					
+			register <<= 6;
+			register |= v;
+			test[2] = (byte) (register & 0xFF);
+			test[1] = (byte) ((register >> 8) & 0xFF);
+			test[0] = (byte) ((register >> 16) & 0xFF);
+
+			i++;
+
+			if ((i % 4) == 0) {
+				flush(out, register, pads);
+				register = 0;
+				pads = 0;
+			}
+		}
+		return out.toByteArray();
+	}
+
+	static private void flush(ByteArrayOutputStream out, int register, int pads) {
+		switch (pads) {
+		case 0:
+			out.write(0xFF & (register >> 16));
+			out.write(0xFF & (register >> 8));
+			out.write(0xFF & (register >> 0));
+			break;
+			
+		case 1:
+			out.write(0xFF & (register >> 16));
+			out.write(0xFF & (register >> 8));
+			break;
+			
+		case 2:
+			out.write(0xFF & (register >> 16));
+		}
+	}
+
+	public Base64(String s) {
+		data = decodeBase64(s);
+	}
+
+	public String toString() {
+		return encodeBase64(data);
+	}
+
+	public static String encodeBase64(byte data[]) {
+		StringBuffer sb = new StringBuffer();
+		int buf = 0;
+		int bits = 0;
+		int n = 0;
+
+		while (true) {
+			if (bits >= 6) {
+				bits -= 6;
+				int v = 0x3F & (buf >> bits);
+				sb.append(alphabet.charAt(v));
+			} else {
+				if (n >= data.length)
+					break;
+
+				buf <<= 8;
+				buf |= 0xFF & data[n++];
+				bits += 8;
+			}
+		}
+		if (bits != 0) // must be less than 7
+			sb.append(alphabet.charAt(0x3F & (buf << (6 - bits))));
+
+		int mod = 4 - (sb.length() % 4);
+		if (mod != 4) {
+			for (int i = 0; i < mod; i++)
+				sb.append('=');
+		}
+		return sb.toString();
+	}
+
+	public Object toData() {
+		return data;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/base64/packageinfo b/bundleplugin/src/main/java/aQute/lib/base64/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/base64/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/LineCollection.java b/bundleplugin/src/main/java/aQute/lib/collections/LineCollection.java
new file mode 100644
index 0000000..36bfa39
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/LineCollection.java
@@ -0,0 +1,54 @@
+package aQute.lib.collections;
+
+import java.io.*;
+import java.util.*;
+
+public class LineCollection implements Iterator<String>, Closeable {
+	final BufferedReader	reader;
+	String					next;
+
+	public LineCollection(InputStream in) throws IOException {
+		this(new InputStreamReader(in, "UTF8"));
+	}
+
+	public LineCollection(File in) throws IOException {
+		this(new FileReader(in));
+	}
+
+	public LineCollection(Reader reader) throws IOException {
+		this(new BufferedReader(reader));
+	}
+
+	public LineCollection(BufferedReader reader) throws IOException {
+		this.reader = reader;
+		next = reader.readLine();
+	}
+
+	public boolean hasNext() {
+		return next != null;
+	}
+
+	public String next() {
+		if (next == null)
+			throw new IllegalStateException("Iterator has finished");
+		try {
+			String result = next;
+			next = reader.readLine();
+			if (next == null)
+				reader.close();
+			return result;
+		} catch (Exception e) {
+			// ignore
+			return null;
+		}
+	}
+
+	public void remove() {
+		if (next == null)
+			throw new UnsupportedOperationException("Cannot remove");
+	}
+
+	public void close() throws IOException {
+		reader.close();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/Logic.java b/bundleplugin/src/main/java/aQute/lib/collections/Logic.java
new file mode 100644
index 0000000..75322dd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/Logic.java
@@ -0,0 +1,22 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+public class Logic {
+	
+	public static <T> Collection<T> retain( Collection<T> first, Collection<T> ... sets) {
+		Set<T> result = new HashSet<T>(first);
+		for ( Collection<T> set : sets ) {
+			result.retainAll(set);
+		}
+		return result;
+	}
+	
+	public static <T> Collection<T> remove( Collection<T> first, Collection<T> ... sets) {
+		Set<T> result = new HashSet<T>(first);
+		for ( Collection<T> set : sets ) {
+			result.removeAll(set);
+		}
+		return result;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java b/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java
new file mode 100644
index 0000000..7672638
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java
@@ -0,0 +1,83 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+public class MultiMap<K,V> extends HashMap<K,Set<V>> {
+	private static final long	serialVersionUID	= 1L;
+	final Set<V> EMPTY = Collections.emptySet();
+	
+	public boolean add( K key, V value ) {
+		Set<V> set = get(key);
+		if ( set == null) {
+			set=new HashSet<V>();
+			put(key,set);
+		}
+		return set.add(value);
+	}
+	
+	public boolean addAll( K key, Collection<V> value ) {
+		Set<V> set = get(key);
+		if ( set == null) {
+			set=new HashSet<V>();
+			put(key,set);
+		}
+		return set.addAll(value);
+	}
+	
+	public boolean remove( K key, V value ) {
+		Set<V> set = get(key);
+		if ( set == null) {
+			return false;
+		}
+		boolean result = set.remove(value);
+		if ( set.isEmpty())
+			remove(key);
+		return result;
+	}
+	
+	public boolean removeAll( K key, Collection<V> value ) {
+		Set<V> set = get(key);
+		if ( set == null) {
+			return false;
+		}
+		boolean result = set.removeAll(value);
+		if ( set.isEmpty())
+			remove(key);
+		return result;
+	}
+	
+	public Iterator<V> iterate(K key) {
+		Set<V> set = get(key);
+		if ( set == null)
+			return EMPTY.iterator();
+		else
+			return set.iterator();
+	}
+	
+	public Iterator<V> all() {
+		return new Iterator<V>() {
+			Iterator<Set<V>> master = values().iterator();
+			Iterator<V> current = null;
+			
+			public boolean hasNext() {
+				if ( current == null || !current.hasNext()) {
+					if ( master.hasNext()) {
+						current = master.next().iterator();
+						return current.hasNext();
+					}
+					return false;
+				}
+				return true;
+			}
+
+			public V next() {
+				return current.next();
+			}
+
+			public void remove() {
+				current.remove();
+			}
+			
+		};
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/packageinfo b/bundleplugin/src/main/java/aQute/lib/collections/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/FileInstallRepo.java b/bundleplugin/src/main/java/aQute/lib/deployer/FileInstallRepo.java
new file mode 100644
index 0000000..cf05f98
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/FileInstallRepo.java
@@ -0,0 +1,149 @@
+package aQute.lib.deployer;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.lib.osgi.*;
+import aQute.libg.reporter.*;
+import aQute.libg.version.*;
+
+public class FileInstallRepo extends FileRepo {
+
+	String group;
+	boolean dirty;
+	Reporter reporter;
+	Pattern              REPO_FILE   = Pattern
+    .compile("([-a-zA-z0-9_\\.]+)-([0-9\\.]+)\\.(jar|lib)");
+	
+    public void setProperties(Map<String, String> map) {
+    	super.setProperties(map);
+    	group = map.get("group");
+    }
+    public void setReporter(Reporter reporter) {
+    	super.setReporter(reporter);
+        this.reporter = reporter;
+    }
+
+    public File put(Jar jar) throws Exception {
+        dirty = true;
+        Manifest manifest = jar.getManifest();
+        if (manifest == null)
+            throw new IllegalArgumentException("No manifest in JAR: " + jar);
+
+        String bsn = manifest.getMainAttributes().getValue(
+                Analyzer.BUNDLE_SYMBOLICNAME);
+        if (bsn == null)
+            throw new IllegalArgumentException("No Bundle SymbolicName set");
+
+        Map<String, Map<String, String>> b = Processor.parseHeader(bsn, null);
+        if (b.size() != 1)
+            throw new IllegalArgumentException("Multiple bsn's specified " + b);
+
+        for (String key : b.keySet()) {
+            bsn = key;
+            if (!Verifier.SYMBOLICNAME.matcher(bsn).matches())
+                throw new IllegalArgumentException(
+                        "Bundle SymbolicName has wrong format: " + bsn);
+        }
+
+        String versionString = manifest.getMainAttributes().getValue(
+                Analyzer.BUNDLE_VERSION);
+        Version version;
+        if (versionString == null)
+            version = new Version();
+        else
+            version = new Version(versionString);
+
+        File dir;
+        if (group == null) {
+        	dir = getRoot();
+        } else {
+        	dir= new File(getRoot(), group);
+        	dir.mkdirs();
+        }
+        String fName = bsn + "-" + version.getMajor() + "."
+                + version.getMinor() + "." + version.getMicro() + ".jar";
+        File file = new File(dir, fName);
+
+        jar.write(file);
+        fireBundleAdded(jar, file);
+
+        file = new File(dir, bsn + "-latest.jar");
+        if (file.isFile() && file.lastModified() < jar.lastModified()) {
+            jar.write(file);
+        }
+        return file;
+    }
+    public boolean refresh() {
+        if ( dirty ) {
+            dirty = false;
+            return true;
+        } else 
+            return false;
+    }
+	@Override
+	public List<String> list(String regex) {
+	       Instruction pattern = null;
+	        if (regex != null)
+	            pattern = Instruction.getPattern(regex);
+
+	        String list[] = getRoot().list();
+	        List<String> result = new ArrayList<String>();
+	        for (String f : list) {
+                Matcher m = REPO_FILE.matcher(f);
+                if (!m.matches()) {
+                	continue;
+                }
+                String s = m.group(1);
+	            if (pattern == null || pattern.matches(s))
+	                result.add(s);
+	        }
+	        return result;
+	}
+	@Override
+	public File[] get(String bsn, String versionRange) throws MalformedURLException {
+	       // If the version is set to project, we assume it is not
+        // for us. A project repo will then get it.
+        if (versionRange != null && versionRange.equals("project"))
+            return null;
+
+        //
+        // The version range we are looking for can
+        // be null (for all) or a version range.
+        //
+        VersionRange range;
+        if (versionRange == null || versionRange.equals("latest")) {
+            range = new VersionRange("0");
+        } else
+            range = new VersionRange(versionRange);
+
+        //
+        // Iterator over all the versions for this BSN.
+        // Create a sorted map over the version as key
+        // and the file as URL as value. Only versions
+        // that match the desired range are included in
+        // this list.
+        //
+        File instances[] = getRoot().listFiles();
+        SortedMap<Version, File> versions = new TreeMap<Version, File>();
+        for (int i = 0; i < instances.length; i++) {
+            Matcher m = REPO_FILE.matcher(instances[i].getName());
+            if (m.matches() && m.group(1).equals(bsn)) {
+                String versionString = m.group(2);
+                Version version;
+                if (versionString.equals("latest"))
+                    version = new Version(Integer.MAX_VALUE);
+                else
+                    version = new Version(versionString);
+
+                if (range.includes(version))
+                    versions.put(version, instances[i]);
+            }
+        }
+        return (File[]) versions.values().toArray(new File[versions.size()]);
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java b/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java
new file mode 100644
index 0000000..0c701aa
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java
@@ -0,0 +1,311 @@
+package aQute.lib.deployer;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+import aQute.libg.reporter.*;
+import aQute.libg.version.*;
+
+public class FileRepo implements Plugin, RepositoryPlugin, Refreshable, RegistryPlugin {
+	public static String LOCATION = "location";
+	public static String READONLY = "readonly";
+	public static String NAME = "name";
+
+	File[] EMPTY_FILES = new File[0];
+	protected File root;
+	Registry registry;
+	boolean canWrite = true;
+	Pattern REPO_FILE = Pattern
+			.compile("([-a-zA-z0-9_\\.]+)-([0-9\\.]+|latest)\\.(jar|lib)");
+	Reporter reporter;
+	boolean dirty;
+	String name;
+
+	public FileRepo() {}
+	
+	public FileRepo(String name, File location, boolean canWrite) {
+		this.name = name;
+		this.root = location;
+		this.canWrite = canWrite;
+	}
+	
+	protected void init() throws Exception {
+		// for extensions
+	}
+	
+	public void setProperties(Map<String, String> map) {
+		String location = (String) map.get(LOCATION);
+		if (location == null)
+			throw new IllegalArgumentException(
+					"Location must be set on a FileRepo plugin");
+
+		root = new File(location);
+		if (!root.isDirectory())
+			throw new IllegalArgumentException(
+					"Repository is not a valid directory " + root);
+
+		String readonly = (String) map.get(READONLY);
+		if (readonly != null && Boolean.valueOf(readonly).booleanValue())
+			canWrite = false;
+
+		name = (String) map.get(NAME);
+	}
+
+	/**
+	 * Get a list of URLs to bundles that are constrained by the bsn and
+	 * versionRange.
+	 */
+	public File[] get(String bsn, String versionRange)
+			throws Exception {
+		init();
+		
+		// If the version is set to project, we assume it is not
+		// for us. A project repo will then get it.
+		if (versionRange != null && versionRange.equals("project"))
+			return null;
+
+		//
+		// Check if the entry exists
+		//
+		File f = new File(root, bsn);
+		if (!f.isDirectory())
+			return null;
+
+		//
+		// The version range we are looking for can
+		// be null (for all) or a version range.
+		//
+		VersionRange range;
+		if (versionRange == null || versionRange.equals("latest")) {
+			range = new VersionRange("0");
+		} else
+			range = new VersionRange(versionRange);
+
+		//
+		// Iterator over all the versions for this BSN.
+		// Create a sorted map over the version as key
+		// and the file as URL as value. Only versions
+		// that match the desired range are included in
+		// this list.
+		//
+		File instances[] = f.listFiles();
+		SortedMap<Version, File> versions = new TreeMap<Version, File>();
+		for (int i = 0; i < instances.length; i++) {
+			Matcher m = REPO_FILE.matcher(instances[i].getName());
+			if (m.matches() && m.group(1).equals(bsn)) {
+				String versionString = m.group(2);
+				Version version;
+				if (versionString.equals("latest"))
+					version = new Version(Integer.MAX_VALUE);
+				else
+					version = new Version(versionString);
+
+				if (range.includes(version)
+						|| versionString.equals(versionRange))
+					versions.put(version, instances[i]);
+			}
+		}
+
+		File[] files = (File[]) versions.values().toArray(EMPTY_FILES);
+		if ("latest".equals(versionRange) && files.length > 0) {
+			return new File[] { files[files.length - 1] };
+		}
+		return files;
+	}
+
+	public boolean canWrite() {
+		return canWrite;
+	}
+
+	public File put(Jar jar) throws Exception {
+		init();
+		dirty = true;
+
+		Manifest manifest = jar.getManifest();
+		if (manifest == null)
+			throw new IllegalArgumentException("No manifest in JAR: " + jar);
+
+		String bsn = manifest.getMainAttributes().getValue(
+				Analyzer.BUNDLE_SYMBOLICNAME);
+		if (bsn == null)
+			throw new IllegalArgumentException("No Bundle SymbolicName set");
+
+		Map<String, Map<String, String>> b = Processor.parseHeader(bsn, null);
+		if (b.size() != 1)
+			throw new IllegalArgumentException("Multiple bsn's specified " + b);
+
+		for (String key : b.keySet()) {
+			bsn = key;
+			if (!Verifier.SYMBOLICNAME.matcher(bsn).matches())
+				throw new IllegalArgumentException(
+						"Bundle SymbolicName has wrong format: " + bsn);
+		}
+
+		String versionString = manifest.getMainAttributes().getValue(
+				Analyzer.BUNDLE_VERSION);
+		Version version;
+		if (versionString == null)
+			version = new Version();
+		else
+			version = new Version(versionString);
+
+		File dir = new File(root, bsn);
+		dir.mkdirs();
+		String fName = bsn + "-" + version.getMajor() + "."
+				+ version.getMinor() + "." + version.getMicro() + ".jar";
+		File file = new File(dir, fName);
+
+		reporter.trace("Updating " + file.getAbsolutePath());
+		if (!file.exists() || file.lastModified() < jar.lastModified()) {
+			jar.write(file);
+			reporter.progress("Updated " + file.getAbsolutePath());
+			fireBundleAdded(jar, file);
+		} else {
+			reporter.progress("Did not update " + jar
+					+ " because repo has a newer version");
+			reporter.trace("NOT Updating " + fName + " (repo is newer)");
+		}
+
+		File latest = new File(dir, bsn + "-latest.jar");
+		if (latest.exists() && latest.lastModified() < jar.lastModified()) {
+			jar.write(latest);
+			file = latest;
+		}
+		
+		return file;
+	}
+
+	protected void fireBundleAdded(Jar jar, File file) {
+		if (registry == null)
+			return;
+		List<RepositoryListenerPlugin> listeners = registry.getPlugins(RepositoryListenerPlugin.class);
+		for (RepositoryListenerPlugin listener : listeners) {
+			try {
+				listener.bundleAdded(this, jar, file);
+			} catch (Exception e) {
+				if (reporter != null)
+					reporter.warning("Repository listener threw an unexpected exception: %s", e);
+			}
+		}
+	}
+
+	public void setLocation(String string) {
+		root = new File(string);
+		if (!root.isDirectory())
+			throw new IllegalArgumentException("Invalid repository directory");
+	}
+
+	public void setReporter(Reporter reporter) {
+		this.reporter = reporter;
+	}
+
+	public List<String> list(String regex) throws Exception {
+		init();
+		Instruction pattern = null;
+		if (regex != null)
+			pattern = Instruction.getPattern(regex);
+
+		List<String> result = new ArrayList<String>();
+		if (root == null) {
+			if (reporter != null) reporter.error("FileRepo root directory is not set.");
+		} else {
+			File[] list = root.listFiles();
+			if (list != null) {
+				for (File f : list) {
+					if (!f.isDirectory()) continue; // ignore non-directories
+					String fileName = f.getName();
+					if (fileName.charAt(0) == '.') continue; // ignore hidden files
+					if (pattern == null || pattern.matches(fileName))
+						result.add(fileName);
+				}
+			} else 
+				if ( reporter != null)
+					reporter.error("FileRepo root directory (%s) does not exist", root);
+		}
+
+		return result;
+	}
+
+	public List<Version> versions(String bsn) throws Exception {
+		init();
+		File dir = new File(root, bsn);
+		if (dir.isDirectory()) {
+			String versions[] = dir.list();
+			List<Version> list = new ArrayList<Version>();
+			for (String v : versions) {
+				Matcher m = REPO_FILE.matcher(v);
+				if (m.matches()) {
+					String version = m.group(2);
+					if (version.equals("latest"))
+						version = "99";
+					list.add(new Version(version));
+				}
+			}
+			return list;
+		}
+		return null;
+	}
+
+	public String toString() {
+		return String
+				.format("%-40s r/w=%s", root.getAbsolutePath(), canWrite());
+	}
+
+	public File getRoot() {
+		return root;
+	}
+
+	public boolean refresh() {
+		if (dirty) {
+			dirty = false;
+			return true;
+		} else
+			return false;
+	}
+
+	public String getName() {
+		if (name == null) {
+			return toString();
+		}
+		return name;
+	}
+	public File get(String bsn, String version, Strategy strategy, Map<String,String> properties) throws Exception {
+		if ( version == null)
+			version = "0.0.0";
+		
+		if ( strategy == Strategy.EXACT) {				
+			VersionRange vr = new VersionRange(version);
+			if ( vr.isRange())
+				return null;
+			
+			File file = IO.getFile(root, bsn + "/" + version +"/" + bsn + "-" + version + ".jar");
+			if ( file.isFile())
+				return file;
+			else
+				return null;
+
+		}
+		File[] files = get(bsn, version);
+		if ( files == null || files.length == 0)
+			return null;
+		
+		if (files.length >= 0) {
+			switch (strategy) {
+			case LOWEST:
+				return files[0];
+			case HIGHEST:
+				return files[files.length - 1];
+			}
+		}
+		return null;
+	}
+
+	public void setRegistry(Registry registry) {
+		this.registry = registry;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/AbstractBaseOBR.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/AbstractBaseOBR.java
new file mode 100644
index 0000000..c6a1af5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/AbstractBaseOBR.java
@@ -0,0 +1,564 @@
+package aQute.lib.deployer.obr;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.SAXException;
+
+import aQute.bnd.build.ResolverMode;
+import aQute.bnd.service.OBRIndexProvider;
+import aQute.bnd.service.OBRResolutionMode;
+import aQute.bnd.service.Plugin;
+import aQute.bnd.service.Registry;
+import aQute.bnd.service.RegistryPlugin;
+import aQute.bnd.service.RemoteRepositoryPlugin;
+import aQute.bnd.service.ResourceHandle;
+import aQute.bnd.service.ResourceHandle.Location;
+import aQute.lib.filter.Filter;
+import aQute.lib.osgi.Jar;
+import aQute.libg.generics.Create;
+import aQute.libg.reporter.Reporter;
+import aQute.libg.version.Version;
+import aQute.libg.version.VersionRange;
+
+/**
+ * Abstract base class for OBR-based repositories.
+ * 
+ * <p>
+ * The repository implementation is read-only by default. To implement a writable
+ * repository, subclasses should override {@link #canWrite()} and {@link #put(Jar)}.
+ * 
+ * @author Neil Bartlett
+ *
+ */
+public abstract class AbstractBaseOBR implements RegistryPlugin, Plugin, RemoteRepositoryPlugin, OBRIndexProvider {
+	
+	public static final String PROP_NAME = "name";
+	public static final String PROP_RESOLUTION_MODE = "mode";
+	public static final String PROP_RESOLUTION_MODE_ANY = "any";
+	
+	public static final String REPOSITORY_FILE_NAME = "repository.xml";
+	
+	protected Registry registry;
+	protected Reporter reporter;
+	protected String name = this.getClass().getName();
+	protected Set<OBRResolutionMode> supportedModes = EnumSet.allOf(OBRResolutionMode.class);
+
+	private boolean initialised = false;
+	private final Map<String, SortedMap<Version, Resource>> pkgResourceMap = new HashMap<String, SortedMap<Version, Resource>>();
+	private final Map<String, SortedMap<Version, Resource>> bsnMap = new HashMap<String, SortedMap<Version, Resource>>();
+	
+	protected abstract File getCacheDirectory();
+
+	protected void addResourceToIndex(Resource resource) {
+		addBundleSymbolicNameToIndex(resource);
+		addPackagesToIndex(resource);
+	}
+
+	protected synchronized void reset() {
+		initialised = false;
+	}
+
+	/**
+	 * Initialise the indexes prior to main initialisation of internal
+	 * data structures. This implementation does nothing, but subclasses
+	 * may override if they need to perform such initialisation.
+	 * @throws Exception 
+	 */
+	protected void initialiseIndexes() throws Exception {
+	}
+
+	protected final synchronized void init() throws Exception {
+		if (!initialised) {
+			bsnMap.clear();
+			pkgResourceMap.clear();
+			
+			initialiseIndexes();
+			
+			IResourceListener listener = new IResourceListener() {
+				public boolean processResource(Resource resource) {
+					addResourceToIndex(resource);
+					return true;
+				}
+			};
+			Collection<URL> indexes = getOBRIndexes();
+			for (URL indexLocation : indexes) {
+				try {
+					InputStream stream = indexLocation.openStream();
+					readIndex(indexLocation.toString(), stream, listener);
+				} catch (Exception e) {
+					e.printStackTrace();
+					reporter.error("Unable to read index at URL '%s'.", indexLocation);
+				}
+			}
+			
+			initialised = true;
+		}
+	}
+	
+	public void setRegistry(Registry registry) {
+		this.registry = registry;
+	}
+
+	public void setProperties(Map<String, String> map) {
+		if (map.containsKey(PROP_NAME))
+			name = map.get(PROP_NAME);
+		
+		if (map.containsKey(PROP_RESOLUTION_MODE)) {
+			supportedModes = EnumSet.noneOf(OBRResolutionMode.class);
+			StringTokenizer tokenizer = new StringTokenizer(map.get(PROP_RESOLUTION_MODE), ",");
+			while (tokenizer.hasMoreTokens()) {
+				String token = tokenizer.nextToken().trim();
+				if (PROP_RESOLUTION_MODE_ANY.equalsIgnoreCase(token))
+					supportedModes = EnumSet.allOf(OBRResolutionMode.class);
+				else {
+					try {
+						supportedModes.add(OBRResolutionMode.valueOf(token));
+					} catch (Exception e) {
+						if (reporter != null) reporter.error("Unknown OBR resolution mode: " + token);
+					}
+				}
+			}
+		}
+	}
+	
+	public File[] get(String bsn, String range) throws Exception {
+		ResourceHandle[] handles = getHandles(bsn, range);
+		
+		return requestAll(handles);
+	}
+	
+	protected static File[] requestAll(ResourceHandle[] handles) throws IOException {
+		File[] result = (handles == null) ? new File[0] : new File[handles.length];
+		for (int i = 0; i < result.length; i++) {
+			result[i] = handles[i].request();
+		}
+		return result;
+	}
+
+	protected ResourceHandle[] getHandles(String bsn, String rangeStr) throws Exception {
+		init();
+		
+		// If the range is set to "project", we cannot resolve it.
+		if ("project".equals(rangeStr))
+			return null;
+		
+		
+		SortedMap<Version, Resource> versionMap = bsnMap.get(bsn);
+		if (versionMap == null || versionMap.isEmpty())
+			return null;
+		List<Resource> resources = narrowVersionsByVersionRange(versionMap, rangeStr);
+		List<ResourceHandle> handles = mapResourcesToHandles(resources);
+		
+		return (ResourceHandle[]) handles.toArray(new ResourceHandle[handles.size()]);
+	}
+	
+	public void setReporter(Reporter reporter) {
+		this.reporter = reporter;
+	}
+	
+	public File get(String bsn, String range, Strategy strategy, Map<String, String> properties) throws Exception {
+		ResourceHandle handle = getHandle(bsn, range, strategy, properties);
+		return handle != null ? handle.request() : null;
+	}
+	
+	public ResourceHandle getHandle(String bsn, String range, Strategy strategy, Map<String, String> properties) throws Exception {
+		ResourceHandle result;
+		if (bsn != null)
+			result = resolveBundle(bsn, range, strategy);
+		else {
+			String pkgName = properties.get(CapabilityType.PACKAGE.getTypeName());
+			
+			String modeName = properties.get(CapabilityType.MODE.getTypeName());
+			ResolverMode mode = (modeName != null) ? ResolverMode.valueOf(modeName) : null;
+			
+			if (pkgName != null)
+				result = resolvePackage(pkgName, range, strategy, mode, properties);
+			else
+				throw new IllegalArgumentException("Cannot resolve bundle: neither bsn nor package specified.");
+		}
+		return result;
+	}
+
+	public boolean canWrite() {
+		return false;
+	}
+
+	public File put(Jar jar) throws Exception {
+		throw new UnsupportedOperationException("Read-only repository.");
+	}
+
+	public List<String> list(String regex) throws Exception {
+		init();
+		Pattern pattern = regex != null ? Pattern.compile(regex) : null;
+		List<String> result = new LinkedList<String>();
+		
+		for (String bsn : bsnMap.keySet()) {
+			if (pattern == null || pattern.matcher(bsn).matches())
+				result.add(bsn);
+		}
+		
+		return result;
+	}
+
+	public List<Version> versions(String bsn) throws Exception {
+		init();
+		SortedMap<Version, Resource> versionMap = bsnMap.get(bsn);
+		List<Version> list;
+		if (versionMap != null) {
+			list = new ArrayList<Version>(versionMap.size());
+			list.addAll(versionMap.keySet());
+		} else {
+			list = Collections.emptyList();
+		}
+		return list;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	void addBundleSymbolicNameToIndex(Resource resource) {
+		String bsn = resource.getSymbolicName();
+		Version version;
+		String versionStr = resource.getVersion();
+		try {
+			version = new Version(versionStr);
+		} catch (Exception e) {
+			version = new Version("0.0.0");
+		}
+		SortedMap<Version, Resource> versionMap = bsnMap.get(bsn);
+		if (versionMap == null) {
+			versionMap = new TreeMap<Version, Resource>();
+			bsnMap.put(bsn, versionMap);
+		}
+		versionMap.put(version, resource);
+	}
+
+	void addPackagesToIndex(Resource resource) {
+		for (Capability capability : resource.getCapabilities()) {
+			if (CapabilityType.PACKAGE.getTypeName().equals(capability.getName())) {
+				String pkgName = null;
+				String versionStr = null;
+				
+				for (Property prop : capability.getProperties()) {
+					if (Property.PACKAGE.equals(prop.getName()))
+						pkgName = prop.getValue();
+					else if (Property.VERSION.equals(prop.getName()))
+						versionStr = prop.getValue();
+				}
+				
+				Version version;
+				try {
+					version = new Version(versionStr);
+				} catch (Exception e) {
+					version = new Version("0.0.0");
+				}
+				
+				if (pkgName != null) {
+					SortedMap<Version, Resource> versionMap = pkgResourceMap.get(pkgName);
+					if (versionMap == null) {
+						versionMap = new TreeMap<Version, Resource>();
+						pkgResourceMap.put(pkgName, versionMap);
+					}
+					versionMap.put(version, resource);
+				}
+			}
+		}
+	}
+
+	/**
+	 * @return Whether to continue parsing other indexes
+	 * @throws IOException 
+	 */
+	boolean readIndex(String baseUrl, InputStream stream, IResourceListener listener) throws ParserConfigurationException, SAXException, IOException {
+		SAXParserFactory parserFactory = SAXParserFactory.newInstance();
+		SAXParser parser = parserFactory.newSAXParser();
+		try {
+			parser.parse(stream, new OBRSAXHandler(baseUrl, listener));
+			return true;
+		} catch (StopParseException e) {
+			return false;
+		} finally {
+			stream.close();
+		}
+	}
+
+	List<Resource> narrowVersionsByFilter(String pkgName, SortedMap<Version, Resource> versionMap, Filter filter) {
+		List<Resource> result = new ArrayList<Resource>(versionMap.size());
+		
+		Dictionary<String, String> dict = new Hashtable<String, String>();
+		dict.put("package", pkgName);
+		
+		for (Version version : versionMap.keySet()) {
+			dict.put("version", version.toString());
+			if (filter.match(dict))
+				result.add(versionMap.get(version));
+		}
+		
+		return result;
+	}
+
+	List<Resource> narrowVersionsByVersionRange(SortedMap<Version, Resource> versionMap, String rangeStr) {
+		List<Resource> result;
+		if ("latest".equals(rangeStr)) {
+			Version highest = versionMap.lastKey();
+			result = Create.list(new Resource[] { versionMap.get(highest) });
+		} else {
+			VersionRange range = rangeStr != null ? new VersionRange(rangeStr) : null;
+			
+			// optimisation: skip versions definitely less than the range
+			if (range != null && range.getLow() != null)
+				versionMap = versionMap.tailMap(range.getLow());
+			
+			result = new ArrayList<Resource>(versionMap.size());
+			for (Version version : versionMap.keySet()) {
+				if (range == null || range.includes(version))
+					result.add(versionMap.get(version));
+				
+				// optimisation: skip versions definitely higher than the range
+				if (range != null && range.isRange() && version.compareTo(range.getHigh()) >= 0)
+					break;
+			}
+		}
+		return result;
+	}
+	
+	void filterResourcesByResolverMode(Collection<Resource> resources, ResolverMode mode) {
+		assert mode != null;
+		
+		Properties modeCapability = new Properties();
+		modeCapability.setProperty(CapabilityType.MODE.getTypeName(), mode.name());
+		
+		for (Iterator<Resource> iter = resources.iterator(); iter.hasNext(); ) {
+			Resource resource = iter.next();
+			
+			Require modeRequire = resource.findRequire(CapabilityType.MODE.getTypeName());
+			if (modeRequire == null)
+				continue;
+			else if (modeRequire.getFilter() == null)
+				iter.remove();
+			else {
+				try {
+					Filter filter = new Filter(modeRequire.getFilter());
+					if (!filter.match(modeCapability))
+						iter.remove();
+				} catch (IllegalArgumentException e) {
+					if (reporter != null)
+						reporter.error("Error parsing mode filter requirement on resource %s: %s", resource.getUrl(), modeRequire.getFilter());
+					iter.remove();
+				}
+			}
+		}
+	}
+	
+	List<ResourceHandle> mapResourcesToHandles(Collection<Resource> resources) throws Exception {
+		List<ResourceHandle> result = new ArrayList<ResourceHandle>(resources.size());
+		
+		for (Resource resource : resources) {
+			ResourceHandle handle = mapResourceToHandle(resource);
+			if (handle != null)
+				result.add(handle);
+		}
+		
+		return result;
+	}
+	
+	ResourceHandle mapResourceToHandle(Resource resource) throws Exception {
+		ResourceHandle result = null;
+		
+		URLResourceHandle handle ;
+		try {
+			handle = new URLResourceHandle(resource.getUrl(), resource.getBaseUrl(), getCacheDirectory());
+		} catch (FileNotFoundException e) {
+			throw new FileNotFoundException("Broken link in repository index: " + e.getMessage());
+		}
+		if (handle.getLocation() == Location.local || getCacheDirectory() != null)
+			result = handle;
+		
+		return result;
+	}
+
+	ResourceHandle resolveBundle(String bsn, String rangeStr, Strategy strategy) throws Exception {
+		if (rangeStr == null) rangeStr = "0.0.0";
+		
+		if (strategy == Strategy.EXACT) {
+			return findExactMatch(bsn, rangeStr, bsnMap);
+		}
+		
+		ResourceHandle[] handles = getHandles(bsn, rangeStr);
+		ResourceHandle selected;
+		if (handles == null || handles.length == 0)
+			selected = null;
+		else {
+			switch(strategy) {
+			case LOWEST:
+				selected = handles[0];
+				break;
+			default:
+				selected = handles[handles.length - 1];
+			}
+		}
+		return selected;
+	}
+
+	ResourceHandle resolvePackage(String pkgName, String rangeStr, Strategy strategy, ResolverMode mode, Map<String, String> props) throws Exception {
+		init();
+		if (rangeStr == null) rangeStr = "0.0.0";
+		
+		SortedMap<Version, Resource> versionMap = pkgResourceMap.get(pkgName);
+		if (versionMap == null)
+			return null;
+		
+		// Was a filter expression supplied?
+		Filter filter = null;
+		String filterStr = props.get("filter");
+		if (filterStr != null) {
+			filter = new Filter(filterStr);
+		}
+		
+		// Narrow the resources by version range string or filter.
+		List<Resource> resources;
+		if (filter != null)
+			resources = narrowVersionsByFilter(pkgName, versionMap, filter);
+		else
+			resources = narrowVersionsByVersionRange(versionMap, rangeStr);
+		
+		// Remove resources that are invalid for the current resolution mode
+		if (mode != null)
+			filterResourcesByResolverMode(resources, mode);
+		
+		// Select the most suitable one
+		Resource selected;
+		if (resources == null || resources.isEmpty())
+			selected = null;
+		else {
+			switch (strategy) {
+			case LOWEST:
+				selected = resources.get(0);
+				break;
+			default:
+				selected = resources.get(resources.size() - 1);
+			}
+			expandPackageUses(pkgName, selected, props);
+		}
+		return selected != null ? mapResourceToHandle(selected) : null;
+	}
+
+	void expandPackageUses(String pkgName, Resource resource, Map<String, String> props) {
+		List<String> internalUses = new LinkedList<String>();
+		Map<String, Require> externalUses = new HashMap<String, Require>();
+		
+		internalUses.add(pkgName);
+		
+		Capability capability = resource.findPackageCapability(pkgName);
+		Property usesProp = capability.findProperty(Property.USES);
+		if (usesProp != null) {
+			StringTokenizer tokenizer = new StringTokenizer(usesProp.getValue(), ",");
+			while (tokenizer.hasMoreTokens()) {
+				String usesPkgName = tokenizer.nextToken();
+				Capability usesPkgCap = resource.findPackageCapability(usesPkgName);
+				if (usesPkgCap != null)
+					internalUses.add(usesPkgName);
+				else {
+					Require require = resource.findPackageRequire(usesPkgName);
+					if (require != null)
+						externalUses.put(usesPkgName, require);
+				}
+			}
+		}
+		props.put("packages", listToString(internalUses));
+		props.put("import-uses", formatPackageRequires(externalUses));
+	}
+	
+	String listToString(List<?> list) {
+		StringBuilder builder = new StringBuilder();
+		
+		int count = 0;
+		for (Object item : list) {
+			if (count++ > 0) builder.append(',');
+			builder.append(item);
+		}
+		
+		return builder.toString();
+	}
+
+	String formatPackageRequires(Map<String, Require> externalUses) {
+		StringBuilder builder = new StringBuilder();
+		
+		int count = 0;
+		for (Entry<String, Require> entry : externalUses.entrySet()) {
+			String pkgName = entry.getKey();
+			String filter = entry.getValue().getFilter();
+
+			if (count++ > 0)
+				builder.append(',');
+			builder.append(pkgName);
+			builder.append(";filter='");
+			builder.append(filter);
+			builder.append('\'');
+		}
+		
+		return builder.toString();
+	}
+
+	ResourceHandle findExactMatch(String identity, String version, Map<String, SortedMap<Version, Resource>> resourceMap) throws Exception {
+		Resource resource;
+		VersionRange range = new VersionRange(version);
+		if (range.isRange())
+			return null;
+		
+		SortedMap<Version, Resource> versions = resourceMap.get(identity);
+		resource = versions.get(range.getLow());
+		
+		return mapResourceToHandle(resource);
+	}
+	
+	/**
+	 * Utility function for parsing lists of URLs.
+	 * 
+	 * @param locationsStr
+	 *            Comma-separated list of URLs
+	 * @throws MalformedURLException
+	 */
+	protected static List<URL> parseLocations(String locationsStr) throws MalformedURLException {
+		StringTokenizer tok = new StringTokenizer(locationsStr, ",");
+		List<URL> urls = new ArrayList<URL>(tok.countTokens());
+		while (tok.hasMoreTokens()) {
+			String urlStr = tok.nextToken().trim();
+			urls.add(new URL(urlStr));
+		}
+		return urls;
+	}
+
+	public Set<OBRResolutionMode> getSupportedModes() {
+		return supportedModes;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/Capability.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/Capability.java
new file mode 100644
index 0000000..983afed
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/Capability.java
@@ -0,0 +1,93 @@
+package aQute.lib.deployer.obr;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+public class Capability {
+	
+	private final String name;
+	private final List<Property> properties;
+
+	private Capability(String name, List<Property> properties) {
+		this.name = name;
+		this.properties = properties;
+	}
+	
+	public static class Builder {
+		private String name;
+		private final List<Property> properties = new LinkedList<Property>();
+		
+		public Builder setName(String name) {
+			this.name = name;
+			return this;
+		}
+		
+		public Builder addProperty(Property property) {
+			this.properties.add(property);
+			return this;
+		}
+		
+		public Capability build() {
+			if (name == null) throw new IllegalStateException("'name' field is not initialised.");
+			return new Capability(name, Collections.unmodifiableList(properties));
+		}
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public List<Property> getProperties() {
+		return properties;
+	}
+	
+	public Property findProperty(String propertyName) {
+		assert propertyName != null;
+		for (Property prop : properties) {
+			if (propertyName.equals(prop.getName()))
+				return prop;
+		}
+		return null;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("Capability [name=").append(name).append(", properties=").append(properties).append("]");
+		return builder.toString();
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result
+				+ ((properties == null) ? 0 : properties.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Capability other = (Capability) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (properties == null) {
+			if (other.properties != null)
+				return false;
+		} else if (!properties.equals(other.properties))
+			return false;
+		return true;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/CapabilityType.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/CapabilityType.java
new file mode 100644
index 0000000..d3f8ae3
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/CapabilityType.java
@@ -0,0 +1,31 @@
+package aQute.lib.deployer.obr;
+
+public enum CapabilityType {
+	
+	PACKAGE("package"),
+	EE("ee"),
+	BUNDLE("bundle"),
+	MODE("mode"),
+	OTHER(null);
+	
+	private String typeName;
+
+	CapabilityType(String name) {
+		this.typeName = name;
+	}
+	
+	public String getTypeName() {
+		return typeName;
+	}
+	
+	/**
+	 * @throws IllegalArgumentException
+	 */
+	public static CapabilityType getForTypeName(String typeName) {
+		for (CapabilityType type : CapabilityType.values()) {
+			if (type.typeName != null && type.typeName.equals(typeName))
+				return type;
+		}
+		throw new IllegalArgumentException("Unknown capability type: " + typeName);
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/IResourceListener.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/IResourceListener.java
new file mode 100644
index 0000000..22dae7a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/IResourceListener.java
@@ -0,0 +1,15 @@
+package aQute.lib.deployer.obr;
+
+public interface IResourceListener {
+	/**
+	 * Process an OBR resource descriptor from the index document, and possibly
+	 * request early termination of the parser.
+	 * 
+	 * @param resource
+	 *            The resource descriptor to be processed.
+	 * @return Whether to continue parsing the document; returning {@code false}
+	 *         will result in the parser being stopped with a
+	 *         {@link StopParseException}.
+	 */
+	boolean processResource(Resource resource);
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/LocalOBR.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/LocalOBR.java
new file mode 100644
index 0000000..e59266a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/LocalOBR.java
@@ -0,0 +1,198 @@
+package aQute.lib.deployer.obr;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.transform.stream.StreamResult;
+
+import org.osgi.service.bindex.BundleIndexer;
+import org.xml.sax.InputSource;
+import org.xml.sax.XMLReader;
+
+import aQute.bnd.service.Refreshable;
+import aQute.bnd.service.Registry;
+import aQute.bnd.service.RegistryPlugin;
+import aQute.lib.deployer.FileRepo;
+import aQute.lib.io.IO;
+import aQute.lib.osgi.Jar;
+import aQute.libg.reporter.Reporter;
+import aQute.libg.sax.SAXUtil;
+import aQute.libg.sax.filters.MergeContentFilter;
+import aQute.libg.version.Version;
+
+public class LocalOBR extends OBR implements Refreshable, RegistryPlugin {
+	
+	public static final String PROP_LOCAL_DIR = "local";
+	public static final String PROP_READONLY = "readonly";
+
+	private final FileRepo storageRepo = new FileRepo();
+	
+	private Registry registry;
+	private File storageDir;
+	private File localIndex;
+	
+	private List<URL> indexUrls;
+	
+	public void setRegistry(Registry registry) {
+		this.registry = registry;
+	}
+	
+	@Override
+	public void setReporter(Reporter reporter) {
+		super.setReporter(reporter);
+		storageRepo.setReporter(reporter);
+	}
+
+	@Override
+	public void setProperties(Map<String, String> map) {
+		super.setProperties(map);
+		
+		// Load essential properties
+		String localDirPath = map.get(PROP_LOCAL_DIR);
+		if (localDirPath == null)
+			throw new IllegalArgumentException(String.format("Attribute '%s' must be set on LocalOBR plugin.", PROP_LOCAL_DIR));
+		storageDir = new File(localDirPath);
+		if (!storageDir.isDirectory())
+			throw new IllegalArgumentException(String.format("Local path '%s' does not exist or is not a directory.", localDirPath));
+		
+		// Configure the storage repository
+		Map<String, String> storageRepoConfig = new HashMap<String, String>(2);
+		storageRepoConfig.put(FileRepo.LOCATION, localDirPath);
+		storageRepoConfig.put(FileRepo.READONLY, map.get(PROP_READONLY));
+		storageRepo.setProperties(storageRepoConfig);
+		
+		// Set the local index and cache directory locations
+		localIndex = new File(storageDir, REPOSITORY_FILE_NAME);
+		if (localIndex.exists() && !localIndex.isFile())
+			throw new IllegalArgumentException(String.format("Cannot build local repository index: '%s' already exists but is not a plain file.", localIndex.getAbsolutePath()));
+		cacheDir = new File(storageDir, ".obrcache");
+		if (cacheDir.exists() && !cacheDir.isDirectory())
+			throw new IllegalArgumentException(String.format("Cannot create repository cache: '%s' already exists but is not directory.", cacheDir.getAbsolutePath()));
+	}
+	
+	@Override
+	protected void initialiseIndexes() throws Exception {
+		if (!localIndex.exists()) {
+			regenerateIndex();
+		}
+		try {
+			Collection<URL> remotes = super.getOBRIndexes();
+			indexUrls = new ArrayList<URL>(remotes.size() + 1);
+			indexUrls.add(localIndex.toURI().toURL());
+			indexUrls.addAll(remotes);
+		} catch (IOException e) {
+			throw new IllegalArgumentException("Error initialising local index URL", e);
+		}
+	}
+	
+	private void regenerateIndex() throws Exception {
+		BundleIndexer indexer = registry.getPlugin(BundleIndexer.class);
+		if (indexer == null)
+			throw new IllegalStateException("Cannot index repository: no Bundle Indexer service or plugin found.");
+		
+		Set<File> allFiles = new HashSet<File>();
+		gatherFiles(allFiles);
+		
+		FileOutputStream out = null;
+		try {
+			out = new FileOutputStream(localIndex);
+			if (!allFiles.isEmpty()) {
+				Map<String, String> config = new HashMap<String, String>();
+				config.put(BundleIndexer.REPOSITORY_NAME, this.getName());
+				config.put(BundleIndexer.ROOT_URL, localIndex.toURI().toURL().toString());
+				indexer.index(allFiles, out, config);
+			} else {
+				ByteArrayInputStream emptyRepo = new ByteArrayInputStream("<?xml version='1.0' encoding='UTF-8'?>\n<repository lastmodified='0'/>".getBytes());
+				IO.copy(emptyRepo, out);
+			}
+		} finally {
+			out.close();
+		}
+	}
+
+	private void gatherFiles(Set<File> allFiles) throws Exception {
+		List<String> bsns = storageRepo.list(null);
+		if (bsns != null) for (String bsn : bsns) {
+			List<Version> versions = storageRepo.versions(bsn);
+			if (versions != null) for (Version version : versions) {
+				File file = storageRepo.get(bsn, version.toString(), Strategy.HIGHEST, null);
+				if (file != null)
+					allFiles.add(file);
+			}
+		}
+	}
+
+	@Override
+	public List<URL> getOBRIndexes() {
+		return indexUrls;
+	}
+	
+	@Override
+	public boolean canWrite() {
+		return storageRepo.canWrite();
+	}
+	
+	@Override
+	public synchronized File put(Jar jar) throws Exception {
+		File newFile = storageRepo.put(jar);
+		
+		// Index the new file
+		BundleIndexer indexer = registry.getPlugin(BundleIndexer.class);
+		if (indexer == null)
+			throw new IllegalStateException("Cannot index repository: no Bundle Indexer service or plugin found.");
+		ByteArrayOutputStream newIndexBuffer = new ByteArrayOutputStream();
+		indexer.index(Collections.singleton(newFile), newIndexBuffer, null);
+		
+		// Merge into main index
+		File tempIndex = File.createTempFile("repository", ".xml");
+		FileOutputStream tempIndexOutput = new FileOutputStream(tempIndex);
+		MergeContentFilter merger = new MergeContentFilter();
+		XMLReader reader = SAXUtil.buildPipeline(new StreamResult(tempIndexOutput), new UniqueResourceFilter(), merger);
+		
+		try {
+			// Parse the newly generated index
+			reader.parse(new InputSource(new ByteArrayInputStream(newIndexBuffer.toByteArray())));
+			
+			// Parse the existing index (which may be empty/missing)
+			try {
+				reader.parse(new InputSource(new FileInputStream(localIndex)));
+			} catch (Exception e) {
+				reporter.warning("Existing local index is invalid or missing, overwriting (%s).", localIndex.getAbsolutePath());
+			}
+			
+			merger.closeRootAndDocument();
+		} finally {
+			tempIndexOutput.flush();
+			tempIndexOutput.close();
+		}
+		IO.copy(tempIndex, localIndex);
+		
+		// Re-read the index
+		reset();
+		init();
+		
+		return newFile;
+	}
+
+	public boolean refresh() {
+		reset();
+		return true;
+	}
+
+	public File getRoot() {
+		return storageDir;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/OBR.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/OBR.java
new file mode 100644
index 0000000..ddf5fcc
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/OBR.java
@@ -0,0 +1,120 @@
+package aQute.lib.deployer.obr;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import aQute.lib.deployer.FileRepo;
+
+/**
+ * A simple read-only OBR-based repository that uses a list of index locations
+ * and a basic local cache.
+ * 
+ * <p>
+ * <h2>Properties</h2>
+ * <ul>
+ * <li><b>locations:</b> comma-separated list of index URLs. <b>NB:</b> surround with single quotes!</li>
+ * <li><b>name:</b> repository name; defaults to the index URLs.
+ * <li><b>cache:</b> local cache directory. May be omitted, in which case the repository will only be
+ * able to serve resources with {@code file:} URLs.</li>
+ * <li><b>location:</b> (deprecated) alias for "locations".
+ * </ul>
+ * 
+ * <p>
+ * <h2>Example</h2>
+ * 
+ * <pre>
+ * -plugin: aQute.lib.deployer.obr.OBR;locations='http://www.example.com/repository.xml';cache=${workspace}/.cache
+ * </pre>
+ * 
+ * @author Neil Bartlett
+ *
+ */
+public class OBR extends AbstractBaseOBR {
+	
+	public static final String PROP_LOCATIONS = "locations";
+	@Deprecated
+	public static final String PROP_LOCATION = "location";
+	public static final String PROP_CACHE = "cache";
+
+	protected List<URL> locations;
+	protected File cacheDir;
+
+	public void setProperties(Map<String, String> map) {
+		super.setProperties(map);
+		
+		String locationsStr = map.get(PROP_LOCATIONS);
+		// backwards compatibility
+		if (locationsStr == null) locationsStr = map.get(PROP_LOCATION);
+		
+		try {
+			if (locationsStr != null)
+				locations = parseLocations(locationsStr);
+			else
+				locations = Collections.emptyList();
+		} catch (MalformedURLException e) {
+			throw new IllegalArgumentException(String.format("Invalid location, unable to parse as URL list: %s", locationsStr), e);
+		}
+		
+		String cacheDirStr = map.get(PROP_CACHE);
+		if (cacheDirStr != null)
+			cacheDir = new File(cacheDirStr);
+	}
+	
+	private FileRepo lookupCachedFileRepo() {
+		if (registry != null) {
+			List<FileRepo> repos = registry.getPlugins(FileRepo.class);
+			for (FileRepo repo : repos) {
+				if ("cache".equals(repo.getName()))
+					return repo;
+			}
+		}
+		return null;
+	}
+
+	public List<URL> getOBRIndexes() {
+		return locations;
+	}
+
+	@Override
+	public synchronized File getCacheDirectory() {
+		if (cacheDir == null) {
+			FileRepo cacheRepo = lookupCachedFileRepo();
+			if (cacheRepo != null) {
+				File temp = new File(cacheRepo.getRoot(), ".obr");
+				temp.mkdirs();
+				if (temp.exists())
+					cacheDir = temp;
+			}
+		}
+		return cacheDir;
+	}
+	
+	public void setCacheDirectory(File cacheDir) {
+		this.cacheDir = cacheDir;
+	}
+	
+	@Override
+	public String getName() {
+		if (name != null && name != this.getClass().getName())
+			return name;
+		
+		StringBuilder builder = new StringBuilder();
+		
+		int count = 0;
+		for (URL location : locations) {
+			if (count++ > 0 ) builder.append(',');
+			builder.append(location);
+		}
+		return builder.toString();
+	}
+
+	public void setLocations(URL[] urls) {
+		this.locations = Arrays.asList(urls);
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/OBRSAXHandler.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/OBRSAXHandler.java
new file mode 100644
index 0000000..3634cb9
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/OBRSAXHandler.java
@@ -0,0 +1,79 @@
+package aQute.lib.deployer.obr;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class OBRSAXHandler extends DefaultHandler {
+	
+	private static final String TAG_RESOURCE = "resource";
+	private static final String ATTR_RESOURCE_ID = "id";
+	private static final String ATTR_RESOURCE_PRESENTATION_NAME = "presentationname";
+	private static final String ATTR_RESOURCE_SYMBOLIC_NAME = "symbolicname";
+	private static final String ATTR_RESOURCE_URI = "uri";
+	private static final String ATTR_RESOURCE_VERSION = "version";
+	
+	private static final String TAG_CAPABILITY = "capability";
+	private static final String ATTR_CAPABILITY_NAME = "name";
+	
+	private static final String TAG_REQUIRE = "require";
+	private static final String ATTR_REQUIRE_NAME = "name";
+	private static final String ATTR_REQUIRE_FILTER = "filter";
+	private static final String ATTR_REQUIRE_OPTIONAL = "optional";
+	
+	private static final String TAG_PROPERTY = "p";
+	private static final String ATTR_PROPERTY_NAME = "n";
+	private static final String ATTR_PROPERTY_TYPE = "t";
+	private static final String ATTR_PROPERTY_VALUE = "v";
+
+	private final String baseUrl;
+	private final IResourceListener resourceListener;
+	
+	private Resource.Builder resourceBuilder = null;
+	private Capability.Builder capabilityBuilder = null;
+	private Require require = null;
+
+	public OBRSAXHandler(String baseUrl, IResourceListener listener) {
+		this.baseUrl = baseUrl;
+		this.resourceListener = listener;
+	}
+	
+
+	@Override
+	public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+		if (TAG_RESOURCE.equals(qName)) {
+			resourceBuilder = new Resource.Builder()
+				.setId(atts.getValue(ATTR_RESOURCE_ID))
+				.setPresentationName(atts.getValue(ATTR_RESOURCE_PRESENTATION_NAME))
+				.setSymbolicName(atts.getValue(ATTR_RESOURCE_SYMBOLIC_NAME))
+				.setUrl(atts.getValue(ATTR_RESOURCE_URI))
+				.setVersion(atts.getValue(ATTR_RESOURCE_VERSION))
+				.setBaseUrl(baseUrl);
+		} else if (TAG_CAPABILITY.equals(qName)) {
+			capabilityBuilder = new Capability.Builder()
+				.setName(atts.getValue(ATTR_CAPABILITY_NAME));
+		} else if (TAG_REQUIRE.equals(qName)) {
+			require = new Require(atts.getValue(ATTR_REQUIRE_NAME), atts.getValue(ATTR_REQUIRE_FILTER), "true".equalsIgnoreCase(atts.getValue(ATTR_REQUIRE_OPTIONAL)));
+		} else if (TAG_PROPERTY.equals(qName)) {
+			Property p = new Property(atts.getValue(ATTR_PROPERTY_NAME), atts.getValue(ATTR_PROPERTY_TYPE), atts.getValue(ATTR_PROPERTY_VALUE));
+			if (capabilityBuilder != null)
+				capabilityBuilder.addProperty(p);
+		}
+	}
+
+	@Override
+	public void endElement(String uri, String localName, String qName) throws SAXException {
+		if (TAG_CAPABILITY.equals(qName)) {
+			resourceBuilder.addCapability(capabilityBuilder);
+			capabilityBuilder = null;
+		} else if (TAG_RESOURCE.equals(qName)) {
+			if (!resourceListener.processResource(resourceBuilder.build()))
+				throw new StopParseException();
+			resourceBuilder = null;
+		} else if (TAG_REQUIRE.equals(qName)) {
+			resourceBuilder.addRequire(require);
+			require = null;
+		}
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/Property.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/Property.java
new file mode 100644
index 0000000..1eaaa8a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/Property.java
@@ -0,0 +1,79 @@
+package aQute.lib.deployer.obr;
+
+/**
+ * @immutable
+ * @author Neil Bartlett
+ */
+public class Property {
+	
+	static final String PACKAGE = "package";
+	static final String USES = "uses";
+	static final String VERSION = "version";
+
+	private final String name;
+	private final String type;
+	private final String value;
+
+	public Property(String name, String type, String value) {
+		this.name = name;
+		this.type = type;
+		this.value = value;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getType() {
+		return type;
+	}
+
+	public String getValue() {
+		return value;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("Property [name=").append(name).append(", type=").append(type).append(", value=").append(value).append("]");
+		return builder.toString();
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((value == null) ? 0 : value.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Property other = (Property) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (value == null) {
+			if (other.value != null)
+				return false;
+		} else if (!value.equals(other.value))
+			return false;
+		return true;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/Require.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/Require.java
new file mode 100644
index 0000000..d8d0fbb
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/Require.java
@@ -0,0 +1,73 @@
+package aQute.lib.deployer.obr;
+
+public class Require {
+
+	private final String name;
+	private final String filter;
+	private final boolean optional;
+
+	public Require(String name, String filter, boolean optional) {
+		this.name = name;
+		this.filter = filter;
+		this.optional = optional;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getFilter() {
+		return filter;
+	}
+
+	public boolean isOptional() {
+		return optional;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("Require [");
+		if (name != null)
+			builder.append("name=").append(name).append(", ");
+		if (filter != null)
+			builder.append("filter=").append(filter).append(", ");
+		builder.append("optional=").append(optional).append("]");
+		return builder.toString();
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((filter == null) ? 0 : filter.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + (optional ? 1231 : 1237);
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Require other = (Require) obj;
+		if (filter == null) {
+			if (other.filter != null)
+				return false;
+		} else if (!filter.equals(other.filter))
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (optional != other.optional)
+			return false;
+		return true;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/Resource.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/Resource.java
new file mode 100644
index 0000000..a355326
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/Resource.java
@@ -0,0 +1,240 @@
+package aQute.lib.deployer.obr;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @immutable
+ * @author Neil Bartlett
+ */
+public class Resource {
+	
+	private final String id;
+	private final String presentationName;
+	private final String symbolicName;
+	private final String baseUrl;
+	private final String url;
+	private final String version;
+	private final List<Capability> capabilities;
+	private final List<Require> requires;
+
+	private Resource(String id, String presentationName, String symbolicName, String baseUrl, String url, String version, List<Capability> capabilities, List<Require> requires) {
+		this.id = id;
+		this.presentationName = presentationName;
+		this.symbolicName = symbolicName;
+		this.baseUrl = baseUrl;
+		this.url = url;
+		this.version = version;
+		
+		this.capabilities = capabilities;
+		this.requires = requires;
+	}
+	
+	public static class Builder {
+		private String id;
+		private String presentationName;
+		private String symbolicName;
+		private String baseUrl;
+		private String url;
+		private String version;
+		private final List<Capability> capabilities = new LinkedList<Capability>();
+		private final List<Require> requires = new LinkedList<Require>();
+		
+		public Builder setId(String id) {
+			this.id = id;
+			return this;
+		}
+		public Builder setPresentationName(String presentationName) {
+			this.presentationName = presentationName;
+			return this;
+		}
+		public Builder setSymbolicName(String symbolicName) {
+			this.symbolicName = symbolicName;
+			return this;
+		}
+		public Builder setBaseUrl(String baseUrl) {
+			this.baseUrl = baseUrl;
+			return this;
+		}
+		public Builder setUrl(String url) {
+			this.url = url;
+			return this;
+		}
+		public Builder setVersion(String version) {
+			this.version = version;
+			return this;
+		}
+		public Builder addCapability(Capability capability) {
+			this.capabilities.add(capability);
+			return this;
+		}
+		public Builder addCapability(Capability.Builder capabilityBuilder) {
+			this.capabilities.add(capabilityBuilder.build());
+			return this;
+		}
+		public Builder addRequire(Require require) {
+			this.requires.add(require);
+			return this;
+		}
+		
+		public Resource build() {
+			if (id == null) throw new IllegalStateException("'id' field is not initialised");
+			if (symbolicName == null) throw new IllegalStateException("'symbolicName' field is not initialised");
+			if (url == null) throw new IllegalStateException("'url' field is not initialised");
+			
+			return new Resource(id, presentationName, symbolicName, baseUrl, url, version, Collections.unmodifiableList(capabilities), Collections.unmodifiableList(requires));
+		}
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public String getPresentationName() {
+		return presentationName;
+	}
+
+	public String getSymbolicName() {
+		return symbolicName;
+	}
+	
+	public String getBaseUrl() {
+		return baseUrl;
+	}
+
+	public String getUrl() {
+		return url;
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	public List<Capability> getCapabilities() {
+		return capabilities;
+	}
+	
+	public Capability findPackageCapability(String pkgName) {
+		for (Capability capability : capabilities) {
+			if (CapabilityType.PACKAGE.getTypeName().equals(capability.getName())) {
+				List<Property> props = capability.getProperties();
+				for (Property prop : props) {
+					if (Property.PACKAGE.equals(prop.getName())) {
+						if (pkgName.equals(prop.getValue()))
+							return capability;
+						else
+							break;
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+
+	
+	public List<Require> getRequires() {
+		return requires;
+	}
+	
+	public Require findRequire(String name) {
+		for (Require require : requires) {
+			if (name.equals(require.getName()))
+				return require;
+		}
+		return null;
+	}
+	
+	public Require findPackageRequire(String usesPkgName) {
+		String matchString = String.format("(package=%s)", usesPkgName);
+		
+		for (Require require : requires) {
+			if (CapabilityType.PACKAGE.getTypeName().equals(require.getName())) {
+				String filter = require.getFilter();
+				if (filter.indexOf(matchString) > -1)
+					return require;
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public String toString() {
+		StringBuilder builder = new StringBuilder();
+		builder.append("Resource [id=").append(id)
+				.append(", presentationName=").append(presentationName)
+				.append(", symbolicName=").append(symbolicName)
+				.append(", baseUrl=").append(baseUrl)
+				.append(", url=").append(url).append(", version=")
+				.append(version).append(", capabilities=").append(capabilities)
+				.append("]");
+		return builder.toString();
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((baseUrl == null) ? 0 : baseUrl.hashCode());
+		result = prime * result
+				+ ((capabilities == null) ? 0 : capabilities.hashCode());
+		result = prime * result + ((id == null) ? 0 : id.hashCode());
+		result = prime
+				* result
+				+ ((presentationName == null) ? 0 : presentationName.hashCode());
+		result = prime * result
+				+ ((symbolicName == null) ? 0 : symbolicName.hashCode());
+		result = prime * result + ((url == null) ? 0 : url.hashCode());
+		result = prime * result + ((version == null) ? 0 : version.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Resource other = (Resource) obj;
+		if (baseUrl == null) {
+			if (other.baseUrl != null)
+				return false;
+		} else if (!baseUrl.equals(other.baseUrl))
+			return false;
+		if (capabilities == null) {
+			if (other.capabilities != null)
+				return false;
+		} else if (!capabilities.equals(other.capabilities))
+			return false;
+		if (id == null) {
+			if (other.id != null)
+				return false;
+		} else if (!id.equals(other.id))
+			return false;
+		if (presentationName == null) {
+			if (other.presentationName != null)
+				return false;
+		} else if (!presentationName.equals(other.presentationName))
+			return false;
+		if (symbolicName == null) {
+			if (other.symbolicName != null)
+				return false;
+		} else if (!symbolicName.equals(other.symbolicName))
+			return false;
+		if (url == null) {
+			if (other.url != null)
+				return false;
+		} else if (!url.equals(other.url))
+			return false;
+		if (version == null) {
+			if (other.version != null)
+				return false;
+		} else if (!version.equals(other.version))
+			return false;
+		return true;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/StopParseException.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/StopParseException.java
new file mode 100644
index 0000000..2ca3005
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/StopParseException.java
@@ -0,0 +1,7 @@
+package aQute.lib.deployer.obr;
+
+import org.xml.sax.SAXException;
+
+public class StopParseException extends SAXException {
+	private static final long serialVersionUID = 1L;
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/URLResourceHandle.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/URLResourceHandle.java
new file mode 100644
index 0000000..75b9243
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/URLResourceHandle.java
@@ -0,0 +1,136 @@
+package aQute.lib.deployer.obr;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLEncoder;
+
+import aQute.bnd.service.ResourceHandle;
+
+public class URLResourceHandle implements ResourceHandle {
+	
+	static final String FILE_SCHEME = "file:";
+	static final String HTTP_SCHEME = "http:";
+	
+	final File cacheDir;
+	
+	// The resolved, absolute URL of the resource
+	final URL url;
+	
+	// The local file, if the resource IS a file, otherwise null.
+	final File localFile;
+	
+	// The cached file copy of the resource, if it is remote and has been downloaded.
+	final File cachedFile;
+
+	public URLResourceHandle(String url, String baseUrl, final File cacheDir) throws IOException {
+		this.cacheDir = cacheDir;
+		if (url.startsWith(FILE_SCHEME)) {
+			// File URL may be relative or absolute
+			File file = new File(url.substring(FILE_SCHEME.length()));
+			if (file.isAbsolute()) {
+				this.localFile = file;
+			} else {
+				if (!baseUrl.startsWith(FILE_SCHEME))
+					throw new IllegalArgumentException("Relative file URLs cannot be resolved if the base URL is a non-file URL.");
+				this.localFile = resolveFile(baseUrl.substring(FILE_SCHEME.length()), file.toString());
+			}
+			this.url = localFile.toURI().toURL();
+			if (!localFile.isFile() && !localFile.isDirectory())
+				throw new FileNotFoundException("File URL " + this.url + " points at a non-existing file.");
+			this.cachedFile = null;
+		} else if (url.startsWith(HTTP_SCHEME)) {
+			// HTTP URLs must be absolute
+			this.url = new URL(url);
+			this.localFile = null;
+			this.cachedFile = mapRemoteURL(this.url);
+		} else {
+			// A path with no scheme means resolve relative to the base URL
+			if (baseUrl.startsWith(FILE_SCHEME)) {
+				this.localFile = resolveFile(baseUrl.substring(FILE_SCHEME.length()), url);
+				this.url = localFile.toURI().toURL();
+				this.cachedFile = null;
+			} else {
+				URL base = new URL(baseUrl);
+				this.url = new URL(base, url);
+				this.localFile = null;
+				this.cachedFile = mapRemoteURL(this.url);
+			}
+		}
+	}
+	
+	File resolveFile(String baseFileName, String fileName) {
+		File resolved;
+		
+		File baseFile = new File(baseFileName);
+		if (baseFile.isDirectory())
+			resolved = new File(baseFile, fileName);
+		else if (baseFile.isFile())
+			resolved = new File(baseFile.getParentFile(), fileName);
+		else
+			throw new IllegalArgumentException("Cannot resolve relative to non-existant base file path: " + baseFileName);
+		
+		return resolved;
+	}
+
+	private File mapRemoteURL(URL url) throws UnsupportedEncodingException {
+		String encoded = URLEncoder.encode(url.toString(), "UTF-8");
+		return new File(cacheDir, encoded);
+	}
+
+	public String getName() {
+		return url.toString();
+	}
+
+	public Location getLocation() {
+		Location result;
+		
+		if (localFile != null)
+			result = Location.local;
+		else if (cachedFile.exists())
+			result = Location.remote_cached;
+		else
+			result = Location.remote;
+		
+		return result;
+	}
+
+	public File request() throws IOException {
+		if (localFile != null)
+			return localFile;
+		if (cachedFile == null)
+			throw new IllegalStateException("Invalid URLResourceHandle: both local file and cache file are uninitialised.");
+		
+		if (!cachedFile.exists()) {
+			cacheDir.mkdirs();
+			downloadToFile(url, cachedFile);
+		}
+		
+		return cachedFile;
+	}
+	
+	private static void downloadToFile(URL url, File file) throws IOException {
+		InputStream in = null;
+		OutputStream out = null;
+		try {
+			in = url.openStream();
+			out = new FileOutputStream(file);
+			
+			byte[] buf = new byte[1024];
+			for(;;) {
+				int bytes = in.read(buf, 0, 1024);
+				if (bytes < 0) break;
+				out.write(buf, 0, bytes);
+			}
+		} finally {
+			try { if (in != null) in.close(); } catch (IOException e) {};
+			try { if (out != null) in.close(); } catch (IOException e) {};
+		}
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/obr/UniqueResourceFilter.java b/bundleplugin/src/main/java/aQute/lib/deployer/obr/UniqueResourceFilter.java
new file mode 100644
index 0000000..0ad2cfb
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/obr/UniqueResourceFilter.java
@@ -0,0 +1,54 @@
+package aQute.lib.deployer.obr;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.xml.sax.Attributes;
+
+import aQute.libg.sax.filters.ElementSelectionFilter;
+
+public class UniqueResourceFilter extends ElementSelectionFilter {
+	
+	final Set<String> uris = new HashSet<String>();
+	final Map<String, List<String>> filteredResources = new HashMap<String, List<String>>();
+
+	@Override
+	protected boolean select(int depth, String uri, String localName, String qName, Attributes attribs) {
+		if ("resource".equals(qName)) {
+			String resourceUri = attribs.getValue("uri");
+			if (uris.contains(resourceUri)) {
+				addFilteredBundle(attribs.getValue("symbolicname"), attribs.getValue("version"));
+				return false;
+			}
+			uris.add(resourceUri);
+		}
+		return true;
+	}
+
+	private void addFilteredBundle(String bsn, String version) {
+		List<String> versions = filteredResources.get(bsn);
+		if (versions == null) {
+			versions = new LinkedList<String>();
+			filteredResources.put(bsn, versions);
+		}
+		versions.add(version);
+	}
+	
+	public Collection<String> getFilteredBSNs() {
+		return filteredResources.keySet();
+	}
+	
+	public Collection<String> getFilteredVersions(String bsn) {
+		List<String> list = filteredResources.get(bsn);
+		if (list == null)
+			list = Collections.emptyList();
+		return list;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/filter/Filter.java b/bundleplugin/src/main/java/aQute/lib/filter/Filter.java
new file mode 100644
index 0000000..320c3ac
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/filter/Filter.java
@@ -0,0 +1,353 @@
+/**
+ * Copyright (c) 2000 Gatespace AB. All Rights Reserved.
+ *
+ * Gatespace grants Open Services Gateway Initiative (OSGi) an irrevocable,
+ * perpetual, non-exclusive, worldwide, paid-up right and license to
+ * reproduce, display, perform, prepare and have prepared derivative works
+ * based upon and distribute and sublicense this material and derivative
+ * works thereof as set out in the OSGi MEMBER AGREEMENT as of January 24
+ * 2000, for use in accordance with Section 2.2 of the BY-LAWS of the
+ * OSGi MEMBER AGREEMENT.
+ */
+
+package aQute.lib.filter;
+
+import java.lang.reflect.*;
+import java.math.*;
+import java.util.*;
+
+public class Filter {
+    final char     WILDCARD = 65535;
+
+    final int      EQ       = 0;
+    final int      LE       = 1;
+    final int      GE       = 2;
+    final int      APPROX   = 3;
+
+    private String filter;
+
+    abstract class Query {
+        static final String GARBAGE   = "Trailing garbage";
+        static final String MALFORMED = "Malformed query";
+        static final String EMPTY     = "Empty list";
+        static final String SUBEXPR   = "No subexpression";
+        static final String OPERATOR  = "Undefined operator";
+        static final String TRUNCATED = "Truncated expression";
+        static final String EQUALITY  = "Only equality supported";
+
+        private String      tail;
+
+        boolean match() throws IllegalArgumentException {
+            tail = filter;
+            boolean val = doQuery();
+            if (tail.length() > 0)
+                error(GARBAGE);
+            return val;
+        }
+
+        private boolean doQuery() throws IllegalArgumentException {
+            if (tail.length() < 3 || !prefix("("))
+                error(MALFORMED);
+            boolean val;
+
+            switch (tail.charAt(0)) {
+            case '&':
+                val = doAnd();
+                break;
+            case '|':
+                val = doOr();
+                break;
+            case '!':
+                val = doNot();
+                break;
+            default:
+                val = doSimple();
+                break;
+            }
+
+            if (!prefix(")"))
+                error(MALFORMED);
+            return val;
+        }
+
+        private boolean doAnd() throws IllegalArgumentException {
+            tail = tail.substring(1);
+            boolean val = true;
+            if (!tail.startsWith("("))
+                error(EMPTY);
+            do {
+                if (!doQuery())
+                    val = false;
+            } while (tail.startsWith("("));
+            return val;
+        }
+
+        private boolean doOr() throws IllegalArgumentException {
+            tail = tail.substring(1);
+            boolean val = false;
+            if (!tail.startsWith("("))
+                error(EMPTY);
+            do {
+                if (doQuery())
+                    val = true;
+            } while (tail.startsWith("("));
+            return val;
+        }
+
+        private boolean doNot() throws IllegalArgumentException {
+            tail = tail.substring(1);
+            if (!tail.startsWith("("))
+                error(SUBEXPR);
+            return !doQuery();
+        }
+
+        private boolean doSimple() throws IllegalArgumentException {
+            int op = 0;
+            Object attr = getAttr();
+
+            if (prefix("="))
+                op = EQ;
+            else if (prefix("<="))
+                op = LE;
+            else if (prefix(">="))
+                op = GE;
+            else if (prefix("~="))
+                op = APPROX;
+            else
+                error(OPERATOR);
+
+            return compare(attr, op, getValue());
+        }
+
+        private boolean prefix(String pre) {
+            if (!tail.startsWith(pre))
+                return false;
+            tail = tail.substring(pre.length());
+            return true;
+        }
+
+        private Object getAttr() {
+            int len = tail.length();
+            int ix = 0;
+            label: for (; ix < len; ix++) {
+                switch (tail.charAt(ix)) {
+                case '(':
+                case ')':
+                case '<':
+                case '>':
+                case '=':
+                case '~':
+                case '*':
+                case '\\':
+                    break label;
+                }
+            }
+            String attr = tail.substring(0, ix).toLowerCase();
+            tail = tail.substring(ix);
+            return getProp(attr);
+        }
+
+        abstract Object getProp(String key);
+
+        private String getValue() {
+            StringBuffer sb = new StringBuffer();
+            int len = tail.length();
+            int ix = 0;
+            label: for (; ix < len; ix++) {
+                char c = tail.charAt(ix);
+                switch (c) {
+                case '(':
+                case ')':
+                    break label;
+                case '*':
+                    sb.append(WILDCARD);
+                    break;
+                case '\\':
+                    if (ix == len - 1)
+                        break label;
+                    sb.append(tail.charAt(++ix));
+                    break;
+                default:
+                    sb.append(c);
+                    break;
+                }
+            }
+            tail = tail.substring(ix);
+            return sb.toString();
+        }
+
+        private void error(String m) throws IllegalArgumentException {
+            throw new IllegalArgumentException(m + " " + tail);
+        }
+
+        private boolean compare(Object obj, int op, String s) {
+            if (obj == null)
+                return false;
+            try {
+                Class<?> numClass = obj.getClass();
+                if (numClass == String.class) {
+                    return compareString((String) obj, op, s);
+                } else if (numClass == Character.class) {
+                    return compareString(obj.toString(), op, s);
+                } else if (numClass == Long.class) {
+                    return compareSign(op, Long.valueOf(s)
+                            .compareTo((Long) obj));
+                } else if (numClass == Integer.class) {
+                    return compareSign(op, Integer.valueOf(s).compareTo(
+                            (Integer) obj));
+                } else if (numClass == Short.class) {
+                    return compareSign(op, Short.valueOf(s).compareTo(
+                            (Short) obj));
+                } else if (numClass == Byte.class) {
+                    return compareSign(op, Byte.valueOf(s)
+                            .compareTo((Byte) obj));
+                } else if (numClass == Double.class) {
+                    return compareSign(op, Double.valueOf(s).compareTo(
+                            (Double) obj));
+                } else if (numClass == Float.class) {
+                    return compareSign(op, Float.valueOf(s).compareTo(
+                            (Float) obj));
+                } else if (numClass == Boolean.class) {
+                    if (op != EQ)
+                        return false;
+                    int a = Boolean.valueOf(s).booleanValue() ? 1 : 0;
+                    int b = ((Boolean) obj).booleanValue() ? 1 : 0;
+                    return compareSign(op, a - b);
+                } else if (numClass == BigInteger.class) {
+                    return compareSign(op, new BigInteger(s)
+                            .compareTo((BigInteger) obj));
+                } else if (numClass == BigDecimal.class) {
+                    return compareSign(op, new BigDecimal(s)
+                            .compareTo((BigDecimal) obj));
+                } else if (obj instanceof Collection<?>) {
+                    for (Object x : (Collection<?>) obj)
+                        if (compare(x, op, s))
+                            return true;
+                } else if (numClass.isArray()) {
+                    int len = Array.getLength(obj);
+                    for (int i = 0; i < len; i++)
+                        if (compare(Array.get(obj, i), op, s))
+                            return true;
+                }
+            } catch (Exception e) {
+            }
+            return false;
+        }
+    }
+
+    class DictQuery extends Query {
+        private Dictionary<?,?> dict;
+
+        DictQuery(Dictionary<?,?> dict) {
+            this.dict = dict;
+        }
+
+        Object getProp(String key) {
+            return dict.get(key);
+        }
+    }
+
+    public Filter(String filter) throws IllegalArgumentException {
+        // NYI: Normalize the filter string?
+        this.filter = filter;
+        if (filter == null || filter.length() == 0)
+            throw new IllegalArgumentException("Null query");
+    }
+
+    public boolean match(Dictionary<?,?> dict) {
+        try {
+            return new DictQuery(dict).match();
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+    }
+
+    public String verify() {
+        try {
+            new DictQuery(new Hashtable<Object,Object>()).match();
+        } catch (IllegalArgumentException e) {
+            return e.getMessage();
+        }
+        return null;
+    }
+
+    public String toString() {
+        return filter;
+    }
+
+    public boolean equals(Object obj) {
+        return obj != null && obj instanceof Filter
+                && filter.equals(((Filter) obj).filter);
+    }
+
+    public int hashCode() {
+        return filter.hashCode();
+    }
+
+    boolean compareString(String s1, int op, String s2) {
+        switch (op) {
+        case EQ:
+            return patSubstr(s1, s2);
+        case APPROX:
+            return fixupString(s2).equals(fixupString(s1));
+        default:
+            return compareSign(op, s2.compareTo(s1));
+        }
+    }
+
+    boolean compareSign(int op, int cmp) {
+        switch (op) {
+        case LE:
+            return cmp >= 0;
+        case GE:
+            return cmp <= 0;
+        case EQ:
+            return cmp == 0;
+        default: /* APPROX */
+            return cmp == 0;
+        }
+    }
+
+    String fixupString(String s) {
+        StringBuffer sb = new StringBuffer();
+        int len = s.length();
+        boolean isStart = true;
+        boolean isWhite = false;
+        for (int i = 0; i < len; i++) {
+            char c = s.charAt(i);
+            if (Character.isWhitespace(c)) {
+                isWhite = true;
+            } else {
+                if (!isStart && isWhite)
+                    sb.append(' ');
+                if (Character.isUpperCase(c))
+                    c = Character.toLowerCase(c);
+                sb.append(c);
+                isStart = false;
+                isWhite = false;
+            }
+        }
+        return sb.toString();
+    }
+
+    boolean patSubstr(String s, String pat) {
+        if (s == null)
+            return false;
+        if (pat.length() == 0)
+            return s.length() == 0;
+        if (pat.charAt(0) == WILDCARD) {
+            pat = pat.substring(1);
+            for (;;) {
+                if (patSubstr(s, pat))
+                    return true;
+                if (s.length() == 0)
+                    return false;
+                s = s.substring(1);
+            }
+        } else {
+            if (s.length() == 0 || s.charAt(0) != pat.charAt(0))
+                return false;
+            return patSubstr(s.substring(1), pat.substring(1));
+        }
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/filter/packageinfo b/bundleplugin/src/main/java/aQute/lib/filter/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/filter/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/lib/hex/Hex.java b/bundleplugin/src/main/java/aQute/lib/hex/Hex.java
new file mode 100644
index 0000000..c1ad416
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/hex/Hex.java
@@ -0,0 +1,59 @@
+package aQute.lib.hex;
+
+import java.io.*;
+
+
+/*
+ * Hex converter.
+ * 
+ * TODO Implement string to byte[]
+ */
+public class Hex {
+	byte[]				data;
+	final static char[] HEX = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+	public final static byte[] toByteArray(String string) {
+		string = string.trim();
+		if ( (string.length() & 1) != 0)
+			throw new IllegalArgumentException("a hex string must have an even length");
+
+		byte[]out = new byte[ string.length()/2];
+		for ( int i=0; i < out.length; i++) {
+			out[i] = (byte) (nibble(string.charAt(i*2))<<4 + nibble(string.charAt(i*2+1)));
+		}
+		return out;
+	}
+
+	
+	public final static int nibble( char c) {
+		if (c >= '0' && c <= '9')
+			return c - '0';
+		
+		if ( c>='A' && c<='F')
+			return c - 'A' + 10;
+		if ( c>='a' && c<='f')
+			return c - 'a' + 10;
+		
+		throw new IllegalArgumentException("Not a hex digit: " + c);
+	}
+	
+	public final static String toHexString(byte data[]) {
+		StringBuilder sb = new StringBuilder();
+		try {
+			append(sb,data);
+		} catch (IOException e) {
+			// cannot happen with sb
+		}
+		return sb.toString();
+	}
+	
+	public final static void append( Appendable sb, byte [] data ) throws IOException {
+		for ( int i =0; i<data.length; i++) {
+			sb.append( nibble( data[i] >> 4));
+			sb.append( nibble( data[i]));
+		}
+	}
+
+	private final static char nibble(int i) {	
+		return HEX[i & 0xF];
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/hex/packageinfo b/bundleplugin/src/main/java/aQute/lib/hex/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/hex/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/lib/index/Index.java b/bundleplugin/src/main/java/aQute/lib/index/Index.java
new file mode 100644
index 0000000..35662d0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/index/Index.java
@@ -0,0 +1,352 @@
+package aQute.lib.index;
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.nio.channels.FileChannel.MapMode;
+import java.util.*;
+
+/**
+ * <pre>
+ *   0   ->   0, 122   -> 1
+ *   123 -> 123, 244   -> 2
+ *   245 -> 245, ...
+ * </pre>
+ * 
+ * 
+ */
+public class Index implements Iterable<byte[]> {
+	final static int					LEAF		= 0;
+	final static int					INDEX		= 1;
+
+	final static int					SIGNATURE	= 0;
+	final static int					MAGIC		= 0x494C4458;
+	final static int					KEYSIZE		= 4;
+
+	private FileChannel					file;
+	final int							pageSize	= 4096;
+	final int							keySize;
+	final int							valueSize	= 8;
+	final int							capacity;
+	public Page							root;
+	final LinkedHashMap<Integer, Page>	cache		= new LinkedHashMap<Integer, Index.Page>();
+	final MappedByteBuffer				settings;
+
+	private int							nextPage;
+
+	class Page {
+		final int				TYPE_OFFSET		= 0;
+		final int				COUNT_OFFSET	= 2;
+		final static int		START_OFFSET	= 4;
+		final int				number;
+		boolean					leaf;
+		final MappedByteBuffer	buffer;
+		int						n				= 0;
+		boolean					dirty;
+
+		Page(int number) throws IOException {
+			this.number = number;
+			buffer = file.map(MapMode.READ_WRITE, number * pageSize, pageSize);
+			n = buffer.getShort(COUNT_OFFSET);
+			int type = buffer.getShort(TYPE_OFFSET);
+			leaf = type != 0;
+		}
+
+		Page(int number, boolean leaf) throws IOException {
+			this.number = number;
+			this.leaf = leaf;
+			this.n = 0;
+			buffer = file.map(MapMode.READ_WRITE, number * pageSize, pageSize);
+		}
+
+		Iterator<byte[]> iterator() {
+			return new Iterator<byte[]>() {
+				Iterator<byte[]>	i;
+				int					rover	= 0;
+
+				public byte[] next() {
+					if (leaf) {
+						return k(rover++);
+					}
+
+					return i.next();
+				}
+
+				public boolean hasNext() {
+					try {
+						if (leaf)
+							return rover < n;
+						else {
+							while (i == null || i.hasNext() == false) {
+								int c = (int) c(rover++);
+								i = getPage(c).iterator();
+							}
+							return i.hasNext();
+						}
+					} catch (IOException e) {
+						throw new RuntimeException(e);
+					}
+
+				}
+
+				public void remove() {
+					throw new UnsupportedOperationException();
+				}
+
+			};
+		}
+
+		void write() throws IOException {
+			buffer.putShort(COUNT_OFFSET, (short) n);
+			buffer.put(TYPE_OFFSET, (byte) (leaf ? 1 : 0));
+			buffer.force();
+		}
+
+		int compare(byte[] key, int i) {
+			int index = pos(i);
+			for (int j = 0; j < keySize; j++, index++) {
+				int a = 0;
+				if (j < key.length)
+					a = key[j] & 0xFF;
+
+				int b = buffer.get(index) & 0xFF;
+				if (a == b)
+					continue;
+
+				return a > b ? 1 : -1;
+			}
+			return 0;
+		}
+
+		int pos(int i) {
+			return START_OFFSET + size(i);
+		}
+
+		int size(int n) {
+			return n * (keySize + valueSize);
+		}
+
+		void copyFrom(Page page, int start, int length) {
+			copy(page.buffer, pos(start), buffer, pos(0), size(length));
+		}
+
+		void copy(ByteBuffer src, int srcPos, ByteBuffer dst, int dstPos, int length) {
+			if (srcPos < dstPos) {
+				while (length-- > 0)
+					dst.put(dstPos + length, src.get(srcPos + length));
+
+			} else {
+				while (length-- > 0)
+					dst.put(dstPos++, src.get(srcPos++));
+			}
+		}
+
+		long search(byte[] k) throws Exception {
+			int cmp = 0;
+			int i = n - 1;
+			while (i >= 0 && (cmp = compare(k, i)) < 0)
+				i--;
+
+			if (leaf) {
+				if (cmp != 0)
+					return -1;
+				else
+					return c(i);
+			} else {
+				long value = c(i);
+				Page child = getPage((int) value);
+				return child.search(k);
+			}
+		}
+
+		void insert(byte[] k, long v) throws IOException {
+			if (n == capacity) {
+				int t = capacity / 2;
+				Page left = allocate(leaf);
+				Page right = allocate(leaf);
+				left.copyFrom(this, 0, t);
+				left.n = t;
+				right.copyFrom(this, t, capacity - t);
+				right.n = capacity - t;
+				leaf = false;
+				set(0, left.k(0), left.number);
+				set(1, right.k(0), right.number);
+				n = 2;
+				left.write();
+				right.write();
+			}
+			insertNonFull(k, v);
+		}
+
+		byte[] k(int i) {
+			buffer.position(pos(i));
+			byte[] key = new byte[keySize];
+			buffer.get(key);
+			return key;
+		}
+
+		long c(int i) {
+			if (i < 0) {
+				System.out.println("Arghhh");
+			}
+			int index = pos(i) + keySize;
+			return buffer.getLong(index);
+		}
+
+		void set(int i, byte[] k, long v) {
+			int index = pos(i);
+			for (int j = 0; j < keySize; j++) {
+				byte a = 0;
+				if (j < k.length)
+					a = k[j];
+				buffer.put(index + j, a);
+			}
+			buffer.putLong(index + keySize, v);
+		}
+
+		void insertNonFull(byte[] k, long v) throws IOException {
+			int cmp = 0;
+			int i = n - 1;
+			while (i >= 0 && (cmp = compare(k, i)) < 0)
+				i--;
+
+			if (leaf) {
+				if (cmp != 0) {
+					i++;
+					if (i != n)
+						copy(buffer, pos(i), buffer, pos(i + 1), size(n - i));
+				}
+				set(i, k, v);
+				n++;
+				dirty = true;
+			} else {
+				long value = c(i);
+				Page child = getPage((int) value);
+
+				if (child.n == capacity) {
+					Page left = child;
+					int t = capacity / 2;
+					Page right = allocate(child.leaf);
+					right.copyFrom(left, t, capacity - t);
+					right.n = capacity - t;
+					left.n = t;
+					i++; // place to insert
+					if (i < n) // ok if at end
+						copy(buffer, pos(i), buffer, pos(i + 1), size(n - i));
+					set(i, right.k(0), right.number);
+					n++;
+					assert i < n;
+					child = right.compare(k, 0) >= 0 ? right : left;
+					left.dirty = true;
+					right.dirty = true;
+					this.dirty = true;
+				}
+				child.insertNonFull(k, v);
+			}
+			write();
+		}
+
+		public String toString() {
+			StringBuilder sb = new StringBuilder();
+			try {
+				toString( sb, "");
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+			return sb.toString();
+		}
+		
+		public void toString( StringBuilder sb, String indent ) throws IOException {
+			for (int i = 0; i < n; i++) {
+				sb.append(String.format("%s %02d:%02d %20s %s %d\n", indent, number, i, hex(k(i), 0, 4), leaf ? "==" : "->", c(i)));
+				if (! leaf ) {
+					long c = c(i);
+					Page sub = getPage((int)c);
+					sub.toString(sb,indent+" ");
+				}
+			}
+		}
+
+		private String hex(byte[] k, int i, int j) {
+			StringBuilder sb = new StringBuilder();
+			
+			while ( i < j) {
+				int b = 0xFF & k[i];
+				sb.append(nibble(b>>4));
+				sb.append(nibble(b));
+				i++;
+			}
+			return sb.toString();
+		}
+
+		private char nibble(int i) {
+			i = i & 0xF;
+			return (char) ( i >= 10 ? i + 'A' - 10 : i + '0');
+		}
+
+	}
+
+	public Index(File file, int keySize) throws IOException {
+		capacity = (pageSize - Page.START_OFFSET) / (keySize + valueSize);
+		RandomAccessFile raf = new RandomAccessFile(file, "rw");
+		this.file = raf.getChannel();
+		settings = this.file.map(MapMode.READ_WRITE, 0, pageSize);
+		if (this.file.size() == pageSize) {
+			this.keySize = keySize;
+			settings.putInt(SIGNATURE, MAGIC);
+			settings.putInt(KEYSIZE, keySize);
+			nextPage = 1;
+			root = allocate(true);
+			root.n = 1;
+			root.set(0, new byte[KEYSIZE], 0);
+			root.write();
+		} else {
+			if (settings.getInt(SIGNATURE) != MAGIC)
+				throw new IllegalStateException("No Index file, magic is not " + MAGIC);
+
+			this.keySize = settings.getInt(KEYSIZE);
+			if (keySize != 0 && this.keySize != keySize)
+				throw new IllegalStateException("Invalid key size for Index file. The file is "
+						+ this.keySize + " and was expected to be " + this.keySize);
+
+			root = getPage(1);
+			nextPage = (int) (this.file.size() / pageSize);
+		}
+	}
+
+	public void insert(byte[] k, long v) throws Exception {
+		root.insert(k, v);
+	}
+
+	public long search(byte[] k) throws Exception {
+		return root.search(k);
+	}
+
+	Page allocate(boolean leaf) throws IOException {
+		Page page = new Page(nextPage++, leaf);
+		cache.put(page.number, page);
+		return page;
+	}
+
+	Page getPage(int number) throws IOException {
+		Page page = cache.get(number);
+		if (page == null) {
+			page = new Page(number);
+			cache.put(number, page);
+		}
+		return page;
+	}
+
+	public String toString() {
+		return root.toString();
+	}
+	
+	public void close() throws IOException {
+		file.close();
+		cache.clear();
+	}
+
+	public Iterator<byte[]> iterator() {
+		return root.iterator();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/index/packageinfo b/bundleplugin/src/main/java/aQute/lib/index/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/index/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/lib/io/IO.java b/bundleplugin/src/main/java/aQute/lib/io/IO.java
new file mode 100644
index 0000000..d2cb411
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/io/IO.java
@@ -0,0 +1,162 @@
+package aQute.lib.io;
+
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+import java.util.*;
+
+public class IO {
+	public static void copy(InputStream in, OutputStream out) throws IOException {
+		DataOutputStream dos = new DataOutputStream(out);
+		copy(in, (DataOutput) dos);
+	}
+
+	public static void copy(InputStream in, DataOutput out) throws IOException {
+		byte[] buffer = new byte[10000];
+		try {
+			int size = in.read(buffer);
+			while (size > 0) {
+				out.write(buffer, 0, size);
+				size = in.read(buffer);
+			}
+		} finally {
+			in.close();
+		}
+	}
+
+	public static void copy(InputStream in, ByteBuffer bb) throws IOException {
+		byte[] buffer = new byte[10000];
+		try {
+			int size = in.read(buffer);
+			while (size > 0) {
+				bb.put(buffer, 0, size);
+				size = in.read(buffer);
+			}
+		} finally {
+			in.close();
+		}
+	}
+
+	public static void copy(File a, File b) throws IOException {
+		FileOutputStream out = new FileOutputStream(b);
+		try {
+			copy(new FileInputStream(a), out);
+		} finally {
+			out.close();
+		}
+	}
+
+	public static void copy(InputStream a, File b) throws IOException {
+		FileOutputStream out = new FileOutputStream(b);
+		try {
+			copy(a, out);
+		} finally {
+			out.close();
+		}
+	}
+
+	public static void copy(File a, OutputStream b) throws IOException {
+		copy(new FileInputStream(a), b);
+	}
+
+	public static String collect(File a, String encoding) throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		copy(a, out);
+		return new String(out.toByteArray(), encoding);
+	}
+
+	public static String collect(URL a, String encoding) throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		copy(a.openStream(), out);
+		return new String(out.toByteArray(), encoding);
+	}
+
+	public static String collect(File a) throws IOException {
+		return collect(a, "UTF-8");
+	}
+
+	public static String collect(InputStream a, String encoding) throws IOException {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+		copy(a, out);
+		return new String(out.toByteArray(), encoding);
+	}
+
+	public static String collect(InputStream a) throws IOException {
+		return collect(a, "UTF-8");
+	}
+
+	public static String collect(Reader a) throws IOException {
+		StringWriter sw = new StringWriter();
+		char[] buffer = new char[10000];
+		int size = a.read(buffer);
+		while (size > 0) {
+			sw.write(buffer, 0, size);
+			size = a.read(buffer);
+		}
+		return sw.toString();
+	}
+
+	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);
+		}
+		if (file.equals(".."))
+			return f.getParentFile();
+		else
+			return new File(f, file).getAbsoluteFile();
+	}
+
+	public static void delete(File f) {
+		f = f.getAbsoluteFile();
+		if (f.getParentFile() == null)
+			throw new IllegalArgumentException("Cannot recursively delete root for safety reasons");
+
+		if (f.isDirectory()) {
+			File[] subs = f.listFiles();
+			for (File sub : subs)
+				delete(sub);
+		}
+
+		f.delete();
+	}
+
+	public static void drain(InputStream in) throws IOException {
+		byte[] buffer = new byte[10000];
+		try {
+			int size = in.read(buffer);
+			while (size > 0) {
+				size = in.read(buffer);
+			}
+		} finally {
+			in.close();
+		}
+	}
+
+	public void copy(Collection<?> c, OutputStream out) {
+		PrintStream ps = new PrintStream(out);
+		for (Object o : c) {
+			ps.println(o);
+		}
+		ps.flush();
+	}
+
+	public static Throwable close(Closeable in) {
+		try {
+			in.close();
+			return null;
+		} catch (Throwable e) {
+			return e;
+		}
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/io/LimitedInputStream.java b/bundleplugin/src/main/java/aQute/lib/io/LimitedInputStream.java
new file mode 100644
index 0000000..bf9a21f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/io/LimitedInputStream.java
@@ -0,0 +1,78 @@
+package aQute.lib.io;
+
+import java.io.*;
+
+public class LimitedInputStream extends InputStream {
+
+	final InputStream	in;
+	final int			size;
+	int					left;
+
+	public LimitedInputStream(InputStream in, int size) {
+		this.in = in;
+		this.left = size;
+		this.size = size;
+	}
+
+	@Override public int read() throws IOException {
+		if (left <= 0) {
+			eof();
+			return -1;
+		}
+
+		left--;
+		return in.read();
+	}
+
+	@Override public int available() throws IOException {		
+		return Math.min(left, in.available());
+	}
+
+	@Override public void close() throws IOException {
+		eof();
+		in.close();
+	}
+
+	protected void eof() {
+	}
+
+	@Override public synchronized void mark(int readlimit) {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override public boolean markSupported() {
+		return false;
+	}
+
+	@Override public int read(byte[] b, int off, int len) throws IOException {
+		int min = Math.min(len, left);
+		if (min == 0)
+			return 0;
+
+		int read = in.read(b, off, min);
+		if (read > 0)
+			left -= read;
+		return read;
+	}
+
+	@Override public int read(byte[] b) throws IOException {
+		return read(b,0,b.length);
+	}
+
+	@Override public synchronized void reset() throws IOException {
+		throw new UnsupportedOperationException();
+	}
+
+	@Override public long skip(long n) throws IOException {
+		long count = 0;
+		byte buffer[] = new byte[1024];
+		while ( n > 0 && read() >= 0) {
+			int size = read(buffer);
+			if ( size <= 0)
+				return count;
+			count+=size;
+			n-=size;
+		}
+		return count;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/io/packageinfo b/bundleplugin/src/main/java/aQute/lib/io/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/io/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/lib/jardiff/Diff.java b/bundleplugin/src/main/java/aQute/lib/jardiff/Diff.java
new file mode 100644
index 0000000..b5daec8
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/jardiff/Diff.java
@@ -0,0 +1,152 @@
+package aQute.lib.jardiff;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.lib.osgi.*;
+
+public class Diff {
+
+    /**
+     * Compare two JAR files with each other.
+     * 
+     * @param a
+     * @param b
+     * @param strict
+     * @return
+     * @throws IOException
+     */
+    public Map<String, Object> diff(Jar a, Jar b, boolean strict)
+            throws Exception {
+        Map<String, Object> different = new TreeMap<String, Object>();
+        compareManifest(different, a.getManifest(), b.getManifest(), strict);
+        diff(different, a.getResources().keySet(), b.getResources().keySet());
+
+        Set<String> shared = new HashSet<String>(a.getResources().keySet());
+        shared.retainAll(b.getResources().keySet());
+
+        for (String path : a.getResources().keySet()) {
+            Resource ra = a.getResource(path);
+            Resource rb = a.getResource(path);
+            if (rb != null) {
+                if (ra.getClass() != rb.getClass()) {
+                    different.put(path, "Different types: "
+                            + a.getClass().getName() + " : "
+                            + b.getClass().getName());
+                } else {
+                    if (path.endsWith(".jar")) {
+                        Jar aa = new Jar(path, ra.openInputStream());
+                        Jar bb = new Jar(path, rb.openInputStream());
+                        try {
+                            Map<String, Object> result = diff(aa, bb, strict);
+                            if (!result.isEmpty())
+                                different.put(path, result);
+                        } finally {
+                            aa.close();
+                            bb.close();
+                        }
+                    } else {
+                        String cmp = diff(ra.openInputStream(), rb
+                                .openInputStream());
+                        if (cmp != null)
+                            different.put(path, cmp);
+                    }
+                }
+            }
+        }
+        return different;
+    }
+
+    String diff(InputStream a, InputStream b) throws IOException {
+        int n = 0;
+        int binary = 0;
+        StringBuffer sb = new StringBuffer();
+        while (true) {
+            int ac = a.read();
+            int bc = b.read();
+            if (ac < 0) {
+                if (bc < 0)
+                    return null;
+
+                return "a is smaller";
+            } else if (bc < 0) {
+                return "b is smaller";
+            }
+
+            if (ac != bc) {
+                String s = "Difference at pos: " + n;
+                if (binary == 0 && sb.length() > 5) {
+                    s = s + "Context: " + sb.substring(sb.length() - 5);
+                }
+            }
+
+            if (ac >= ' ' && ac <= '~')
+                sb.append((char) ac);
+            else
+                binary++;
+
+            n++;
+        }
+    }
+
+    void diff(Map<String, Object> different, Set<?> a, Set<?> b) {
+        Set<Object> onlyInA = new HashSet<Object>(a);
+        onlyInA.removeAll(b);
+        Set<Object> onlyInB = new HashSet<Object>(b);
+        onlyInB.removeAll(a);
+
+        for (Object element : onlyInA) {
+            different.put(element.toString(), "a");
+        }
+        for (Object element : onlyInB) {
+            different.put(element.toString(), "b");
+        }
+    }
+
+    public void compareManifest(Map<String, Object> different, Manifest a,
+            Manifest b, boolean strict) {
+        if (a == null || b == null) {
+            different.put("Manifest null", (a == null ? "a=null" : "a exists")
+                    + " " + (b == null ? "b=null" : "b exists"));
+            return;
+        }
+
+        Attributes attrs = a.getMainAttributes();
+        Attributes bttrs = b.getMainAttributes();
+        diff(different, attrs.keySet(), bttrs.keySet());
+        for (Object element : attrs.keySet()) {
+            Attributes.Name name = (Attributes.Name) element;
+            String av = attrs.getValue(name);
+            String bv = bttrs.getValue(name);
+            if (bv != null) {
+                if (!av.equals(bv))
+                    different.put(name.toString(), "M:" + name + ":" + av
+                            + "!=" + bv);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void print(PrintStream pout, Map<String, Object> map, int indent) {
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+            for (int j = 0; j < indent; j++) {
+                pout.print(" ");
+            }
+            String key = entry.getKey();
+            pout.print(key);
+            for (int j = 0; j < 70 - indent - key.length(); j++) {
+                pout.print(" ");
+            }
+            if (entry.getValue() instanceof Map) {
+                pout.println();
+                print(pout, (Map<String, Object>) entry.getValue(), indent + 1);
+            } else
+                pout.println(entry.getValue());
+        }
+    }
+
+    public void close() {
+
+    }
+}
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..ade8497
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/About.java
@@ -0,0 +1,46 @@
+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$
+ */
+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..c3ab0cf
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Analyzer.java
@@ -0,0 +1,2169 @@
+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.Name;
+import java.util.regex.*;
+
+import aQute.bnd.annotation.*;
+import aQute.bnd.service.*;
+import aQute.lib.collections.*;
+import aQute.lib.filter.*;
+import aQute.lib.osgi.Clazz.QUERY;
+import aQute.libg.generics.*;
+import aQute.libg.header.*;
+import aQute.libg.tarjan.*;
+import aQute.libg.version.Version;
+
+public class Analyzer extends Processor {
+
+	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();							// refers
+	// package
+	final Map<String, Set<String>>			uses					= newHashMap();							// package
+	Map<String, Clazz>						classspace;
+	Map<String, Clazz>						importedClassesCache	= newMap();
+	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;
+	String									versionPolicyUses;
+	String									versionPolicyImplemented;
+	boolean									diagnostics				= false;
+	SortedSet<Clazz.JAVA>					formats					= new TreeSet<Clazz.JAVA>();
+	private boolean							inited;
+
+	public Analyzer(Processor parent) {
+		super(parent);
+	}
+
+	public Analyzer() {
+	}
+
+	/**
+	 * Specifically for Maven
+	 * 
+	 * @param properties
+	 *            the properties
+	 */
+
+	public static Properties getManifest(File dirOrJar) throws Exception {
+		Analyzer analyzer = new Analyzer();
+		try {
+			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;
+		} finally {
+			analyzer.close();
+		}
+	}
+
+	/**
+	 * Calculates the data structures for generating a manifest.
+	 * 
+	 * @throws IOException
+	 */
+	public void analyze() throws Exception {
+		if (!analyzed) {
+			analyzed = true;
+			activator = getProperty(BUNDLE_ACTIVATOR);
+			bundleClasspath = parseHeader(getProperty(BUNDLE_CLASSPATH));
+
+			analyzeClasspath();
+
+			classspace = analyzeBundleClasspath(dot, bundleClasspath, contained, referred, uses);
+
+			for (AnalyzerPlugin plugin : getPlugins(AnalyzerPlugin.class)) {
+				if (plugin instanceof AnalyzerPlugin) {
+					AnalyzerPlugin analyzer = (AnalyzerPlugin) plugin;
+					try {
+						boolean reanalyze = analyzer.analyzeJar(this);
+						if (reanalyze)
+							classspace = analyzeBundleClasspath(dot, bundleClasspath, contained,
+									referred, uses);
+					} catch (Exception e) {
+						error("Plugin Analyzer " + analyzer + " throws exception " + e);
+						e.printStackTrace();
+					}
+				}
+			}
+
+			if (activator != null) {
+				// Add the package of the activator to the set
+				// of referred classes. This must be done before we remove
+				// contained set.
+				int n = activator.lastIndexOf('.');
+				if (n > 0) {
+					referred.put(activator.substring(0, n), new LinkedHashMap<String, String>());
+				}
+			}
+
+			referred.keySet().removeAll(contained.keySet());
+			if (referred.containsKey(".")) {
+				error("The default package '.' is not permitted by the Import-Package syntax. \n"
+						+ " This can be caused by compile errors in Eclipse because Eclipse creates \n"
+						+ "valid class files regardless of compile errors.\n"
+						+ "The following package(s) import from the default package "
+						+ getUsedBy("."));
+			}
+
+			Map<String, Map<String, String>> exportInstructions = parseHeader(getProperty(EXPORT_PACKAGE));
+			Map<String, Map<String, String>> additionalExportInstructions = parseHeader(getProperty(EXPORT_CONTENTS));
+			exportInstructions.putAll(additionalExportInstructions);
+			Map<String, Map<String, String>> importInstructions = parseHeader(getImportPackages());
+			Map<String, Map<String, String>> dynamicImports = parseHeader(getProperty(DYNAMICIMPORT_PACKAGE));
+
+			if (dynamicImports != null) {
+				// Remove any dynamic imports from the referred set.
+				referred.keySet().removeAll(dynamicImports.keySet());
+			}
+
+			Map<String, Map<String, String>> superfluous = newHashMap();
+			// Tricky!
+			for (Iterator<String> i = exportInstructions.keySet().iterator(); i.hasNext();) {
+				String instr = i.next();
+				if (!instr.startsWith("!"))
+					superfluous.put(instr, exportInstructions.get(instr));
+			}
+
+			exports = merge("export-package", exportInstructions, contained, superfluous.keySet(),
+					null);
+
+			// disallow export of default package
+			exports.remove(".");
+
+			for (Iterator<Map.Entry<String, Map<String, String>>> i = superfluous.entrySet()
+					.iterator(); i.hasNext();) {
+				// It is possible to mention metadata directories in the export
+				// explicitly, they are then exported and removed from the
+				// warnings. Note that normally metadata directories are not
+				// exported.
+				Map.Entry<String, Map<String, String>> entry = i.next();
+				String pack = entry.getKey();
+				if (isDuplicate(pack))
+					i.remove();
+				else if (isMetaData(pack)) {
+					exports.put(pack, entry.getValue());
+					i.remove();
+				}
+			}
+
+			if (!superfluous.isEmpty()) {
+				warning("Superfluous export-package instructions: " + superfluous.keySet());
+			}
+
+			// Add all exports that do not have an -noimport: directive
+			// to the imports.
+			Map<String, Map<String, String>> referredAndExported = newMap(referred);
+			referredAndExported.putAll(doExportsToImports(exports));
+
+			// match the imports to the referred and exported packages,
+			// merge the info for matching packages
+			Set<String> extra = new TreeSet<String>(importInstructions.keySet());
+			imports = merge("import-package", importInstructions, referredAndExported, extra,
+					ignored);
+
+			// Instructions that have not been used could be superfluous
+			// or if they do not contain wildcards, should be added
+			// as extra imports, the user knows best.
+			for (Iterator<String> i = extra.iterator(); i.hasNext();) {
+				String p = i.next();
+				if (p.startsWith("!") || p.indexOf('*') >= 0 || p.indexOf('?') >= 0
+						|| p.indexOf('[') >= 0) {
+					if (!isResourceOnly() && !(p.equals("*")))
+						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
+			// exports. I.e. look on the classpath
+			augmentExports();
+
+			// 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 isTrue(getProperty(RESOURCEONLY));
+	}
+
+	/**
+	 * 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 Exception {
+		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-" + getBndVersion());
+			main.putValue(BND_LASTMODIFIED, "" + System.currentTimeMillis());
+		}
+
+		String exportHeader = printClauses(exports, 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));
+		} else {
+			main.remove(IMPORT_PACKAGE);
+		}
+
+		temp = newMap(contained);
+		temp.keySet().removeAll(exports.keySet());
+
+		if (!temp.isEmpty())
+			main.putValue(PRIVATE_PACKAGE, printClauses(temp));
+		else
+			main.remove(PRIVATE_PACKAGE);
+
+		if (!ignored.isEmpty()) {
+			main.putValue(IGNORE_PACKAGE, printClauses(ignored));
+		} else {
+			main.remove(IGNORE_PACKAGE);
+		}
+
+		if (bundleClasspath != null && !bundleClasspath.isEmpty())
+			main.putValue(BUNDLE_CLASSPATH, printClauses(bundleClasspath));
+		else
+			main.remove(BUNDLE_CLASSPATH);
+
+		for (Enumeration<?> h = getProperties().propertyNames(); h.hasMoreElements();) {
+			String header = (String) h.nextElement();
+			if (header.trim().length() == 0) {
+				warning("Empty property set with value: " + getProperties().getProperty(header));
+				continue;
+			}
+
+			if (isMissingPlugin(header.trim())) {
+				error("Missing plugin for command %s", header);
+			}
+			if (!Character.isUpperCase(header.charAt(0))) {
+				if (header.charAt(0) == '@')
+					doNameSection(manifest, header);
+				continue;
+			}
+
+			if (header.equals(BUNDLE_CLASSPATH) || header.equals(EXPORT_PACKAGE)
+					|| header.equals(IMPORT_PACKAGE))
+				continue;
+
+			if (header.equalsIgnoreCase("Name")) {
+				error("Your bnd file contains a header called 'Name'. This interferes with the manifest name section.");
+				continue;
+			}
+
+			if (Verifier.HEADER_PATTERN.matcher(header).matches()) {
+				String value = getProperty(header);
+				if (value != null && main.getValue(header) == null) {
+					if (value.trim().length() == 0)
+						main.remove(header);
+					else if (value.trim().equals(EMPTY_HEADER))
+						main.putValue(header, "");
+					else
+						main.putValue(header, value);
+				}
+			} else {
+				// TODO should we report?
+			}
+		}
+
+		//
+		// Calculate the bundle symbolic name if it is
+		// not set.
+		// 1. set
+		// 2. name of properties file (must be != bnd.bnd)
+		// 3. name of directory, which is usualy project name
+		//
+		String bsn = getBsn();
+		if (main.getValue(BUNDLE_SYMBOLICNAME) == null) {
+			main.putValue(BUNDLE_SYMBOLICNAME, bsn);
+		}
+
+		//
+		// Use the same name for the bundle name as BSN when
+		// the bundle name is not set
+		//
+		if (main.getValue(BUNDLE_NAME) == null) {
+			main.putValue(BUNDLE_NAME, bsn);
+		}
+
+		if (main.getValue(BUNDLE_VERSION) == null)
+			main.putValue(BUNDLE_VERSION, "0");
+
+		// Copy old values into new manifest, when they
+		// exist in the old one, but not in the new one
+		merge(manifest, dot.getManifest());
+
+		// Remove all the headers mentioned in -removeheaders
+		Map<String, Map<String, String>> removes = parseHeader(getProperty(REMOVEHEADERS));
+		Set<Instruction> matchers = Instruction.replaceWithInstruction(removes).keySet();
+
+		Collection<Object> toBeRemoved = Instruction.select(matchers, main.keySet());
+		Iterator<Object> i = main.keySet().iterator();
+		while (i.hasNext())
+			if (toBeRemoved.contains(i.next()))
+				i.remove();
+
+		dot.setManifest(manifest);
+		return manifest;
+	}
+
+	/**
+	 * This method is called when the header starts with a @, signifying a name
+	 * section header. The name part is defined by replacing all the @ signs to
+	 * a /, removing the first and the last, and using the last part as header
+	 * name:
+	 * 
+	 * <pre>
+	 * &#064;org@osgi@service@event@Implementation-Title
+	 * </pre>
+	 * 
+	 * This will be the header Implementation-Title in the
+	 * org/osgi/service/event named section.
+	 * 
+	 * @param manifest
+	 * @param header
+	 */
+	private void doNameSection(Manifest manifest, String header) {
+		String path = header.replace('@', '/');
+		int n = path.lastIndexOf('/');
+		// Must succeed because we start with @
+		String name = path.substring(n + 1);
+		// Skip first /
+		path = path.substring(1, n);
+		if (name.length() != 0 && path.length() != 0) {
+			Attributes attrs = manifest.getAttributes(path);
+			if (attrs == null) {
+				attrs = new Attributes();
+				manifest.getEntries().put(path, attrs);
+			}
+			attrs.putValue(name, getProperty(header));
+		} else {
+			warning("Invalid header (starts with @ but does not seem to be for the Name section): %s",
+					header);
+		}
+	}
+
+	/**
+	 * Clear the key part of a header. I.e. remove everything from the first ';'
+	 * 
+	 * @param value
+	 * @return
+	 */
+	public String getBsn() {
+		String value = getProperty(BUNDLE_SYMBOLICNAME);
+		if (value == null) {
+			if (getPropertiesFile() != null)
+				value = getPropertiesFile().getName();
+
+			String projectName = getBase().getName();
+			if (value == null || value.equals("bnd.bnd")) {
+				value = projectName;
+			} else if (value.endsWith(".bnd")) {
+				value = value.substring(0, value.length() - 4);
+				if (!value.startsWith(getBase().getName()))
+					value = projectName + "." + value;
+			}
+		}
+
+		if (value == null)
+			return "untitled";
+
+		int n = value.indexOf(';');
+		if (n > 0)
+			value = value.substring(0, n);
+		return value.trim();
+	}
+
+	public String _bsn(String args[]) {
+		return getBsn();
+	}
+
+	/**
+	 * Calculate an export header solely based on the contents of a JAR file
+	 * 
+	 * @param bundle
+	 *            The jar file to analyze
+	 * @return
+	 */
+	public String calculateExportsFromContents(Jar bundle) {
+		String ddel = "";
+		StringBuffer sb = new StringBuffer();
+		Map<String, Map<String, Resource>> map = bundle.getDirectories();
+		for (Iterator<String> i = map.keySet().iterator(); i.hasNext();) {
+			String directory = (String) i.next();
+			if (directory.equals("META-INF") || directory.startsWith("META-INF/"))
+				continue;
+			if (directory.equals("OSGI-OPT") || directory.startsWith("OSGI-OPT/"))
+				continue;
+			if (directory.equals("/"))
+				continue;
+
+			if (directory.endsWith("/"))
+				directory = directory.substring(0, directory.length() - 1);
+
+			directory = directory.replace('/', '.');
+			sb.append(ddel);
+			sb.append(directory);
+			ddel = ",";
+		}
+		return sb.toString();
+	}
+
+	public Map<String, Map<String, String>> getBundleClasspath() {
+		return bundleClasspath;
+	}
+
+	public Map<String, Map<String, String>> getContained() {
+		return contained;
+	}
+
+	public Map<String, Map<String, String>> getExports() {
+		return exports;
+	}
+
+	public Map<String, Map<String, String>> getImports() {
+		return imports;
+	}
+
+	public Jar getJar() {
+		return dot;
+	}
+
+	public Map<String, Map<String, String>> getReferred() {
+		return referred;
+	}
+
+	/**
+	 * Return the set of unreachable code depending on exports and the bundle
+	 * activator.
+	 * 
+	 * @return
+	 */
+	public Set<String> getUnreachable() {
+		Set<String> unreachable = new HashSet<String>(uses.keySet()); // all
+		for (Iterator<String> r = exports.keySet().iterator(); r.hasNext();) {
+			String packageName = r.next();
+			removeTransitive(packageName, unreachable);
+		}
+		if (activator != null) {
+			String pack = activator.substring(0, activator.lastIndexOf('.'));
+			removeTransitive(pack, unreachable);
+		}
+		return unreachable;
+	}
+
+	public Map<String, Set<String>> getUses() {
+		return uses;
+	}
+
+	/**
+	 * Get the version for this bnd
+	 * 
+	 * @return version or unknown.
+	 */
+	public String getBndVersion() {
+		return getBndInfo("version", "1.42.1");
+	}
+
+	public long getBndLastModified() {
+		String time = getBndInfo("modified", "0");
+		try {
+			return Long.parseLong(time);
+		} catch (Exception e) {
+		}
+		return 0;
+	}
+
+	public String getBndInfo(String key, String defaultValue) {
+		if (bndInfo == null) {
+			bndInfo = new Properties();
+			try {
+				InputStream in = Analyzer.class.getResourceAsStream("bnd.info");
+				if (in != null) {
+					bndInfo.load(in);
+					in.close();
+				}
+			} catch (IOException ioe) {
+				warning("Could not read bnd.info in " + Analyzer.class.getPackage() + ioe);
+			}
+		}
+		return bndInfo.getProperty(key, defaultValue);
+	}
+
+	/**
+	 * Merge the existing manifest with the instructions.
+	 * 
+	 * @param manifest
+	 *            The manifest to merge with
+	 * @throws IOException
+	 */
+	public void mergeManifest(Manifest manifest) throws IOException {
+		if (manifest != null) {
+			Attributes attributes = manifest.getMainAttributes();
+			for (Iterator<Object> i = attributes.keySet().iterator(); i.hasNext();) {
+				Name name = (Name) i.next();
+				String key = name.toString();
+				// Dont want instructions
+				if (key.startsWith("-"))
+					continue;
+
+				if (getProperty(key) == null)
+					setProperty(key, (String) attributes.get(name));
+			}
+		}
+	}
+
+	public void setBase(File file) {
+		super.setBase(file);
+		getProperties().put("project.dir", getBase().getAbsolutePath());
+	}
+
+	/**
+	 * Set the classpath for this analyzer by file.
+	 * 
+	 * @param classpath
+	 * @throws IOException
+	 */
+	public void setClasspath(File[] classpath) throws IOException {
+		List<Jar> list = new ArrayList<Jar>();
+		for (int i = 0; i < classpath.length; i++) {
+			if (classpath[i].exists()) {
+				Jar current = new Jar(classpath[i]);
+				list.add(current);
+			} else {
+				error("Missing file on classpath: %s", 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() {
+		if (inited == false) {
+			inited = true;
+			super.begin();
+
+			updateModified(getBndLastModified(), "bnd last modified");
+			verifyManifestHeadersCase(getProperties());
+
+		}
+	}
+
+	/**
+	 * Check if the given class or interface name is contained in the jar.
+	 * 
+	 * @param interfaceName
+	 * @return
+	 */
+
+	public boolean checkClass(String interfaceName) {
+		String path = Clazz.fqnToPath(interfaceName);
+		if (classspace.containsKey(path))
+			return true;
+
+		if (interfaceName.startsWith("java."))
+			return true;
+
+		if (imports != null && !imports.isEmpty()) {
+			String pack = interfaceName;
+			int n = pack.lastIndexOf('.');
+			if (n > 0)
+				pack = pack.substring(0, n);
+			else
+				pack = ".";
+
+			if (imports.containsKey(pack))
+				return true;
+		}
+		int n = interfaceName.lastIndexOf('.');
+		if (n > 0 && n + 1 < interfaceName.length()
+				&& Character.isUpperCase(interfaceName.charAt(n + 1))) {
+			return checkClass(interfaceName.substring(0, n) + '$' + interfaceName.substring(n + 1));
+		}
+		return false;
+	}
+
+	/**
+	 * 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 manifests
+	 * @throws Exception
+	 */
+	void merge(Manifest result, Manifest old) throws IOException {
+		if (old != null) {
+			for (Iterator<Map.Entry<Object, Object>> e = old.getMainAttributes().entrySet()
+					.iterator(); e.hasNext();) {
+				Map.Entry<Object, Object> entry = e.next();
+				Attributes.Name name = (Attributes.Name) entry.getKey();
+				String value = (String) entry.getValue();
+				if (name.toString().equalsIgnoreCase("Created-By"))
+					name = new Attributes.Name("Originally-Created-By");
+				if (!result.getMainAttributes().containsKey(name))
+					result.getMainAttributes().put(name, value);
+			}
+
+			// do not overwrite existing entries
+			Map<String, Attributes> oldEntries = old.getEntries();
+			Map<String, Attributes> newEntries = result.getEntries();
+			for (Iterator<Map.Entry<String, Attributes>> e = oldEntries.entrySet().iterator(); e
+					.hasNext();) {
+				Map.Entry<String, Attributes> entry = e.next();
+				if (!newEntries.containsKey(entry.getKey())) {
+					newEntries.put(entry.getKey(), entry.getValue());
+				}
+			}
+		}
+	}
+
+	String stem(String name) {
+		int n = name.lastIndexOf('.');
+		if (n > 0)
+			return name.substring(0, n);
+		else
+			return name;
+	}
+
+	/**
+	 * Bnd is case sensitive for the instructions so we better check people are
+	 * not using an invalid case. We do allow this to set headers that should
+	 * not be processed by us but should be used by the framework.
+	 * 
+	 * @param properties
+	 *            Properties to verify.
+	 */
+
+	void verifyManifestHeadersCase(Properties properties) {
+		for (Iterator<Object> i = properties.keySet().iterator(); i.hasNext();) {
+			String header = (String) i.next();
+			for (int j = 0; j < headers.length; j++) {
+				if (!headers[j].equals(header) && headers[j].equalsIgnoreCase(header)) {
+					warning("Using a standard OSGi header with the wrong case (bnd is case sensitive!), using: "
+							+ header + " and expecting: " + headers[j]);
+					break;
+				}
+			}
+		}
+	}
+
+	/**
+	 * We will add all exports to the imports unless there is a -noimport
+	 * directive specified on an export. This directive is skipped for the
+	 * manifest.
+	 * 
+	 * We also remove any version parameter so that augmentImports can do the
+	 * version policy.
+	 * 
+	 * The following method is really tricky and evolved over time. Coming from
+	 * the original background of OSGi, it was a weird idea for me to have a
+	 * public package that should not be substitutable. I was so much convinced
+	 * that this was the right rule that I rücksichtlos imported them all. Alas,
+	 * the real world was more subtle than that. It turns out that it is not a
+	 * good idea to always import. First, there must be a need to import, i.e.
+	 * there must be a contained package that refers to the exported package for
+	 * it to make use importing that package. Second, if an exported package
+	 * refers to an internal package than it should not be imported.
+	 * 
+	 * Additionally, it is necessary to treat the exports in groups. If an
+	 * exported package refers to another exported packages than it must be in
+	 * the same group. A framework can only substitute exports for imports for
+	 * the whole of such a group. WHY????? Not clear anymore ...
+	 * 
+	 */
+	/**
+	 * I could no longer argue why the groups are needed :-( See what happens
+	 * ... The getGroups calculated the groups and then removed the imports from
+	 * there. Now we only remove imports that have internal references. Using
+	 * internal code for an exported package means that a bundle cannot import
+	 * that package from elsewhere because its assumptions might be violated if
+	 * it receives a substitution. //
+	 */
+	Map<String, Map<String, String>> doExportsToImports(Map<String, Map<String, String>> exports) {
+
+		// private packages = contained - exported.
+		Set<String> privatePackages = new HashSet<String>(contained.keySet());
+		privatePackages.removeAll(exports.keySet());
+
+		// private references = ∀ p : private packages | uses(p)
+		Set<String> privateReferences = newSet();
+		for (String p : privatePackages) {
+			Set<String> uses = this.uses.get(p);
+			if (uses != null)
+				privateReferences.addAll(uses);
+		}
+
+		// Assume we are going to export all exported packages
+		Set<String> toBeImported = new HashSet<String>(exports.keySet());
+
+		// Remove packages that are not referenced privately
+		toBeImported.retainAll(privateReferences);
+
+		// Not necessary to import anything that is already
+		// imported in the Import-Package statement.
+		if (imports != null)
+			toBeImported.removeAll(imports.keySet());
+
+		// Remove exported packages that are referring to
+		// private packages.
+		// Each exported package has a uses clause. We just use
+		// the used packages for each exported package to find out
+		// if it refers to an internal package.
+		//
+
+		for (Iterator<String> i = toBeImported.iterator(); i.hasNext();) {
+			Set<String> usedByExportedPackage = this.uses.get(i.next());
+			for (String privatePackage : privatePackages) {
+				if (usedByExportedPackage.contains(privatePackage)) {
+					i.remove();
+					break;
+				}
+			}
+		}
+
+		// Clean up attributes and generate result map
+		Map<String, Map<String, String>> result = newMap();
+		for (Iterator<String> i = toBeImported.iterator(); i.hasNext();) {
+			String ep = i.next();
+			Map<String, String> parameters = exports.get(ep);
+
+			String noimport = parameters.get(NO_IMPORT_DIRECTIVE);
+			if (noimport != null && noimport.equalsIgnoreCase("true"))
+				continue;
+
+			// // we can't substitute when there is no version
+			// String version = parameters.get(VERSION_ATTRIBUTE);
+			// if (version == null) {
+			// if (isPedantic())
+			// warning(
+			// "Cannot automatically import exported package %s because it has no version defined",
+			// ep);
+			// continue;
+			// }
+
+			parameters = newMap(parameters);
+			parameters.remove(VERSION_ATTRIBUTE);
+			result.put(ep, parameters);
+		}
+		return result;
+	}
+
+	private <T> boolean intersects(Collection<T> aa, Collection<T> bb) {
+		if (aa.equals(bb))
+			return true;
+
+		if (aa.size() > bb.size())
+			return intersects(bb, aa);
+
+		for (T t : aa)
+			if (bb.contains(t))
+				return true;
+		return false;
+	}
+
+	public boolean referred(String packageName) {
+		// return true;
+		for (Map.Entry<String, Set<String>> contained : uses.entrySet()) {
+			if (!contained.getKey().equals(packageName)) {
+				if (contained.getValue().contains(packageName))
+					return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Create the imports/exports by parsing
+	 * 
+	 * @throws IOException
+	 */
+	void analyzeClasspath() throws Exception {
+		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();
+					try {
+						String version = parsePackageInfo(in);
+						setPackageInfo(dir, VERSION_ATTRIBUTE, version);
+					} finally {
+						in.close();
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * 
+	 * @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) {
+						for (Map.Entry<String, Map<String, String>> entry : exported.entrySet()) {
+							if (!classpathExports.containsKey(entry.getKey())) {
+								classpathExports.put(entry.getKey(), entry.getValue());
+							}
+						}
+					}
+				}
+			}
+		} 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));
+				}
+
+				fixupAttributes(importAttributes);
+				removeAttributes(importAttributes);
+
+			} finally {
+				unsetProperty(CURRENT_PACKAGE);
+			}
+		}
+	}
+
+	/**
+	 * Provide any macro substitutions and versions for exported packages.
+	 */
+
+	void augmentExports() {
+		for (String packageName : exports.keySet()) {
+			setProperty(CURRENT_PACKAGE, packageName);
+			try {
+				Map<String, String> attributes = exports.get(packageName);
+				Map<String, String> exporterAttributes = classpathExports.get(packageName);
+				if (exporterAttributes == null)
+					continue;
+
+				for (Map.Entry<String, String> entry : exporterAttributes.entrySet()) {
+					String key = entry.getKey();
+					if (key.equalsIgnoreCase(SPECIFICATION_VERSION))
+						key = VERSION_ATTRIBUTE;
+					if (!key.endsWith(":") && !attributes.containsKey(key)) {
+						attributes.put(key, entry.getValue());
+					}
+				}
+
+				fixupAttributes(attributes);
+				removeAttributes(attributes);
+
+			} finally {
+				unsetProperty(CURRENT_PACKAGE);
+			}
+		}
+	}
+
+	/**
+	 * Fixup Attributes
+	 * 
+	 * Execute any macros on an export and
+	 */
+
+	void fixupAttributes(Map<String, String> attributes) {
+		// Convert any attribute values that have macros.
+		for (String key : attributes.keySet()) {
+			String value = attributes.get(key);
+			if (value.indexOf('$') >= 0) {
+				value = getReplacer().process(value);
+				attributes.put(key, value);
+			}
+		}
+
+	}
+
+	/*
+	 * Remove the attributes mentioned in the REMOVE_ATTRIBUTE_DIRECTIVE.
+	 */
+
+	void removeAttributes(Map<String, String> attributes) {
+		// 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 = attributes.remove(REMOVE_ATTRIBUTE_DIRECTIVE);
+		Instruction removeInstr = null;
+
+		if (remove != null)
+			removeInstr = Instruction.getPattern(remove);
+
+		for (Iterator<Map.Entry<String, String>> i = attributes.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 ...
+			}
+		}
+	}
+
+	/**
+	 * 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_ATTRIBUTE);
+		if (exportVersion == null)
+			return;
+
+		exportVersion = cleanupVersion(exportVersion);
+		String importRange = currentAttributes.get(VERSION_ATTRIBUTE);
+		boolean impl = isTrue(currentAttributes.get(PROVIDE_DIRECTIVE));
+		try {
+			setProperty("@", exportVersion);
+
+			if (importRange != null) {
+				importRange = cleanupVersion(importRange);
+				importRange = getReplacer().process(importRange);
+			} else
+				importRange = getVersionPolicy(impl);
+
+		} finally {
+			unsetProperty("@");
+		}
+		// See if we can borrow the version
+		// we must 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_ATTRIBUTE, importRange);
+	}
+
+	/**
+	 * Calculate a version from a version policy.
+	 * 
+	 * @param version
+	 *            The actual exported version
+	 * @param impl
+	 *            true for implementations and false for clients
+	 */
+
+	String calculateVersionRange(String version, boolean impl) {
+		setProperty("@", version);
+		try {
+			return getVersionPolicy(impl);
+		} finally {
+			unsetProperty("@");
+		}
+	}
+
+	/**
+	 * Add the uses clauses. This method iterates over the exports and cal
+	 * 
+	 * @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 {
+				doUses(packageName, exports, uses, imports);
+			} finally {
+				unsetProperty(CURRENT_PACKAGE);
+			}
+
+		}
+	}
+
+	/**
+	 * @param packageName
+	 * @param exports
+	 * @param uses
+	 * @param imports
+	 */
+	protected void doUses(String packageName, Map<String, Map<String, String>> exports,
+			Map<String, Set<String>> uses, Map<String, Map<String, String>> imports) {
+		Map<String, String> clause = exports.get(packageName);
+
+		// Check if someone already set the uses: directive
+		String override = clause.get(USES_DIRECTIVE);
+		if (override == null)
+			override = USES_USES;
+
+		// Get the used packages
+		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_DIRECTIVE, override);
+			}
+		}
+	}
+
+	/**
+	 * 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);
+			}
+			if (!map.containsKey(VERSION_ATTRIBUTE))
+				map.put(key, value);
+			else if (!map.get(VERSION_ATTRIBUTE).equals(value)) {
+				// System.out.println("duplicate version info for " + dir + " "
+				// + value + " and " + map.get(VERSION_ATTRIBUTE));
+			}
+		}
+	}
+
+	public void close() {
+		if (diagnostics) {
+			PrintStream out = System.out;
+			out.printf("Current directory            : %s\n", new File("").getAbsolutePath());
+			out.println("Classpath used");
+			for (Jar jar : getClasspath()) {
+				out.printf("File                                : %s\n", jar.getSource());
+				out.printf("File abs path                       : %s\n", jar.getSource()
+						.getAbsolutePath());
+				out.printf("Name                                : %s\n", jar.getName());
+				Map<String, Map<String, Resource>> dirs = jar.getDirectories();
+				for (Map.Entry<String, Map<String, Resource>> entry : dirs.entrySet()) {
+					Map<String, Resource> dir = entry.getValue();
+					String name = entry.getKey().replace('/', '.');
+					if (dir != null) {
+						out.printf("                                      %-30s %d\n", name,
+								dir.size());
+					} else {
+						out.printf("                                      %-30s <<empty>>\n", name);
+					}
+				}
+			}
+		}
+
+		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);
+					else
+						warning("Cannot find entry on -classpath: %s", s);
+				}
+		}
+		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;
+	}
+
+	protected 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 Exception {
+		Map<String, Clazz> classSpace = new HashMap<String, Clazz>();
+		Set<String> hide = Create.set();
+		boolean containsDirectory = false;
+		
+		for (String path : bundleClasspath.keySet()) {
+			if ( dot.getDirectories().containsKey(path)) {
+				containsDirectory = true;
+				break;
+			}
+		}
+		
+		if (bundleClasspath.isEmpty()) {
+			analyzeJar(dot, "", classSpace, contained, referred, uses, hide, true);
+		} else {
+			for (String path : bundleClasspath.keySet()) {
+				Map<String, String> info = bundleClasspath.get(path);
+
+				if (path.equals(".")) {
+					analyzeJar(dot, "", classSpace, contained, referred, uses, hide, !containsDirectory);
+					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, hide, true);
+					} catch (Exception e) {
+						warning("Invalid bundle classpath entry: " + path + " " + e);
+					}
+				} else {
+					if (dot.getDirectories().containsKey(path)) {
+						// if directories are used, we should not have dot as we
+						// would have the classes in these directories on the
+						// class
+						// path twice.
+						if (bundleClasspath.containsKey("."))
+							warning("Bundle-ClassPath uses a directory '%s' as well as '.', this implies the directory is seen \n"
+									+ "twice by the class loader. bnd assumes that the classes are only "
+									+ "loaded from '%s'. It is better to unroll the directory to create a flat bundle.",
+									path, path);
+						analyzeJar(dot, Processor.appendPath(path) + "/", classSpace, contained,
+								referred, uses, hide,true);
+					} else {
+						if (!"optional".equals(info.get(RESOLUTION_DIRECTIVE)))
+							warning("No sub JAR or directory " + path);
+					}
+				}
+			}
+
+			for (Clazz c : classSpace.values()) {
+				formats.add(c.getFormat());
+			}
+		}
+		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, Set<String> hide, boolean reportWrongPath) throws Exception {
+
+		next: for (String path : jar.getResources().keySet()) {
+			if (path.startsWith(prefix) /* && !hide.contains(path) */) {
+				hide.add(path);
+				String relativePath = path.substring(prefix.length());
+
+				// // TODO this check (and the whole hide) is likely redundant
+				// // it only protects against repeated checks for non-class
+				// // bundle resources, but should not affect results otherwise.
+				// if (!hide.add(relativePath)) {
+				// continue;
+				// }
+
+				// Check if we'd already had this one.
+				// Notice that we're flattening the space because
+				// this is what class loaders do.
+				if (classSpace.containsKey(relativePath))
+					continue;
+
+				String pack = getPackage(relativePath);
+
+				if (pack != null && !contained.containsKey(pack)) {
+					// For each package we encounter for the first
+					// time
+					if (!isMetaData(relativePath)) {
+
+						Map<String, String> info = newMap();
+						contained.put(pack, info);
+
+						Resource pinfo = jar.getResource(prefix + pack.replace('.', '/')
+								+ "/packageinfo");
+						if (pinfo != null) {
+							InputStream in = pinfo.openInputStream();
+							String version;
+							try {
+								version = parsePackageInfo(in);
+							} finally {
+								in.close();
+							}
+							if (version != null)
+								info.put(VERSION_ATTRIBUTE, version);
+						}
+					}
+				}
+
+				// Check class resources, we need to analyze them
+				if (path.endsWith(".class")) {
+					Resource resource = jar.getResource(path);
+					Clazz clazz;
+
+					try {
+						InputStream in = resource.openInputStream();
+						clazz = new Clazz(relativePath, resource);
+						try {
+							// Check if we have a package-info
+							if (relativePath.endsWith("/package-info.class")) {
+								// package-info can contain an Export annotation
+								Map<String, String> info = contained.get(pack);
+								parsePackageInfoClass(clazz, info);
+							} else {
+								// Otherwise we just parse it simply
+								clazz.parseClassFile();
+							}
+						} finally {
+							in.close();
+						}
+					} catch (Throwable e) {
+						error("Invalid class file: " + relativePath, e);
+						e.printStackTrace();
+						continue next;
+					}
+
+					String calculatedPath = clazz.getClassName() + ".class";
+					if (!calculatedPath.equals(relativePath)) {
+						if (!isNoBundle() && reportWrongPath) {
+							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);
+
+					// Look at the referred packages
+					// and copy them to our baseline
+					for (String p : clazz.getReferred()) {
+						Map<String, String> attrs = referred.get(p);
+						if (attrs == null) {
+							attrs = newMap();
+							referred.put(p, attrs);
+						}
+					}
+
+					// 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());
+					t.remove(pack);
+				}
+			}
+		}
+	}
+
+	static Pattern	OBJECT_REFERENCE	= Pattern.compile("L([^/]+/)*([^;]+);");
+
+	private void parsePackageInfoClass(final Clazz clazz, final Map<String, String> info)
+			throws Exception {
+		clazz.parseClassFileWithCollector(new ClassDataCollector() {
+			@Override public void annotation(Annotation a) {
+				if (a.name.equals(Clazz.toDescriptor(aQute.bnd.annotation.Version.class))) {
+
+					// Check version
+					String version = a.get("value");
+					if (!info.containsKey(Constants.VERSION_ATTRIBUTE)) {
+						if (version != null) {
+							version = getReplacer().process(version);
+							if (Verifier.VERSION.matcher(version).matches())
+								info.put(VERSION_ATTRIBUTE, version);
+							else
+								error("Export annotatio in %s has invalid version info: %s", clazz,
+										version);
+						}
+					} else {
+						// Verify this matches with packageinfo
+						String presentVersion = info.get(VERSION_ATTRIBUTE);
+						try {
+							Version av = new Version(presentVersion);
+							Version bv = new Version(version);
+							if (!av.equals(bv)) {
+								error("Version from annotation for %s differs with packageinfo or Manifest",
+										Clazz.getPackage(clazz.className));
+							}
+						} catch (Exception e) {
+							// Ignore
+						}
+					}
+				} else if (a.name.equals(Clazz.toDescriptor(Export.class))) {
+
+					// Check mandatory attributes
+					Map<String, String> attrs = doAttrbutes((Object[]) a.get(Export.MANDATORY),
+							clazz, getReplacer());
+					if (!attrs.isEmpty()) {
+						info.putAll(attrs);
+						info.put(MANDATORY_DIRECTIVE, Processor.join(attrs.keySet()));
+					}
+
+					// Check optional attributes
+					attrs = doAttrbutes((Object[]) a.get(Export.OPTIONAL), clazz, getReplacer());
+					if (!attrs.isEmpty()) {
+						info.putAll(attrs);
+					}
+
+					// Check Included classes
+					Object[] included = a.get(Export.INCLUDE);
+					if (included != null && included.length > 0) {
+						StringBuilder sb = new StringBuilder();
+						String del = "";
+						for (Object i : included) {
+							Matcher m = OBJECT_REFERENCE.matcher((String) i);
+							if (m.matches()) {
+								sb.append(del);
+								sb.append(m.group(2));
+								del = ",";
+							}
+						}
+						info.put(INCLUDE_DIRECTIVE, sb.toString());
+					}
+
+					// Check Excluded classes
+					Object[] excluded = a.get(Export.EXCLUDE);
+					if (excluded != null && excluded.length > 0) {
+						StringBuilder sb = new StringBuilder();
+						String del = "";
+						for (Object i : excluded) {
+							Matcher m = OBJECT_REFERENCE.matcher((String) i);
+							if (m.matches()) {
+								sb.append(del);
+								sb.append(m.group(2));
+								del = ",";
+							}
+						}
+						info.put(EXCLUDE_DIRECTIVE, sb.toString());
+					}
+
+					// Check Uses
+					Object[] uses = a.get(Export.USES);
+					if (uses != null && uses.length > 0) {
+						String old = info.get(USES_DIRECTIVE);
+						if (old == null)
+							old = "";
+						StringBuilder sb = new StringBuilder(old);
+						String del = sb.length() == 0 ? "" : ",";
+
+						for (Object use : uses) {
+							sb.append(del);
+							sb.append(use);
+							del = ",";
+						}
+						info.put(USES_DIRECTIVE, sb.toString());
+					}
+				}
+			}
+
+		});
+	}
+
+	/**
+	 * 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) {
+		Matcher m = Verifier.VERSIONRANGE.matcher(version);
+
+		if (m.matches()) {
+			return version;
+		}
+
+		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 = removeLeadingZeroes(m.group(1));
+				String minor = removeLeadingZeroes(m.group(3));
+				String micro = removeLeadingZeroes(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;
+	}
+
+	private static String removeLeadingZeroes(String group) {
+		int n = 0;
+		while (group != null && n < group.length() - 1 && group.charAt(n) == '0')
+			n++;
+		if (n == 0)
+			return group;
+
+		return group.substring(n);
+	}
+
+	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;
+	}
+
+	final static String	DEFAULT_PROVIDER_POLICY	= "${range;[==,=+)}";
+	final static String	DEFAULT_CONSUMER_POLICY	= "${range;[==,+)}";
+
+	@SuppressWarnings("deprecation") public String getVersionPolicy(boolean implemented) {
+		if (implemented) {
+			String s = getProperty(PROVIDER_POLICY);
+			if (s != null)
+				return s;
+
+			s = getProperty(VERSIONPOLICY_IMPL);
+			if (s != null)
+				return s;
+
+			return getProperty(VERSIONPOLICY, DEFAULT_PROVIDER_POLICY);
+		} else {
+			String s = getProperty(CONSUMER_POLICY);
+			if (s != null)
+				return s;
+
+			s = getProperty(VERSIONPOLICY_USES);
+			if (s != null)
+				return s;
+
+			return getProperty(VERSIONPOLICY, DEFAULT_CONSUMER_POLICY);
+		}
+		// String vp = implemented ? getProperty(VERSIONPOLICY_IMPL) :
+		// getProperty(VERSIONPOLICY_USES);
+		//
+		// if (vp != null)
+		// return vp;
+		//
+		// if (implemented)
+		// return getProperty(VERSIONPOLICY_IMPL, "{$range;[==,=+}");
+		// else
+		// return getProperty(VERSIONPOLICY, "${range;[==,+)}");
+	}
+
+	/**
+	 * 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) throws Exception {
+		// Macro.verifyCommand(args, _classesHelp, new
+		// Pattern[]{null,Pattern.compile("(implementing|implements|extending|extends|importing|imports|any)"),
+		// null}, 3,3);
+
+		Collection<Clazz> matched = getClasses(args);
+		if (matched.isEmpty())
+			return "";
+
+		return join(matched);
+	}
+
+	public Collection<Clazz> getClasses(String... args) throws Exception {
+
+		Set<Clazz> matched = new HashSet<Clazz>(classspace.values());
+		for (int i = 1; i < args.length; i++) {
+			if (args.length < i + 1)
+				throw new IllegalArgumentException(
+						"${classes} macro must have odd number of arguments. " + _classesHelp);
+
+			String typeName = args[i];
+			if (typeName.equalsIgnoreCase("extending"))
+				typeName = "extends";
+			else if (typeName.equalsIgnoreCase("importing"))
+				typeName = "imports";
+			else if (typeName.equalsIgnoreCase("implementing"))
+				typeName = "implements";
+
+			Clazz.QUERY type = Clazz.QUERY.valueOf(typeName.toUpperCase());
+
+			if (type == null)
+				throw new IllegalArgumentException("${classes} has invalid type: " + typeName
+						+ ". " + _classesHelp);
+
+			Instruction instr = null;
+			if (Clazz.HAS_ARGUMENT.contains(type)) {
+				StringBuilder sb = new StringBuilder();
+				String s = args[++i];
+				if (type == QUERY.ANNOTATION) {
+					// Annotations use the descriptor format ...
+					// But at least they're always an object
+					sb.append("L");
+					for (int ci = 0; ci < s.length(); ci++) {
+						char c = s.charAt(ci);
+						if (c == '.')
+							sb.append("/");
+						else
+							sb.append(c);
+					}
+					sb.append(';');
+				} else {
+					// 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. We also have to take into account
+					// that some classes are nested and use $ for separator
+					for (int ci = 0; ci < s.length(); ci++) {
+						char c = s.charAt(ci);
+						if (c == '.')
+							sb.append("(/|\\$)");
+						else
+							sb.append(c);
+					}
+				}
+				instr = Instruction.getPattern(sb.toString());
+			}
+			for (Iterator<Clazz> c = matched.iterator(); c.hasNext();) {
+				Clazz clazz = c.next();
+				if (!clazz.is(type, instr, this)) {
+					c.remove();
+				}
+			}
+		}
+		return 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;
+	}
+
+	/**
+	 * Locate a resource on the class path.
+	 * 
+	 * @param path
+	 *            Path of the reosurce
+	 * @return A resource or <code>null</code>
+	 */
+	public Resource findResource(String path) {
+		for (Jar entry : getClasspath()) {
+			Resource r = entry.getResource(path);
+			if (r != null)
+				return r;
+		}
+		return null;
+	}
+
+	/**
+	 * Find a clazz on the class path. This class has been parsed.
+	 * 
+	 * @param path
+	 * @return
+	 */
+	public Clazz findClass(String path) throws Exception {
+		Clazz c = classspace.get(path);
+		if (c != null)
+			return c;
+
+		c = importedClassesCache.get(path);
+		if (c != null)
+			return c;
+
+		Resource r = findResource(path);
+		if (r != null) {
+			c = new Clazz(path, r);
+			c.parseClassFile();
+			importedClassesCache.put(path, c);
+		}
+		return c;
+	}
+
+	/**
+	 * Answer the bundle version.
+	 * 
+	 * @return
+	 */
+	public String getVersion() {
+		String version = getProperty(BUNDLE_VERSION);
+		if (version == null)
+			version = "0.0.0";
+		return version;
+	}
+
+	public boolean isNoBundle() {
+		return isTrue(getProperty(RESOURCEONLY)) || isTrue(getProperty(NOMANIFEST));
+	}
+
+	public void referTo(String impl) {
+		String pack = Clazz.getPackage(impl);
+		if (!referred.containsKey(pack))
+			referred.put(pack, new LinkedHashMap<String, String>());
+	}
+
+	/**
+	 * Calculate the groups inside the bundle. A group consists of packages that
+	 * have a reference to each other.
+	 */
+
+	public MultiMap<Set<String>, String> getGroups() {
+		MultiMap<String, String> map = new MultiMap<String, String>();
+		Set<String> keys = uses.keySet();
+
+		for (Map.Entry<String, Set<String>> entry : uses.entrySet()) {
+			Set<String> newSet = new HashSet<String>(entry.getValue());
+			newSet.retainAll(keys);
+			map.put(entry.getKey(), newSet);
+		}
+
+		// Calculate strongly connected packages
+		Set<Set<String>> scc = Tarjan.tarjan(map);
+
+		MultiMap<Set<String>, String> grouped = new MultiMap<Set<String>, String>();
+		for (Set<String> group : scc) {
+			for (String p : group) {
+				grouped.addAll(group, uses.get(p));
+			}
+		}
+		return grouped;
+	}
+
+	/**
+	 * Ensure that we are running on the correct bnd.
+	 */
+	void doRequireBnd() {
+		Map<String, String> require = OSGiHeader.parseProperties(getProperty(REQUIRE_BND));
+		if (require == null || require.isEmpty())
+			return;
+
+		Hashtable<String, String> map = new Hashtable<String, String>();
+		map.put(Constants.VERSION_FILTER, getBndVersion());
+
+		for (String filter : require.keySet()) {
+			try {
+				Filter f = new Filter(filter);
+				if (f.match(map))
+					continue;
+				error("%s fails %s", REQUIRE_BND, require.get(filter));
+			} catch (Exception t) {
+				error("%s with value %s throws exception", t, REQUIRE_BND, require);
+			}
+		}
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Annotation.java b/bundleplugin/src/main/java/aQute/lib/osgi/Annotation.java
new file mode 100644
index 0000000..d0e6b12
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Annotation.java
@@ -0,0 +1,59 @@
+package aQute.lib.osgi;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import aQute.bnd.annotation.metatype.*;
+
+public class Annotation {
+	String				name;
+	Map<String, Object>	elements;
+	ElementType			member;
+	RetentionPolicy		policy;
+
+	public Annotation(String name, Map<String, Object> elements, ElementType member,
+			RetentionPolicy policy) {
+		this.name = name;
+		if ( elements == null)
+			this.elements = Collections.emptyMap();
+		else
+			this.elements = elements;
+		this.member = member;
+		this.policy = policy;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String toString() {
+		return name + ":" + member + ":" + policy + ":" + elements;
+	}
+
+	@SuppressWarnings("unchecked") public <T> T get(String string) {
+		if (elements == null)
+			return null;
+
+		return (T) elements.get(string);
+	}
+
+	public <T> void put(String string, Object v) {
+		if (elements == null)
+			return;
+
+		elements.put(string, v);
+	}
+
+	@SuppressWarnings("unchecked") public <T extends java.lang.annotation.Annotation> T getAnnotation() throws Exception {
+		String cname = Clazz.objectDescriptorToFQN(name);
+		Class<T> c = (Class<T>) getClass().getClassLoader().loadClass(cname);
+		return getAnnotation(c);
+	}
+	public <T extends java.lang.annotation.Annotation> T getAnnotation(Class<T> c)
+			throws Exception {
+		String cname = Clazz.objectDescriptorToFQN(name);
+		if ( ! c.getName().equals(cname))
+			return null;
+		return Configurable.createConfigurable(c, elements );
+	}
+}
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..903aaf7
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
@@ -0,0 +1,1217 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+import java.util.zip.*;
+
+import aQute.bnd.component.*;
+import aQute.bnd.make.*;
+import aQute.bnd.make.component.*;
+import aQute.bnd.make.metatype.*;
+import aQute.bnd.maven.*;
+import aQute.bnd.service.*;
+
+/**
+ * Include-Resource: ( [name '=' ] file )+
+ * 
+ * Private-Package: package-decl ( ',' package-decl )*
+ * 
+ * Export-Package: package-decl ( ',' package-decl )*
+ * 
+ * Import-Package: package-decl ( ',' package-decl )*
+ * 
+ * @version $Revision$
+ */
+public class Builder extends Analyzer {
+	Pattern						xdoNotCopy			= null;
+	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>();
+
+	Make						make				= new Make(this);
+
+	public Builder(Processor parent) {
+		super(parent);
+	}
+
+	public Builder() {
+	}
+
+	public Jar build() throws Exception {
+		init();
+		if (isTrue(getProperty(NOBUNDLES)))
+			return null;
+
+		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);
+		dot = doWab(dot);
+
+		// NEW!
+		// Check if we override the calculation of the
+		// manifest. We still need to calculated it because
+		// we need to have analyzed the classpath.
+
+		Manifest manifest = calcManifest();
+
+		String mf = getProperty(MANIFEST);
+		if (mf != null) {
+			File mff = getFile(mf);
+			if (mff.isFile()) {
+				try {
+					InputStream in = new FileInputStream(mff);
+					manifest = new Manifest(in);
+					in.close();
+				} catch (Exception e) {
+					error(MANIFEST + " while reading manifest file", e);
+				}
+			} else {
+				error(MANIFEST + ", no such file " + mf);
+			}
+		}
+
+		if (getProperty(NOMANIFEST) == null)
+			dot.setManifest(manifest);
+		else
+			dot.setDoNotTouchManifest();
+
+		// This must happen after we analyzed so
+		// we know what it is on the classpath
+		addSources(dot);
+
+		if (getProperty(POM) != null)
+			dot.putResource("pom.xml", new PomResource(dot.getManifest()));
+
+		if (!isNoBundle())
+			doVerify(dot);
+
+		if (dot.getResources().isEmpty())
+			error("The JAR is empty: " + dot.getName());
+
+		dot.updateModified(lastModified(), "Last Modified Processor");
+		dot.setName(getBsn());
+
+		sign(dot);
+
+		doSaveManifest(dot);
+		return dot;
+	}
+
+	/**
+	 * Allow any local initialization by subclasses before we build.
+	 */
+	public void init() throws Exception {
+		begin();
+		doRequireBnd();
+	}
+
+	/**
+	 * Turn this normal bundle in a web and add any resources.
+	 * 
+	 * @throws Exception
+	 */
+	private Jar doWab(Jar dot) throws Exception {
+		String wab = getProperty(WAB);
+		String wablib = getProperty(WABLIB);
+		if (wab == null && wablib == null)
+			return dot;
+
+		setProperty(BUNDLE_CLASSPATH, append("WEB-INF/classes", getProperty(BUNDLE_CLASSPATH)));
+
+		Jar next = new Jar(dot.getName());
+		addClose(next);
+
+		for (Map.Entry<String, Resource> entry : dot.getResources().entrySet()) {
+			String path = entry.getKey();
+			if (path.indexOf('/') > 0 && !Character.isUpperCase(path.charAt(0))) {
+				trace("wab: moving: %s", path);
+				next.putResource("WEB-INF/classes/" + path, entry.getValue());
+			} else {
+				trace("wab: not moving: %s", path);
+				next.putResource(path, entry.getValue());
+			}
+		}
+
+		Map<String, Map<String, String>> clauses = parseHeader(getProperty(WABLIB));
+		for (String key : clauses.keySet()) {
+			File f = getFile(key);
+			addWabLib(next, f);
+		}
+		doIncludeResource(next, wab);
+		return next;
+	}
+
+	/**
+	 * Add a wab lib to the jar.
+	 * 
+	 * @param f
+	 */
+	private void addWabLib(Jar dot, File f) throws Exception {
+		if (f.exists()) {
+			Jar jar = new Jar(f);
+			jar.setDoNotTouchManifest();
+			addClose(jar);
+			String path = "WEB-INF/lib/" + f.getName();
+			dot.putResource(path, new JarResource(jar));
+			setProperty(BUNDLE_CLASSPATH, append(getProperty(BUNDLE_CLASSPATH), path));
+
+			Manifest m = jar.getManifest();
+			String cp = m.getMainAttributes().getValue("Class-Path");
+			if (cp != null) {
+				Collection<String> parts = split(cp, ",");
+				for (String part : parts) {
+					File sub = getFile(f.getParentFile(), part);
+					if (!sub.exists() || !sub.getParentFile().equals(f.getParentFile())) {
+						warning("Invalid Class-Path entry %s in %s, must exist and must reside in same directory",
+								sub, f);
+					} else {
+						addWabLib(dot, sub);
+					}
+				}
+			}
+		} else {
+			error("WAB lib does not exist %s", f);
+		}
+	}
+
+	/**
+	 * Get the manifest and write it out separately if -savemanifest is set
+	 * 
+	 * @param dot
+	 */
+	private void doSaveManifest(Jar dot) throws Exception {
+		String output = getProperty(SAVEMANIFEST);
+		if (output == null)
+			return;
+
+		File f = getFile(output);
+		if (f.isDirectory()) {
+			f = new File(f, "MANIFEST.MF");
+		}
+		f.delete();
+		f.getParentFile().mkdirs();
+		OutputStream out = new FileOutputStream(f);
+		try {
+			Jar.writeManifest(dot.getManifest(), out);
+		} finally {
+			out.close();
+		}
+		changedFile(f);
+	}
+
+	protected void changedFile(File f) {
+	}
+
+	/**
+	 * Sign the jar file.
+	 * 
+	 * -sign : <alias> [ ';' 'password:=' <password> ] [ ';' 'keystore:='
+	 * <keystore> ] [ ';' 'sign-password:=' <pw> ] ( ',' ... )*
+	 * 
+	 * @return
+	 */
+
+	void sign(Jar jar) throws Exception {
+		String signing = getProperty("-sign");
+		if (signing == null)
+			return;
+
+		trace("Signing %s, with %s", getBsn(), signing);
+		List<SignerPlugin> signers = getPlugins(SignerPlugin.class);
+
+		Map<String, Map<String, String>> infos = parseHeader(signing);
+		for (Map.Entry<String, Map<String, String>> entry : infos.entrySet()) {
+			for (SignerPlugin signer : signers) {
+				signer.sign(this, entry.getKey());
+			}
+		}
+	}
+
+	public boolean hasSources() {
+		return isTrue(getProperty(SOURCES));
+	}
+
+	protected String getImportPackages() {
+		String ip = super.getImportPackages();
+		if (ip != null)
+			return ip;
+
+		return "*";
+	}
+
+	private void doConditional(Jar dot) throws Exception {
+		Map<String, Map<String, String>> conditionals = getHeader(CONDITIONAL_PACKAGE);
+		if (conditionals.isEmpty())
+			return;
+
+		while (true) {
+			analyze();
+			Map<String, Map<String, String>> imports = getImports();
+
+			// Match the packages specified in conditionals
+			// against the imports. Any match must become a
+			// Private-Package
+			Map<String, Map<String, String>> filtered = merge(CONDITIONAL_PACKAGE, conditionals,
+					imports, new HashSet<String>(), null);
+
+			// Imports can also specify a private import. These
+			// packages must also be copied to the bundle
+			for (Map.Entry<String, Map<String, String>> entry : getImports().entrySet()) {
+				String type = entry.getValue().get(IMPORT_DIRECTIVE);
+				if (type != null && type.equals(PRIVATE_DIRECTIVE))
+					filtered.put(entry.getKey(), entry.getValue());
+			}
+
+			// remove existing packages to prevent merge errors
+			filtered.keySet().removeAll(dot.getPackages());
+			if (filtered.size() == 0)
+				break;
+
+			int size = dot.getResources().size();
+			doExpand(dot, CONDITIONAL_PACKAGE + " Private imports",
+					Instruction.replaceWithInstruction(filtered), false);
+
+			// Were there any expansions?
+			if (size == dot.getResources().size())
+				break;
+
+			analyzed = false;
+		}
+	}
+
+	/**
+	 * 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 Exception {
+		super.analyze();
+		cleanupVersion(imports, null);
+		cleanupVersion(exports, getVersion());
+		String version = getProperty(BUNDLE_VERSION);
+		if (version != null) {
+			version = cleanupVersion(version);
+			if (version.endsWith(".SNAPSHOT")) {
+				version = version.replaceAll("SNAPSHOT$", getProperty(SNAPSHOT, "SNAPSHOT"));
+			}
+			setProperty(BUNDLE_VERSION, version);
+		}
+	}
+
+	public void cleanupVersion(Map<String, Map<String, String>> mapOfMap, String defaultVersion) {
+		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();
+			String v = attributes.get(Constants.VERSION_ATTRIBUTE);
+			if (v == null && defaultVersion != null) {
+				if (!isTrue(getProperty(Constants.NODEFAULTVERSION))) {
+					v = defaultVersion;
+					if (isPedantic())
+						warning("Used bundle version %s for exported package %s", v, entry.getKey());
+				} else {
+					if (isPedantic())
+						warning("No export version for exported package %s", entry.getKey());
+				}
+			}
+			if (v != null)
+				attributes.put(Constants.VERSION_ATTRIBUTE, cleanupVersion(v));
+		}
+	}
+
+	/**
+     * 
+     */
+	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/"+path, resource);
+					} else {
+						resource = jar.getResource("OSGI-OPT/src/" + path);
+						if (resource != null) {
+							dot.putResource("OSGI-OPT/src/"+path, 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(EXPORT_PACKAGE) != null || getProperty(PRIVATE_PACKAGE) != null))
+			warning("Classpath is empty. Private-Package and Export-Package can only expand from the classpath when there is one");
+
+		Map<Instruction, Map<String, String>> privateMap = Instruction
+				.replaceWithInstruction(getHeader(PRIVATE_PACKAGE));
+		Map<Instruction, Map<String, String>> exportMap = Instruction
+				.replaceWithInstruction(getHeader(EXPORT_PACKAGE));
+
+		if (isTrue(getProperty(Constants.UNDERTEST))) {
+			privateMap.putAll(Instruction.replaceWithInstruction(parseHeader(getProperty(
+					Constants.TESTPACKAGES, "test;presence:=optional"))));
+		}
+		if (!privateMap.isEmpty())
+			doExpand(jar, "Private-Package, or -testpackages", privateMap, true);
+
+		if (!exportMap.isEmpty()) {
+			Jar exports = new Jar("exports");
+			doExpand(exports, EXPORT_PACKAGE, exportMap, true);
+			jar.addAll(exports);
+			exports.close();
+		}
+
+		if (!isNoBundle()) {
+			if (privateMap.isEmpty() && exportMap.isEmpty() && !isResourceOnly()
+					&& getProperty(EXPORT_CONTENTS) == null) {
+				warning("None of Export-Package, Provide-Package, Private-Package, -testpackages, or -exportcontents is set, therefore no packages will be included");
+			}
+		}
+	}
+
+	/**
+	 * 
+	 * @param jar
+	 * @param name
+	 * @param instructions
+	 */
+	private void doExpand(Jar jar, String name, Map<Instruction, Map<String, String>> instructions,
+			boolean mandatory) {
+		Set<Instruction> superfluous = removeMarkedDuplicates(instructions.keySet());
+
+		for (Iterator<Jar> c = getClasspath().iterator(); c.hasNext();) {
+			Jar now = c.next();
+			doExpand(jar, instructions, now, superfluous);
+		}
+
+		if (mandatory && superfluous.size() > 0) {
+			StringBuilder sb = new StringBuilder();
+			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.toString());
+				del = "\n                ";
+			}
+			sb.append("\nClasspath: ");
+			sb.append(Processor.join(getClasspath()));
+			sb.append("\n");
+
+			warning(sb.toString());
+			if (isPedantic())
+				diagnostics = true;
+		}
+	}
+
+	/**
+	 * 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(getName(path)))
+				continue;
+
+			if (directory.getValue() == null)
+				continue;
+
+			String pack = path.replace('/', '.');
+			Instruction instr = matches(included, pack, superfluous, classpathEntry.getName());
+			if (instr != null) {
+				// System.out.println("Pattern match: " + pack + " " +
+				// instr.getPattern() + " " + instr.isNegated());
+				if (!instr.isNegated()) {
+					Map<String, Resource> contents = directory.getValue();
+
+					// What to do with split packages? Well if this
+					// directory already exists, we will check the strategy
+					// and react accordingly.
+					boolean overwriteResource = true;
+					if (jar.hasDirectory(path)) {
+						Map<String, String> directives = included.get(instr);
+
+						switch (getSplitStrategy((String) directives.get(SPLIT_PACKAGE_DIRECTIVE))) {
+						case SPLIT_MERGE_LAST:
+							overwriteResource = true;
+							break;
+
+						case SPLIT_MERGE_FIRST:
+							overwriteResource = false;
+							break;
+
+						case SPLIT_ERROR:
+							error(diagnostic(pack, getClasspath(), classpathEntry.source));
+							continue loop;
+
+						case SPLIT_FIRST:
+							continue loop;
+
+						default:
+							warning(diagnostic(pack, getClasspath(), classpathEntry.source));
+							overwriteResource = false;
+							break;
+						}
+					}
+
+					jar.addDirectory(contents, overwriteResource);
+
+					String key = path + "/bnd.info";
+					Resource r = jar.getResource(key);
+					if (r != null)
+						jar.putResource(key, new PreprocessResource(this, r));
+
+					if (hasSources()) {
+						String srcPath = "OSGI-OPT/src/" + path;
+						Map<String, Resource> srcContents = classpathEntry.getDirectories().get(
+								srcPath);
+						if (srcContents != null) {
+							jar.addDirectory(srcContents, overwriteResource);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Analyze the classpath for a split package
+	 * 
+	 * @param pack
+	 * @param classpath
+	 * @param source
+	 * @return
+	 */
+	private String diagnostic(String pack, List<Jar> classpath, File source) {
+		// Default is like merge-first, but with a warning
+		// Find the culprits
+		pack = pack.replace('.', '/');
+		List<Jar> culprits = new ArrayList<Jar>();
+		for (Iterator<Jar> i = classpath.iterator(); i.hasNext();) {
+			Jar culprit = (Jar) i.next();
+			if (culprit.getDirectories().containsKey(pack)) {
+				culprits.add(culprit);
+			}
+		}
+		return "Split package "
+				+ pack
+				+ "\nUse directive -split-package:=(merge-first|merge-last|error|first) on Export/Private Package instruction to get rid of this warning\n"
+				+ "Package found in   " + culprits + "\n" + "Reference from     " + source + "\n"
+				+ "Classpath          " + classpath;
+	}
+
+	private int getSplitStrategy(String type) {
+		if (type == null)
+			return SPLIT_DEFAULT;
+
+		if (type.equals("merge-last"))
+			return SPLIT_MERGE_LAST;
+
+		if (type.equals("merge-first"))
+			return SPLIT_MERGE_FIRST;
+
+		if (type.equals("error"))
+			return SPLIT_ERROR;
+
+		if (type.equals("first"))
+			return SPLIT_FIRST;
+
+		error("Invalid strategy for split-package: " + type);
+		return SPLIT_DEFAULT;
+	}
+
+	/**
+	 * Matches the instructions against a package.
+	 * 
+	 * @param instructions
+	 *            The list of instructions
+	 * @param pack
+	 *            The name of the package
+	 * @param superfluousPatterns
+	 *            The total list of patterns, matched patterns are removed
+	 * @param source
+	 *            The name of the source container, can be filtered upon with
+	 *            the from: directive.
+	 * @return
+	 */
+	private Instruction matches(Map<Instruction, Map<String, String>> instructions, String pack,
+			Set<Instruction> superfluousPatterns, String source) {
+		for (Map.Entry<Instruction, Map<String, String>> entry : instructions.entrySet()) {
+			Instruction pattern = entry.getKey();
+
+			// It is possible to filter on the source of the
+			// package with the from: directive. This is an
+			// instruction that must match the name of the
+			// source class path entry.
+
+			String from = entry.getValue().get(FROM_DIRECTIVE);
+			if (from != null) {
+				Instruction f = Instruction.getPattern(from);
+				if (!f.matches(source) || f.isNegated())
+					return null;
+			}
+
+			// Now do the normal
+			// matching
+			if (pattern.matches(pack)) {
+				if (superfluousPatterns != null)
+					superfluousPatterns.remove(pattern);
+				return pattern;
+			}
+		}
+		return null;
+	}
+
+	private Map<String, Map<String, String>> getHeader(String string) {
+		if (string == null)
+			return Collections.emptyMap();
+		return parseHeader(getProperty(string));
+	}
+
+	/**
+	 * Parse the Bundle-Includes header. Files in the bundles Include header are
+	 * included in the jar. The source can be a directory or a file.
+	 * 
+	 * @throws IOException
+	 * @throws FileNotFoundException
+	 */
+	private void doIncludeResources(Jar jar) throws Exception {
+		String includes = getProperty("Bundle-Includes");
+		if (includes == null) {
+			includes = getProperty(INCLUDERESOURCE);
+			if (includes == null || includes.length() == 0)
+				includes = getProperty("Include-Resource");
+		} else
+			warning("Please use -includeresource instead of Bundle-Includes");
+
+		doIncludeResource(jar, includes);
+
+	}
+
+	private void doIncludeResource(Jar jar, String includes) throws Exception {
+		Map<String, Map<String, String>> clauses = parseHeader(includes);
+		doIncludeResource(jar, clauses);
+	}
+
+	private void doIncludeResource(Jar jar, Map<String, Map<String, String>> clauses)
+			throws ZipException, IOException, Exception {
+		for (Map.Entry<String, Map<String, String>> entry : clauses.entrySet()) {
+			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();
+		}
+
+		String parts[] = name.split("\\s*=\\s*");
+		String source = parts[0];
+		String destination = parts[0];
+		if (parts.length == 2)
+			source = parts[1];
+
+		if (source.startsWith("@")) {
+			extractFromJar(jar, source.substring(1), parts.length == 1 ? "" : destination);
+		} else 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 {
+			File sourceFile;
+			String destinationPath;
+
+			sourceFile = getFile(source);
+			if (parts.length == 1) {
+				// Directories should be copied to the root
+				// but files to their file name ...
+				if (sourceFile.isDirectory())
+					destinationPath = "";
+				else
+					destinationPath = sourceFile.getName();
+			} else {
+				destinationPath = parts[0];
+			}
+			// Handle directories
+			if (sourceFile.isDirectory()) {
+				destinationPath = doResourceDirectory(jar, extra, preprocess, sourceFile,
+						destinationPath);
+				return;
+			}
+
+			// destinationPath = checkDestinationPath(destinationPath);
+
+			if (!sourceFile.exists()) {
+				noSuchFile(jar, name, extra, source, destinationPath);
+			} else
+				copy(jar, destinationPath, sourceFile, preprocess, extra);
+		}
+	}
+
+	private String doResourceDirectory(Jar jar, Map<String, String> extra, boolean preprocess,
+			File sourceFile, String destinationPath) throws Exception {
+		String filter = extra.get("filter:");
+		boolean flatten = isTrue(extra.get("flatten:"));
+		boolean recursive = true;
+		String directive = extra.get("recursive:");
+		if (directive != null) {
+			recursive = isTrue(directive);
+		}
+
+		InstructionFilter iFilter = null;
+		if (filter != null) {
+			iFilter = new InstructionFilter(Instruction.getPattern(filter), recursive,
+					getDoNotCopy());
+		} else {
+			iFilter = new InstructionFilter(null, recursive, getDoNotCopy());
+		}
+
+		Map<String, File> files = newMap();
+		resolveFiles(sourceFile, iFilter, recursive, destinationPath, files, flatten);
+
+		for (Map.Entry<String, File> entry : files.entrySet()) {
+			copy(jar, entry.getKey(), entry.getValue(), preprocess, extra);
+		}
+		return destinationPath;
+	}
+
+	private void resolveFiles(File dir, FileFilter filter, boolean recursive, String path,
+			Map<String, File> files, boolean flatten) {
+
+		if (doNotCopy(dir.getName())) {
+			return;
+		}
+
+		File[] fs = dir.listFiles(filter);
+		for (File file : fs) {
+			if (file.isDirectory()) {
+				if (recursive) {
+					String nextPath;
+					if (flatten)
+						nextPath = path;
+					else
+						nextPath = appendPath(path, file.getName());
+
+					resolveFiles(file, filter, recursive, nextPath, files, flatten);
+				}
+				// Directories are ignored otherwise
+			} else {
+				String p = appendPath(path, file.getName());
+				if (files.containsKey(p))
+					warning("Include-Resource overwrites entry %s from file %s", p, file);
+				files.put(p, file);
+			}
+		}
+	}
+
+	private void noSuchFile(Jar jar, String clause, Map<String, String> extra, String source,
+			String destinationPath) throws Exception {
+		Jar src = getJarFromName(source, "Include-Resource " + source);
+		if (src != null) {
+			JarResource jarResource = new JarResource(src);
+			jar.putResource(destinationPath, jarResource);
+		} else {
+			Resource lastChance = make.process(source);
+			if (lastChance != null) {
+				String x = extra.get("extra");
+				if (x != null)
+					lastChance.setExtra(x);
+				jar.putResource(destinationPath, lastChance);
+			} else
+				error("Input file does not exist: " + source);
+		}
+	}
+
+	/**
+	 * Extra resources from a Jar and add them to the given jar. The clause is
+	 * the
+	 * 
+	 * @param jar
+	 * @param clauses
+	 * @param i
+	 * @throws ZipException
+	 * @throws IOException
+	 */
+	private void extractFromJar(Jar jar, String source, String destination) 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 = source.lastIndexOf("!/");
+		Instruction instr = null;
+		if (n > 0) {
+			instr = Instruction.getPattern(source.substring(n + 2));
+			source = source.substring(0, n);
+		}
+
+		// Pattern filter = null;
+		// if (n > 0) {
+		// String fstring = source.substring(n + 2);
+		// source = source.substring(0, n);
+		// filter = wildcard(fstring);
+		// }
+		Jar sub = getJarFromName(source, "extract from jar");
+		if (sub == null)
+			error("Can not find JAR file " + source);
+		else {
+			jar.addAll(sub, instr, destination);
+		}
+	}
+
+	private void copy(Jar jar, String path, File from, boolean preprocess, Map<String, String> extra)
+			throws Exception {
+		if (doNotCopy(from.getName()))
+			return;
+
+		if (from.isDirectory()) {
+
+			File files[] = from.listFiles();
+			for (int i = 0; i < files.length; i++) {
+				copy(jar, appendPath(path, files[i].getName()), files[i], preprocess, extra);
+			}
+		} else {
+			if (from.exists()) {
+				Resource resource = new FileResource(from);
+				if (preprocess) {
+					resource = new PreprocessResource(this, resource);
+				}
+				String x = extra.get("extra");
+				if (x != null)
+					resource.setExtra(x);
+				if (path.endsWith("/"))
+					path = path + from.getName();
+				jar.putResource(path, resource);
+
+				if (isTrue(extra.get(LIB_DIRECTIVE))) {
+					setProperty(BUNDLE_CLASSPATH, append(getProperty(BUNDLE_CLASSPATH), path));
+				}
+			} 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);
+	}
+
+	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;
+		}
+
+		List<Jar> result = new ArrayList<Jar>();
+		List<Builder> builders;
+
+		builders = getSubBuilders();
+
+		for (Builder builder : builders) {
+			try {
+				Jar jar = builder.build();
+				jar.setName(builder.getBsn());
+				result.add(jar);
+			} catch (Exception e) {
+				e.printStackTrace();
+				error("Sub Building " + builder.getBsn(), e);
+			}
+			if (builder != this)
+				getInfo(builder, builder.getBsn() + ": ");
+		}
+		return result.toArray(new Jar[result.size()]);
+	}
+
+	/**
+	 * Answer a list of builders that represent this file or a list of files
+	 * specified in -sub. This list can be empty. These builders represents to
+	 * be created artifacts and are each scoped to such an artifacts. The
+	 * builders can be used to build the bundles or they can be used to find out
+	 * information about the to be generated bundles.
+	 * 
+	 * @return List of 0..n builders representing artifacts.
+	 * @throws Exception
+	 */
+	public List<Builder> getSubBuilders() throws Exception {
+		String sub = (String) getProperty(SUB);
+		if (sub == null || sub.trim().length() == 0 || EMPTY_HEADER.equals(sub))
+			return Arrays.asList(this);
+
+		List<Builder> builders = new ArrayList<Builder>();
+		if (isTrue(getProperty(NOBUNDLES)))
+			return builders;
+
+		Map<String, Map<String, String>> subsMap = parseHeader(sub);
+		for (Iterator<String> i = subsMap.keySet().iterator(); i.hasNext();) {
+			File file = getFile(i.next());
+			if (file.isFile()) {
+				builders.add(getSubBuilder(file));
+				i.remove();
+			}
+		}
+
+		Set<Instruction> subs = Instruction.replaceWithInstruction(subsMap).keySet();
+
+		List<File> members = new ArrayList<File>(Arrays.asList(getBase().listFiles()));
+
+		nextFile: while (members.size() > 0) {
+
+			File file = members.remove(0);
+
+			// Check if the file is one of our parents
+			Processor p = this;
+			while (p != null) {
+				if (file.equals(p.getPropertiesFile()))
+					continue nextFile;
+				p = p.getParent();
+			}
+
+			for (Iterator<Instruction> i = subs.iterator(); i.hasNext();) {
+
+				Instruction instruction = i.next();
+				if (instruction.matches(file.getName())) {
+
+					if (!instruction.isNegated()) {
+						builders.add(getSubBuilder(file));
+					}
+
+					// Because we matched (even though we could be negated)
+					// we skip any remaining searches
+					continue nextFile;
+				}
+			}
+		}
+		return builders;
+	}
+
+	public Builder getSubBuilder(File file) throws Exception {
+		Builder builder = getSubBuilder();
+		if (builder != null) {
+			builder.setProperties(file);
+			addClose(builder);
+		}
+		return builder;
+	}
+
+	public Builder getSubBuilder() throws Exception {
+		Builder builder = new Builder(this);
+		builder.setBase(getBase());
+
+		for (Jar file : getClasspath()) {
+			builder.addClasspath(file);
+		}
+
+		return builder;
+	}
+
+	/**
+	 * A macro to convert a maven version to an OSGi version
+	 */
+
+	public String _maven_version(String args[]) {
+		if (args.length > 2)
+			error("${maven_version} macro receives too many arguments " + Arrays.toString(args));
+		else if (args.length < 2)
+			error("${maven_version} macro has no arguments, use ${maven_version;1.2.3-SNAPSHOT}");
+		else {
+			return cleanupVersion(args[1]);
+		}
+		return null;
+	}
+
+	public String _permissions(String args[]) throws IOException {
+		StringBuilder sb = new StringBuilder();
+
+		for (String arg : args) {
+			if ("packages".equals(arg) || "all".equals(arg)) {
+				for (String imp : getImports().keySet()) {
+					if (!imp.startsWith("java.")) {
+						sb.append("(org.osgi.framework.PackagePermission \"");
+						sb.append(imp);
+						sb.append("\" \"import\")\r\n");
+					}
+				}
+				for (String exp : getExports().keySet()) {
+					sb.append("(org.osgi.framework.PackagePermission \"");
+					sb.append(exp);
+					sb.append("\" \"export\")\r\n");
+				}
+			} else if ("admin".equals(arg) || "all".equals(arg)) {
+				sb.append("(org.osgi.framework.AdminPermission)");
+			} else if ("permissions".equals(arg))
+				;
+			else
+				error("Invalid option in ${permissions}: %s", arg);
+		}
+		return sb.toString();
+	}
+
+	/**
+     * 
+     */
+	public void removeBundleSpecificHeaders() {
+		Set<String> set = new HashSet<String>(Arrays.asList(BUNDLE_SPECIFIC_HEADERS));
+		setForceLocal(set);
+	}
+
+	/**
+	 * Check if the given resource is in scope of this bundle. That is, it
+	 * checks if the Include-Resource includes this resource or if it is a class
+	 * file it is on the class path and the Export-Pacakge or Private-Package
+	 * include this resource.
+	 * 
+	 * For now, include resources are skipped.
+	 * 
+	 * @param f
+	 * @return
+	 */
+	public boolean isInScope(Collection<File> resources) throws Exception {
+		Map<String, Map<String, String>> clauses = parseHeader(getProperty(Constants.EXPORT_PACKAGE));
+		clauses.putAll(parseHeader(getProperty(Constants.PRIVATE_PACKAGE)));
+		if (isTrue(getProperty(Constants.UNDERTEST))) {
+			clauses.putAll(parseHeader(getProperty(Constants.TESTPACKAGES,
+					"test;presence:=optional")));
+		}
+		Map<Instruction, Map<String, String>> instructions = Instruction
+				.replaceWithInstruction(clauses);
+
+		for (File r : resources) {
+			String cpEntry = getClasspathEntrySuffix(r);
+			if (cpEntry != null) {
+				String pack = Clazz.getPackage(cpEntry);
+				Instruction i = matches(instructions, pack, null, r.getName());
+				if (i != null)
+					return !i.isNegated();
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Answer the string of the resource that it has in the container.
+	 * 
+	 * @param resource
+	 *            The resource to look for
+	 * @return
+	 * @throws Exception
+	 */
+	public String getClasspathEntrySuffix(File resource) throws Exception {
+		for (Jar jar : getClasspath()) {
+			File source = jar.getSource();
+			if (source != null) {
+				source = source.getCanonicalFile();
+				String sourcePath = source.getAbsolutePath();
+				String resourcePath = resource.getAbsolutePath();
+
+				if (resourcePath.startsWith(sourcePath)) {
+					// Make sure that the path name is translated correctly
+					// i.e. on Windows the \ must be translated to /
+					String filePath = resourcePath.substring(sourcePath.length() + 1);
+
+					return filePath.replace(File.separatorChar, '/');
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * doNotCopy
+	 * 
+	 * The doNotCopy variable maintains a patter for files that should not be
+	 * copied. There is a default {@link #DEFAULT_DO_NOT_COPY} but this ca be
+	 * overridden with the {@link Constants#DONOTCOPY} property.
+	 */
+
+	public boolean doNotCopy(String v) {
+		return getDoNotCopy().matcher(v).matches();
+	}
+
+	public Pattern getDoNotCopy() {
+		if (xdoNotCopy == null) {
+			String string = null;
+			try {
+				string = getProperty(DONOTCOPY, DEFAULT_DO_NOT_COPY);
+				xdoNotCopy = Pattern.compile(string);
+			} catch (Exception e) {
+				error("Invalid value for %s, value is %s", DONOTCOPY, string);
+				xdoNotCopy = Pattern.compile(DEFAULT_DO_NOT_COPY);
+			}
+		}
+		return xdoNotCopy;
+	}
+
+	/**
+	 */
+
+	static MakeBnd			makeBnd				= new MakeBnd();
+	static MakeCopy			makeCopy			= new MakeCopy();
+	static ServiceComponent	serviceComponent	= new ServiceComponent();
+	static DSAnnotations	dsAnnotations		= new DSAnnotations();
+	static MetatypePlugin	metatypePlugin		= new MetatypePlugin();
+
+	@Override protected void setTypeSpecificPlugins(Set<Object> list) {
+		list.add(makeBnd);
+		list.add(makeCopy);
+		list.add(serviceComponent);
+		//list.add(dsAnnotations);
+		list.add(metatypePlugin);
+		super.setTypeSpecificPlugins(list);
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/ClassDataCollector.java b/bundleplugin/src/main/java/aQute/lib/osgi/ClassDataCollector.java
new file mode 100644
index 0000000..12e9a37
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/ClassDataCollector.java
@@ -0,0 +1,88 @@
+package aQute.lib.osgi;
+
+public class ClassDataCollector {
+    public void classBegin(int access, String name) {
+    }
+
+    public boolean classStart(int access, String name) {
+        classBegin(access,name);
+        return true;
+    }
+
+    public void extendsClass(String name) {
+    }
+
+    public void implementsInterfaces(String name[]) {
+    }
+
+    public void addReference(String token) {
+    }
+
+    public void annotation(Annotation annotation) {
+    }
+
+    public void parameter(int p) {
+    }
+
+    public void method(Clazz.MethodDef defined) {
+        if (defined.isConstructor())
+            constructor(defined.access, defined.descriptor);
+        else
+            method(defined.access, defined.name, defined.descriptor);
+    }
+
+    public void field(Clazz.FieldDef defined) {
+        field(defined.access, defined.name, defined.descriptor);
+    }
+
+    public void reference(Clazz.MethodDef referenced) {
+    }
+
+    public void reference(Clazz.FieldDef referenced) {
+    }
+
+    public void classEnd() {
+    }
+
+    @Deprecated // Will really be removed!
+    public void field(int access, String name, String descriptor) {
+    }
+
+    @Deprecated // Will really be removed!
+    public void constructor(int access, String descriptor) {
+    }
+
+    @Deprecated // Will really be removed!
+    public void method(int access, String name, String descriptor) {
+    }
+
+    /**
+     * The EnclosingMethod attribute
+     * 
+     * @param cName The name of the enclosing class, never null. Name is with slashes.
+     * @param mName The name of the enclosing method in the class with cName or null
+     * @param mDescriptor The descriptor of this type
+     */
+	public void enclosingMethod(String cName, String mName, String mDescriptor) {
+		
+	}
+
+	/**
+	 * The InnerClass attribute
+	 * 
+	 * @param innerClass The name of the inner class (with slashes). Can be null.
+	 * @param outerClass The name of the outer class (with slashes) Can be null.
+	 * @param innerName The name inside the outer class, can be null.
+	 * @param modifiers The access flags 
+	 */
+	public void innerClass(String innerClass, String outerClass, String innerName,
+			int innerClassAccessFlags) {		
+	}
+
+	public void signature(String signature) {
+	}
+
+	public void constant(Object object) {
+	}
+
+}
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..d7ed1ce
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Clazz.java
@@ -0,0 +1,1608 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.nio.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.annotation.*;
+import aQute.libg.generics.*;
+
+public class Clazz {
+
+	public class ClassConstant {
+		int	cname;
+
+		public ClassConstant(int class_index) {
+			this.cname = class_index;
+		}
+
+		public String getName() {
+			return (String) pool[cname];
+		}
+	}
+
+	public static enum JAVA {
+		UNKNOWN(Integer.MAX_VALUE), OpenJDK7(51), J2S6(50), J2SE5(49), JDK1_4(48), JDK1_3(47), JDK1_2(
+				46), JDK1_1(45);
+
+		final int	major;
+
+		JAVA(int major) {
+			this.major = major;
+		}
+
+		static JAVA format(int n) {
+			for (JAVA e : JAVA.values())
+				if (e.major == n)
+					return e;
+			return UNKNOWN;
+		}
+
+		public int getMajor() {
+			return major;
+		}
+
+		public boolean hasAnnotations() {
+			return major >= J2SE5.major;
+		}
+
+		public boolean hasGenerics() {
+			return major >= J2SE5.major;
+		}
+
+		public boolean hasEnums() {
+			return major >= J2SE5.major;
+		}
+	};
+
+	public static enum QUERY {
+		IMPLEMENTS, EXTENDS, IMPORTS, NAMED, ANY, VERSION, CONCRETE, ABSTRACT, PUBLIC, ANNOTATION, RUNTIMEANNOTATIONS, CLASSANNOTATIONS
+	};
+
+	public static EnumSet<QUERY>	HAS_ARGUMENT	= EnumSet.of(QUERY.IMPLEMENTS, QUERY.EXTENDS,
+															QUERY.IMPORTS, QUERY.NAMED,
+															QUERY.VERSION, QUERY.ANNOTATION);
+
+	/**
+	 * <pre>
+	 * ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its
+	 * package. 
+	 * ACC_FINAL 0x0010 Declared final; no subclasses allowed.
+	 * ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the
+	 * invokespecial instruction. 
+	 * ACC_INTERFACE 0x0200 Is an interface, not a
+	 * class. 
+	 * ACC_ABSTRACT 0x0400 Declared abstract; may not be instantiated.
+	 * </pre>
+	 * 
+	 * @param mod
+	 */
+	final static int				ACC_PUBLIC		= 0x0001;									// Declared
+	// public;
+	// may
+	// be
+	// accessed
+	// from outside its package.
+	final static int				ACC_FINAL		= 0x0010;									// Declared
+	// final;
+	// no
+	// subclasses
+	// allowed.
+	final static int				ACC_SUPER		= 0x0020;									// Treat
+	// superclass
+	// methods
+	// specially when invoked by the
+	// invokespecial instruction.
+	final static int				ACC_INTERFACE	= 0x0200;									// Is
+	// an
+	// interface,
+	// not
+	// a
+	// classs
+	final static int				ACC_ABSTRACT	= 0x0400;									// Declared
+
+	// abstract;
+	// may
+	// not
+	// be
+
+	// instantiated.
+
+	final static int				ACC_ENUM		= 0x04000;
+
+	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;
+	}
+
+	static public class FieldDef implements Comparable<FieldDef> {
+		public FieldDef(int access, String clazz, String name, String descriptor) {
+			this.access = access;
+			this.clazz = clazz.replace('/', '.');
+			this.name = name;
+			this.descriptor = descriptor;
+		}
+
+		final public int	access;
+		final public String	clazz;
+		final public String	name;
+		final public String	descriptor;
+		public String		signature;
+		public Object		constant;
+
+		public boolean equals(Object other) {
+			if (!(other instanceof MethodDef))
+				return false;
+
+			FieldDef m = (FieldDef) other;
+			return clazz.equals(m.clazz) && name.equals(m.name) && descriptor.equals(m.descriptor);
+		}
+
+		public int hashCode() {
+			return clazz.hashCode() ^ name.hashCode() ^ descriptor.hashCode();
+		}
+
+		public int compareTo(FieldDef o) {
+			int result = clazz.compareTo(o.clazz);
+			if (result == 0) {
+				result = name.compareTo(o.name);
+				if (result == 0) {
+					result = descriptor.compareTo(o.descriptor);
+				}
+			}
+			return result;
+		}
+
+		public String getPretty() {
+			return name;
+		}
+
+		public String toString() {
+			return getPretty();
+		}
+
+		public boolean isEnum() {
+			return (access & ACC_ENUM) != 0;
+		}
+	}
+
+	static public class MethodDef extends FieldDef {
+		Pattern	METHOD_DESCRIPTOR	= Pattern.compile("\\((.*)\\)(.+)");
+
+		public MethodDef(int access, String clazz, String method, String descriptor) {
+			super(access, clazz, method, descriptor);
+		}
+
+		public boolean isConstructor() {
+			return name.equals("<init>") || name.equals("<clinit>");
+		}
+
+		public String getReturnType() {
+			String use = descriptor;
+			if (signature != null)
+				use = signature;
+
+			Matcher m = METHOD_DESCRIPTOR.matcher(use);
+			if (!m.matches())
+				throw new IllegalArgumentException("Not a valid method descriptor: " + descriptor);
+
+			String returnType = m.group(2);
+			return objectDescriptorToFQN(returnType);
+		}
+
+		public String getPretty() {
+
+			StringBuilder sb = new StringBuilder();
+			sb.append(descriptor.charAt(0));
+			int index = 1;
+			String del = "";
+			while (index < descriptor.length() && descriptor.charAt(index) != ')') {
+				sb.append(del);
+				index = printParameter(sb, descriptor, index);
+				del = ",";
+			}
+			sb.append(descriptor.charAt(index++));
+			StringBuilder sb2 = new StringBuilder();
+			if (isConstructor()) {
+				sb2.append(getShortName(clazz));
+				index++; // skip the V
+			} else {
+				printParameter(sb2, descriptor, index);
+				sb2.append(" ");
+				sb2.append(getShortName(clazz));
+				sb2.append(".");
+				sb2.append(name);
+			}
+			sb2.append(sb);
+			return sb2.toString();
+		}
+
+		private int printParameter(StringBuilder sb, CharSequence descriptor, int index) {
+			char c = descriptor.charAt(index++);
+			switch (c) {
+			case 'B':
+				sb.append("byte");
+				break;
+			case 'C':
+				sb.append("char");
+				break;
+			case 'D':
+				sb.append("double");
+				break;
+			case 'F':
+				sb.append("float");
+				break;
+			case 'I':
+				sb.append("int");
+				break;
+			case 'J':
+				sb.append("long");
+				break;
+			case 'S':
+				sb.append("short");
+				break;
+			case 'Z':
+				sb.append("boolean");
+				break;
+			case 'V':
+				sb.append("void");
+				break;
+			case 'L':
+				index = reference(sb, descriptor, index);
+				break;
+
+			case '[':
+				index = array(sb, descriptor, index);
+				break;
+			}
+			return index;
+		}
+
+		private int reference(StringBuilder sb, CharSequence descriptor, int index) {
+			int n = sb.length();
+			int lastSlash = n;
+			while (index < descriptor.length() && descriptor.charAt(index) != ';') {
+				char c = descriptor.charAt(index++);
+				if (c == '/') {
+					c = '.';
+					lastSlash = sb.length() + 1;
+				}
+				sb.append(c);
+			}
+			if (lastSlash != n) {
+				sb.delete(n, lastSlash);
+			}
+			return ++index;
+		}
+
+		private int array(StringBuilder sb, CharSequence descriptor, int index) {
+			int n = 1;
+			while (index < descriptor.length() && descriptor.charAt(index) == '[') {
+				index++;
+			}
+			index = printParameter(sb, descriptor, index);
+			while (n-- > 0) {
+				sb.append("[]");
+			}
+			return index;
+		}
+	}
+
+	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
+									};
+
+	boolean				isAbstract;
+	boolean				isPublic;
+	boolean				isEnum;
+	boolean				hasRuntimeAnnotations;
+	boolean				hasClassAnnotations;
+
+	String				className;
+	Object				pool[];
+	int					intPool[];
+	Set<String>			imports		= Create.set();
+	String				path;
+	int					minor		= 0;
+	int					major		= 0;
+	int					access		= 0;
+	String				sourceFile;
+	Set<String>			xref;
+	Set<Integer>		classes;
+	Set<Integer>		descriptors;
+	Set<String>			annotations;
+	int					forName		= 0;
+	int					class$		= 0;
+	String[]			interfaces;
+	String				zuper;
+	ClassDataCollector	cd			= null;
+	Resource			resource;
+	FieldDef			last		= null;
+
+	public Clazz(String path, Resource resource) {
+		this.path = path;
+		this.resource = resource;
+	}
+
+	public Set<String> parseClassFile() throws Exception {
+		return parseClassFileWithCollector(null);
+	}
+
+	public Set<String> parseClassFile(InputStream in) throws IOException {
+		return parseClassFile(in, null);
+	}
+
+	public Set<String> parseClassFileWithCollector(ClassDataCollector cd) throws Exception {
+		InputStream in = resource.openInputStream();
+		try {
+			return parseClassFile(in, cd);
+		} finally {
+			in.close();
+		}
+	}
+
+	public Set<String> parseClassFile(InputStream in, ClassDataCollector cd) throws IOException {
+		DataInputStream din = new DataInputStream(in);
+		try {
+			this.cd = cd;
+			return parseClassFile(din);
+		} finally {
+			cd = null;
+			din.close();
+		}
+	}
+
+	Set<String> parseClassFile(DataInputStream in) throws IOException {
+
+		xref = new HashSet<String>();
+		classes = new HashSet<Integer>();
+		descriptors = new HashSet<Integer>();
+
+		boolean crawl = cd != null; // Crawl the byte code if we have a
+		// collector
+		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;
+
+			case 3:
+				constantInteger(in, poolIndex);
+				break;
+
+			case 4:
+				constantFloat(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
+			case 11: // Interface 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
+		isAbstract = (access_flags & ACC_ABSTRACT) != 0;
+		isPublic = (access_flags & ACC_PUBLIC) != 0;
+		isEnum = (access_flags & ACC_ENUM) != 0;
+
+		int this_class = in.readUnsignedShort();
+		className = (String) pool[intPool[this_class]];
+
+		try {
+
+			if (cd != null) {
+				if (!cd.classStart(access_flags, className))
+					return null;
+			}
+
+			int super_class = in.readUnsignedShort();
+			zuper = (String) pool[intPool[super_class]];
+			if (zuper != null) {
+				String pack = getPackage(zuper);
+				packageReference(pack);
+				if (cd != null)
+					cd.extendsClass(zuper);
+			}
+
+			int interfacesCount = in.readUnsignedShort();
+			if (interfacesCount > 0) {
+				interfaces = new String[interfacesCount];
+				for (int i = 0; i < interfacesCount; i++)
+					interfaces[i] = (String) pool[intPool[in.readUnsignedShort()]];
+				if (cd != null)
+					cd.implementsInterfaces(interfaces);
+			}
+
+			int fieldsCount = in.readUnsignedShort();
+			for (int i = 0; i < fieldsCount; i++) {
+				access_flags = in.readUnsignedShort(); // skip access flags
+				int name_index = in.readUnsignedShort();
+				int descriptor_index = in.readUnsignedShort();
+
+				// Java prior to 1.5 used a weird
+				// static variable to hold the com.X.class
+				// result construct. If it did not find it
+				// it would create a variable class$com$X
+				// that would be used to hold the class
+				// object gotten with Class.forName ...
+				// Stupidly, they did not actively use the
+				// class name for the field type, so bnd
+				// would not see a reference. We detect
+				// this case and add an artificial descriptor
+				String name = pool[name_index].toString(); // name_index
+				if (name.startsWith("class$")) {
+					crawl = true;
+				}
+				if (cd != null)
+					cd.field(last = new FieldDef(access_flags, className, name,
+							pool[descriptor_index].toString()));
+				descriptors.add(new Integer(descriptor_index));
+				doAttributes(in, ElementType.FIELD, 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 = findMethodReference("java/lang/Class", "forName",
+						"(Ljava/lang/String;)Ljava/lang/Class;");
+				class$ = findMethodReference(className, "class$",
+						"(Ljava/lang/String;)Ljava/lang/Class;");
+			} else if (major == 48) {
+				forName = findMethodReference("java/lang/Class", "forName",
+						"(Ljava/lang/String;)Ljava/lang/Class;");
+				if (forName > 0) {
+					crawl = true;
+					class$ = findMethodReference(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();
+				descriptors.add(new Integer(descriptor_index));
+				String name = pool[name_index].toString();
+				String descriptor = pool[descriptor_index].toString();
+				if (cd != null) {
+					MethodDef mdef = new MethodDef(access_flags, className, name, descriptor);
+					last = mdef;
+					cd.method(mdef);
+				}
+
+				if ("<init>".equals(name)) {
+					doAttributes(in, ElementType.CONSTRUCTOR, crawl);
+				} else {
+					doAttributes(in, ElementType.METHOD, crawl);
+				}
+			}
+
+			doAttributes(in, ElementType.TYPE, false);
+
+			//
+			// Now iterate over all classes we found and
+			// parse those as well. We skip duplicates
+			//
+
+			for (int n : classes) {
+				String clazz = (String) pool[n];
+				if (clazz.endsWith(";") || clazz.startsWith("["))
+					parseReference(clazz, 0);
+				else {
+
+					String pack = getPackage(clazz);
+					packageReference(pack);
+				}
+			}
+
+			//
+			// Parse all the descriptors we found
+			//
+
+			for (Iterator<Integer> e = descriptors.iterator(); e.hasNext();) {
+				Integer index = e.next();
+				String prototype = (String) pool[index.intValue()];
+				if (prototype != null)
+					parseDescriptor(prototype);
+				else
+					System.err.println("Unrecognized descriptor: " + index);
+			}
+			Set<String> xref = this.xref;
+			reset();
+			return xref;
+		} finally {
+			if (cd != null)
+				cd.classEnd();
+		}
+	}
+
+	private void constantFloat(DataInputStream in, int poolIndex) throws IOException {
+		if (cd != null)
+			pool[poolIndex] = in.readFloat(); // ALU
+		else
+			in.skipBytes(4);
+	}
+
+	private void constantInteger(DataInputStream in, int poolIndex) throws IOException {
+		intPool[poolIndex] = in.readInt();
+		if (cd != null)
+			pool[poolIndex] = intPool[poolIndex];
+	}
+
+	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;
+		ClassConstant c = new ClassConstant(class_index);
+		pool[poolIndex] = c;
+	}
+
+	/**
+	 * @param in
+	 * @throws IOException
+	 */
+	protected void constantDouble(DataInputStream in, int poolIndex) throws IOException {
+		if (cd != null)
+			pool[poolIndex] = in.readDouble();
+		else
+			in.skipBytes(8);
+	}
+
+	/**
+	 * @param in
+	 * @throws IOException
+	 */
+	protected void constantLong(DataInputStream in, int poolIndex) throws IOException {
+		if (cd != null) {
+			pool[poolIndex] = in.readLong();
+		} else
+			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 findMethodReference(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;
+	}
+
+	/**
+	 * Called for each attribute in the class, field, or method.
+	 * 
+	 * @param in
+	 *            The stream
+	 * @throws IOException
+	 */
+	private void doAttributes(DataInputStream in, ElementType member, boolean crawl)
+			throws IOException {
+		int attributesCount = in.readUnsignedShort();
+		for (int j = 0; j < attributesCount; j++) {
+			// skip name CONSTANT_Utf8 pointer
+			doAttribute(in, member, crawl);
+		}
+	}
+
+	/**
+	 * Process a single attribute, if not recognized, skip it.
+	 * 
+	 * @param in
+	 *            the data stream
+	 * @throws IOException
+	 */
+	private void doAttribute(DataInputStream in, ElementType member, boolean crawl)
+			throws IOException {
+		int attribute_name_index = in.readUnsignedShort();
+		String attributeName = (String) pool[attribute_name_index];
+		long attribute_length = in.readInt();
+		attribute_length &= 0xFFFFFFFF;
+		if ("RuntimeVisibleAnnotations".equals(attributeName))
+			doAnnotations(in, member, RetentionPolicy.RUNTIME);
+		else if ("RuntimeVisibleParameterAnnotations".equals(attributeName))
+			doParameterAnnotations(in, member, RetentionPolicy.RUNTIME);
+		else if ("RuntimeInvisibleAnnotations".equals(attributeName))
+			doAnnotations(in, member, RetentionPolicy.CLASS);
+		else if ("RuntimeInvisibleParameterAnnotations".equals(attributeName))
+			doParameterAnnotations(in, member, RetentionPolicy.CLASS);
+		else if ("InnerClasses".equals(attributeName))
+			doInnerClasses(in);
+		else if ("EnclosingMethod".equals(attributeName))
+			doEnclosingMethod(in);
+		else if ("SourceFile".equals(attributeName))
+			doSourceFile(in);
+		else if ("Code".equals(attributeName) && crawl)
+			doCode(in);
+		else if ("Signature".equals(attributeName))
+			doSignature(in, member);
+		else if ("ConstantValue".equals(attributeName))
+			doConstantValue(in);
+		else {
+			if (attribute_length > 0x7FFFFFFF) {
+				throw new IllegalArgumentException("Attribute > 2Gb");
+			}
+			in.skipBytes((int) attribute_length);
+		}
+	}
+
+	/**
+	 * <pre>
+	 * EnclosingMethod_attribute { 
+	 * 	u2 attribute_name_index; 
+	 * 	u4 attribute_length; 
+	 * 	u2 class_index
+	 * 	u2 method_index;
+	 * }
+	 * </pre>
+	 * 
+	 * 
+	 * @param in
+	 * @throws IOException
+	 */
+	private void doEnclosingMethod(DataInputStream in) throws IOException {
+		int cIndex = in.readShort();
+		int mIndex = in.readShort();
+
+		if (cd != null) {
+			int nameIndex = intPool[cIndex];
+			String cName = (String) pool[nameIndex];
+
+			String mName = null;
+			String mDescriptor = null;
+
+			if (mIndex != 0) {
+				Assoc nameAndType = (Assoc) pool[mIndex];
+				mName = (String) pool[nameAndType.a];
+				mDescriptor = (String) pool[nameAndType.b];
+			}
+			cd.enclosingMethod(cName, mName, mDescriptor);
+		}
+	}
+
+	/**
+	 * <pre>
+	 * InnerClasses_attribute {
+	 * 	u2 attribute_name_index; 
+	 * 	u4 attribute_length; 
+	 * 	u2 number_of_classes; {	
+	 * 		u2 inner_class_info_index;
+	 * 		u2 outer_class_info_index; 
+	 * 		u2 inner_name_index; 
+	 * 		u2 inner_class_access_flags;
+	 * 	} classes[number_of_classes];
+	 * }
+	 * </pre>
+	 * 
+	 * @param in
+	 * @throws IOException
+	 */
+	private void doInnerClasses(DataInputStream in) throws IOException {
+		int number_of_classes = in.readShort();
+		for (int i = 0; i < number_of_classes; i++) {
+			int inner_class_info_index = in.readShort();
+			int outer_class_info_index = in.readShort();
+			int inner_name_index = in.readShort();
+			int inner_class_access_flags = in.readShort() & 0xFFFF;
+
+			if (cd != null) {
+				String innerClass = null;
+				String outerClass = null;
+				String innerName = null;
+
+				if (inner_class_info_index != 0) {
+					int nameIndex = intPool[inner_class_info_index];
+					innerClass = (String) pool[nameIndex];
+				}
+
+				if (outer_class_info_index != 0) {
+					int nameIndex = intPool[outer_class_info_index];
+					outerClass = (String) pool[nameIndex];
+				}
+
+				if (inner_name_index != 0)
+					innerName = (String) pool[inner_name_index];
+
+				cd.innerClass(innerClass, outerClass, innerName, inner_class_access_flags);
+			}
+		}
+	}
+
+	/**
+	 * Handle a signature
+	 * 
+	 * <pre>
+	 * Signature_attribute { 
+	 *     u2 attribute_name_index; 
+	 *     u4 attribute_length; 
+	 *     u2 signature_index; 
+	 *     }
+	 * </pre>
+	 * 
+	 * @param member
+	 */
+
+	void doSignature(DataInputStream in, ElementType member) throws IOException {
+		int signature_index = in.readUnsignedShort();
+		String signature = (String) pool[signature_index];
+
+		// System.out.println("Signature " + signature );
+
+		// The type signature is kind of weird,
+		// lets skip it for now. Seems to be some kind of
+		// type variable name index but it does not seem to
+		// conform to the language specification.
+		if (member != ElementType.TYPE)
+			parseDescriptor(signature);
+
+		if (last != null)
+			last.signature = signature;
+
+		if (cd != null)
+			cd.signature(signature);
+	}
+
+	/**
+	 * Handle a constant value call the data collector with it
+	 */
+	void doConstantValue(DataInputStream in) throws IOException {
+		int constantValue_index = in.readUnsignedShort();
+		if (cd == null)
+			return;
+
+		Object object = pool[constantValue_index];
+		if (object == null)
+			object = pool[intPool[constantValue_index]];
+
+		last.constant = object;
+		cd.constant(object);
+	}
+
+	/**
+	 * <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, ElementType.METHOD, 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.invokespecial: {
+				int mref = 0xFFFF & bb.getShort();
+				if (cd != null)
+					cd.reference(getMethodDef(0, mref));
+				break;
+			}
+
+			case OpCodes.invokevirtual: {
+				int mref = 0xFFFF & bb.getShort();
+				if (cd != null)
+					cd.reference(getMethodDef(0, mref));
+				break;
+			}
+
+			case OpCodes.invokeinterface: {
+				int mref = 0xFFFF & bb.getShort();
+				if (cd != null)
+					cd.reference(getMethodDef(0, mref));
+				break;
+			}
+
+			case OpCodes.invokestatic: {
+				int methodref = 0xFFFF & bb.getShort();
+				if (cd != null)
+					cd.reference(getMethodDef(0, methodref));
+
+				if ((methodref == forName || methodref == class$) && lastReference != -1
+						&& pool[intPool[lastReference]] instanceof String) {
+					String clazz = (String) pool[intPool[lastReference]];
+					if (clazz.startsWith("[") || clazz.endsWith(";"))
+						parseReference(clazz, 0);
+					else {
+						int n = clazz.lastIndexOf('.');
+						if (n > 0)
+							packageReference(clazz.substring(0, n));
+					}
+				}
+				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, ElementType member,
+			RetentionPolicy policy) throws IOException {
+		int num_parameters = in.readUnsignedByte();
+		for (int p = 0; p < num_parameters; p++) {
+			if (cd != null)
+				cd.parameter(p);
+			doAnnotations(in, member, policy);
+		}
+	}
+
+	private void doAnnotations(DataInputStream in, ElementType member, RetentionPolicy policy)
+			throws IOException {
+		int num_annotations = in.readUnsignedShort(); // # of annotations
+		for (int a = 0; a < num_annotations; a++) {
+			if (cd == null)
+				doAnnotation(in, member, policy, false);
+			else {
+				Annotation annotion = doAnnotation(in, member, policy, true);
+				cd.annotation(annotion);
+			}
+		}
+	}
+
+	private Annotation doAnnotation(DataInputStream in, ElementType member, RetentionPolicy policy,
+			boolean collect) throws IOException {
+		int type_index = in.readUnsignedShort();
+		if (annotations == null)
+			annotations = new HashSet<String>();
+
+		annotations.add(pool[type_index].toString());
+
+		if (policy == RetentionPolicy.RUNTIME) {
+			descriptors.add(new Integer(type_index));
+			hasRuntimeAnnotations = true;
+		} else {
+			hasClassAnnotations = true;
+		}
+		String name = (String) pool[type_index];
+		int num_element_value_pairs = in.readUnsignedShort();
+		Map<String, Object> elements = null;
+		for (int v = 0; v < num_element_value_pairs; v++) {
+			int element_name_index = in.readUnsignedShort();
+			String element = (String) pool[element_name_index];
+			Object value = doElementValue(in, member, policy, collect);
+			if (collect) {
+				if (elements == null)
+					elements = new LinkedHashMap<String, Object>();
+				elements.put(element, value);
+			}
+		}
+		if (collect)
+			return new Annotation(name, elements, member, policy);
+		else
+			return null;
+	}
+
+	private Object doElementValue(DataInputStream in, ElementType member, RetentionPolicy policy,
+			boolean collect) throws IOException {
+		char tag = (char) in.readUnsignedByte();
+		switch (tag) {
+		case 'B': // Byte
+		case 'C': // Character
+		case 'I': // Integer
+		case 'S': // Short
+			int const_value_index = in.readUnsignedShort();
+			return intPool[const_value_index];
+
+		case 'D': // Double
+		case 'F': // Float
+		case 's': // String
+		case 'J': // Long
+			const_value_index = in.readUnsignedShort();
+			return pool[const_value_index];
+
+		case 'Z': // Boolean
+			const_value_index = in.readUnsignedShort();
+			return pool[const_value_index] == null || pool[const_value_index].equals(0) ? false : true;
+
+		case 'e': // enum constant
+			int type_name_index = in.readUnsignedShort();
+			if (policy == RetentionPolicy.RUNTIME)
+				descriptors.add(new Integer(type_name_index));
+			int const_name_index = in.readUnsignedShort();
+			return pool[const_name_index];
+
+		case 'c': // Class
+			int class_info_index = in.readUnsignedShort();
+			if (policy == RetentionPolicy.RUNTIME)
+				descriptors.add(new Integer(class_info_index));
+			return pool[class_info_index];
+
+		case '@': // Annotation type
+			return doAnnotation(in, member, policy, collect);
+
+		case '[': // Array
+			int num_values = in.readUnsignedShort();
+			Object[] result = new Object[num_values];
+			for (int i = 0; i < num_values; i++) {
+				result[i] = doElementValue(in, member, policy, collect);
+			}
+			return result;
+
+		default:
+			throw new IllegalArgumentException("Invalid value for Annotation ElementValue tag "
+					+ tag);
+		}
+	}
+
+	/**
+	 * Add a new package reference.
+	 * 
+	 * @param pack
+	 *            A '.' delimited package name
+	 */
+	void packageReference(String pack) {
+		imports.add(pack);
+	}
+
+	/**
+	 * This method parses a descriptor and adds the package of the descriptor to
+	 * the referenced packages.
+	 * 
+	 * The syntax of the descriptor is:
+	 * 
+	 * <pre>
+	 *   descriptor ::= ( '(' reference * ')' )? reference
+	 *   reference  ::= 'L' classname ( '&lt;' references '&gt;' )? ';' | 'B' | 'Z' | ... | '+' | '-' | '['
+	 * </pre>
+	 * 
+	 * This methods uses heavy recursion to parse the descriptor and a roving
+	 * pointer to limit the creation of string objects.
+	 * 
+	 * @param descriptor
+	 *            The to be parsed descriptor
+	 * @param rover
+	 *            The pointer to start at
+	 */
+	public void parseDescriptor(String descriptor) {
+		// Some descriptors are weird, they start with a generic
+		// declaration that contains ':', not sure what they mean ...
+		if (descriptor.charAt(0) == '<')
+			return;
+
+		int rover = 0;
+		if (descriptor.charAt(rover) == '(') {
+			rover = parseReferences(descriptor, rover + 1, ')');
+			rover++;
+		}
+		parseReferences(descriptor, rover, (char) 0);
+	}
+
+	/**
+	 * Parse a sequence of references. A sequence ends with a given character or
+	 * when the string ends.
+	 * 
+	 * @param descriptor
+	 *            The whole descriptor.
+	 * @param rover
+	 *            The index in the descriptor
+	 * @param delimiter
+	 *            The end character or 0
+	 * @return the last index processed, one character after the delimeter
+	 */
+	int parseReferences(String descriptor, int rover, char delimiter) {
+		while (rover < descriptor.length() && descriptor.charAt(rover) != delimiter) {
+			rover = parseReference(descriptor, rover);
+		}
+		return rover;
+	}
+
+	/**
+	 * Parse a single reference. This can be a single character or an object
+	 * reference when it starts with 'L'.
+	 * 
+	 * @param descriptor
+	 *            The descriptor
+	 * @param rover
+	 *            The place to start
+	 * @return The return index after the reference
+	 */
+	int parseReference(String descriptor, int rover) {
+
+		char c = descriptor.charAt(rover);
+		while (c == '[')
+			c = descriptor.charAt(++rover);
+
+		if (c == '<') {
+			rover = parseReferences(descriptor, rover + 1, '>');
+		} else if (c == 'T') {
+			// Type variable name
+			rover++;
+			while (descriptor.charAt(rover) != ';')
+				rover++;
+		} else if (c == 'L') {
+			StringBuilder sb = new StringBuilder();
+			rover++;
+			int lastSlash = -1;
+			while ((c = descriptor.charAt(rover)) != ';') {
+				if (c == '<') {
+					rover = parseReferences(descriptor, rover + 1, '>');
+				} else if (c == '/') {
+					lastSlash = sb.length();
+					sb.append('.');
+				} else
+					sb.append(c);
+				rover++;
+			}
+			if (cd != null)
+				cd.addReference(sb.toString());
+
+			if (lastSlash > 0)
+				packageReference(sb.substring(0, lastSlash));
+		} else {
+			if ("+-*BCDFIJSZV".indexOf(c) < 0)
+				;// System.out.println("Should not skip: " + c);
+		}
+
+		// this skips a lot of characters
+		// [, *, +, -, B, etc.
+
+		return rover + 1;
+	}
+
+	public static String getPackage(String clazz) {
+		int n = clazz.lastIndexOf('/');
+		if (n < 0) {
+			n = clazz.lastIndexOf('.');
+			if (n < 0)
+				return ".";
+		}
+		return clazz.substring(0, n).replace('/', '.');
+	}
+
+	public Set<String> getReferred() {
+		return imports;
+	}
+
+	String getClassName() {
+		if (className == null)
+			return "NOCLASSNAME";
+		return className;
+	}
+
+	public String getPath() {
+		return path;
+	}
+
+	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, Analyzer analyzer) throws Exception {
+		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 PUBLIC:
+			return !isPublic;
+
+		case CONCRETE:
+			return !isAbstract;
+
+		case ANNOTATION:
+			if (annotations == null)
+				return false;
+
+			if (annotations.contains(instr.getPattern()))
+				return true;
+
+			for (String annotation : annotations) {
+				if (instr.matches(annotation))
+					return !instr.isNegated();
+			}
+
+			return false;
+
+		case RUNTIMEANNOTATIONS:
+			return hasClassAnnotations;
+		case CLASSANNOTATIONS:
+			return hasClassAnnotations;
+
+		case ABSTRACT:
+			return isAbstract;
+
+		case IMPORTS:
+			for (String imp : imports) {
+				if (instr.matches(imp.replace('.', '/')))
+					return !instr.isNegated();
+			}
+		}
+
+		if (zuper == null)
+			return false;
+
+		Clazz clazz = analyzer.findClass(zuper + ".class");
+		if (clazz == null)
+			return false;
+
+		return clazz.is(query, instr, analyzer);
+	}
+
+	public String toString() {
+		return getFQN();
+	}
+
+	public String getFQN() {
+		String s = getClassName().replace('/', '.');
+		return s;
+	}
+
+	/**
+	 * Return a list of packages implemented by this class.
+	 * 
+	 * @param implemented
+	 * @param classspace
+	 * @param clazz
+	 * @throws Exception
+	 */
+	@SuppressWarnings("deprecation") final static String	USEPOLICY		= toDescriptor(UsePolicy.class);
+	final static String										PROVIDERPOLICY	= toDescriptor(ProviderType.class);
+
+	public static void getImplementedPackages(Set<String> implemented, Analyzer analyzer,
+			Clazz clazz) throws Exception {
+		if (clazz.interfaces != null) {
+			for (String interf : clazz.interfaces) {
+				interf = interf + ".class";
+				Clazz c = analyzer.getClassspace().get(interf);
+
+				// If not found, actually parse the imported
+				// class file to check for implementation policy.
+				if (c == null)
+					c = analyzer.findClass(interf);
+
+				if (c != null) {
+					boolean consumer = false;
+					Set<String> annotations = c.annotations;
+					if (annotations != null)
+						// Override if we marked the interface as a consumer
+						// interface
+						consumer = annotations.contains(USEPOLICY)
+								|| annotations.contains(PROVIDERPOLICY);
+
+					if (!consumer)
+						implemented.add(getPackage(interf));
+					getImplementedPackages(implemented, analyzer, c);
+				} else
+					implemented.add(getPackage(interf));
+
+			}
+		}
+		if (clazz.zuper != null) {
+			Clazz c = analyzer.getClassspace().get(clazz.zuper);
+			if (c != null) {
+				getImplementedPackages(implemented, analyzer, c);
+			}
+		}
+
+	}
+
+	// String RNAME = "LaQute/bnd/annotation/UsePolicy;";
+
+	public static String toDescriptor(Class<?> clazz) {
+		StringBuilder sb = new StringBuilder();
+		sb.append('L');
+		sb.append(clazz.getName().replace('.', '/'));
+		sb.append(';');
+		return sb.toString();
+	}
+
+	MethodDef getMethodDef(int access, int methodRefPoolIndex) {
+		Object o = pool[methodRefPoolIndex];
+		if (o != null && o instanceof Assoc) {
+			Assoc assoc = (Assoc) o;
+			if (assoc.tag == 10) {
+				int string_index = intPool[assoc.a];
+				String className = (String) pool[string_index];
+				int name_and_type_index = assoc.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;
+					String method = (String) pool[name_index];
+					String descriptor = (String) pool[type_index];
+					return new MethodDef(access, className, method, descriptor);
+				} else
+					throw new IllegalArgumentException(
+							"Invalid class file (or parsing is wrong), assoc is not type + name (12)");
+			} else
+				throw new IllegalArgumentException(
+						"Invalid class file (or parsing is wrong), Assoc is not method ref! (10)");
+		} else
+			throw new IllegalArgumentException(
+					"Invalid class file (or parsing is wrong), Not an assoc at a method ref");
+	}
+
+	public static String getShortName(String cname) {
+		int n = cname.lastIndexOf('.');
+		if (n < 0)
+			return cname;
+		return cname.substring(n + 1, cname.length());
+	}
+
+	public static String fqnToPath(String dotted) {
+		return dotted.replace('.', '/') + ".class";
+	}
+
+	public static String fqnToBinary(String dotted) {
+		return "L" + dotted.replace('.', '/') + ";";
+	}
+
+	public static String pathToFqn(String path) {
+		return path.replace('/', '.').substring(0, path.length() - 6);
+	}
+
+	public boolean isPublic() {
+		return isPublic;
+	}
+
+	public boolean isEnum() {
+		return isEnum;
+	}
+
+	public JAVA getFormat() {
+		return JAVA.format(major);
+
+	}
+
+	public static String objectDescriptorToFQN(String string) {
+		if (string.startsWith("L") && string.endsWith(";"))
+			return string.substring(1, string.length() - 1).replace('/', '.');
+
+		switch (string.charAt(0)) {
+		case 'V':
+			return "void";
+		case 'B':
+			return "byte";
+		case 'C':
+			return "char";
+		case 'I':
+			return "int";
+		case 'S':
+			return "short";
+		case 'D':
+			return "double";
+		case 'F':
+			return "float";
+		case 'J':
+			return "long";
+		case 'Z':
+			return "boolean";
+		case '[': // Array
+			return objectDescriptorToFQN(string.substring(1)) + "[]";
+		}
+		throw new IllegalArgumentException("Invalid type character in descriptor " + string);
+	}
+
+	public static String internalToFqn(String string) {
+		return string.replace('/', '.');
+	}
+
+	public static String unCamel(String id) {
+		StringBuilder out = new StringBuilder();
+		for (int i = 0; i < id.length(); i++) {
+			char c = id.charAt(i);
+			if (c == '_' || c == '$' || c == '.') {
+				if (out.length() > 0 && !Character.isWhitespace(out.charAt(out.length() - 1)))
+					out.append(' ');
+				continue;
+			}
+
+			int n = i;
+			while (n < id.length() && Character.isUpperCase(id.charAt(n))) {
+				n++;
+			}
+			if (n == i)
+				out.append(id.charAt(i));
+			else {
+				boolean tolower = (n - i) == 1;
+				if (i > 0 && !Character.isWhitespace(out.charAt(out.length() - 1)))
+					out.append(' ');
+
+				for (; i < n;) {
+					if (tolower)
+						out.append(Character.toLowerCase(id.charAt(i)));
+					else
+						out.append(id.charAt(i));
+					i++;
+				}
+				i--;
+			}
+		}
+		if (id.startsWith("."))
+			out.append(" *");
+		out.replace(0, 1, Character.toUpperCase(out.charAt(0)) + "");
+		return out.toString();
+	}
+
+}
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..f1afe72
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Constants.java
@@ -0,0 +1,240 @@
+package aQute.lib.osgi;
+
+import java.nio.charset.*;
+import java.util.regex.*;
+
+public interface Constants {
+	/*
+	 * Defined in OSGi
+	 */
+	/**
+	 * @syntax Bundle-ActivationPolicy ::= policy ( ’;’ directive )* policy ::=
+	 *         ’lazy’
+	 */
+	String					BND_ADDXMLTOTEST							= "Bnd-AddXMLToTest";
+	String					BUNDLE_ACTIVATIONPOLICY						= "Bundle-ActivationPolicy";
+	String					BUNDLE_ACTIVATOR							= "Bundle-Activator";
+	String					BUNDLE_BLUEPRINT							= "Bundle-Copyright";
+	String					BUNDLE_CATEGORY								= "Bundle-Category";
+	String					BUNDLE_CLASSPATH							= "Bundle-ClassPath";
+	String					BUNDLE_CONTACTADDRESS						= "Bundle-ContactAddress";
+	String					BUNDLE_COPYRIGHT							= "Bundle-Copyright";
+	String					BUNDLE_DESCRIPTION							= "Bundle-Description";
+	String					BUNDLE_DOCURL								= "Bundle-DocURL";
+	String					BUNDLE_ICON									= "Bundle-Icon";
+	String					BUNDLE_LICENSE								= "Bundle-License";
+	String					BUNDLE_LOCALIZATION							= "Bundle-Localization";
+	String					BUNDLE_MANIFESTVERSION						= "Bundle-ManifestVersion";
+	String					BUNDLE_NAME									= "Bundle-Name";
+	String					BUNDLE_NATIVECODE							= "Bundle-NativeCode";
+	String					BUNDLE_REQUIREDEXECUTIONENVIRONMENT			= "Bundle-RequiredExecutionEnvironment";
+	String					BUNDLE_SYMBOLICNAME							= "Bundle-SymbolicName";
+	String					BUNDLE_UPDATELOCATION						= "Bundle-UpdateLocation";
+	String					BUNDLE_VENDOR								= "Bundle-Vendor";
+	String					BUNDLE_VERSION								= "Bundle-Version";
+	String					DYNAMICIMPORT_PACKAGE						= "DynamicImport-Package";
+	String					EXPORT_PACKAGE								= "Export-Package";
+	String					EXPORT_SERVICE								= "Export-Service";
+	String					FRAGMENT_HOST								= "Fragment-Host";
+	String					IMPORT_PACKAGE								= "Import-Package";
+	String					IMPORT_SERVICE								= "Import-Service";
+	String					REQUIRE_BUNDLE								= "Require-Bundle";
+	String					SERVICE_COMPONENT							= "Service-Component";
+
+	String					PRIVATE_PACKAGE								= "Private-Package";
+	String					IGNORE_PACKAGE								= "Ignore-Package";
+	String					INCLUDE_RESOURCE							= "Include-Resource";
+	String					CONDITIONAL_PACKAGE							= "Conditional-Package";
+	String					BND_LASTMODIFIED							= "Bnd-LastModified";
+	String					CREATED_BY									= "Created-By";
+	String					TOOL										= "Tool";
+	String					TESTCASES									= "Test-Cases";
+	String					SIGNATURE_TEST								= "-signaturetest";
+
+	String					headers[]									= { BUNDLE_ACTIVATOR,
+			BUNDLE_CONTACTADDRESS, BUNDLE_COPYRIGHT, BUNDLE_DESCRIPTION, BUNDLE_DOCURL,
+			BUNDLE_LOCALIZATION, BUNDLE_NATIVECODE, BUNDLE_VENDOR, BUNDLE_VERSION, BUNDLE_LICENSE,
+			BUNDLE_CLASSPATH, SERVICE_COMPONENT, EXPORT_PACKAGE, IMPORT_PACKAGE,
+			BUNDLE_LOCALIZATION, BUNDLE_MANIFESTVERSION, BUNDLE_NAME, BUNDLE_NATIVECODE,
+			BUNDLE_REQUIREDEXECUTIONENVIRONMENT, BUNDLE_SYMBOLICNAME, BUNDLE_VERSION,
+			FRAGMENT_HOST, PRIVATE_PACKAGE, IGNORE_PACKAGE, INCLUDE_RESOURCE, REQUIRE_BUNDLE,
+			IMPORT_SERVICE, EXPORT_SERVICE, CONDITIONAL_PACKAGE, BND_LASTMODIFIED, TESTCASES,
+			SIGNATURE_TEST												};
+
+	String					BUILDPATH									= "-buildpath";
+	String					BUILDPACKAGES								= "-buildpackages";
+	String					BUMPPOLICY									= "-bumppolicy";
+	String					CONDUIT										= "-conduit";
+	String					COMPILER_SOURCE								= "-source";
+	String					COMPILER_TARGET								= "-target";
+	String					DEPENDSON									= "-dependson";
+	String					DEPLOY										= "-deploy";
+	String					DEPLOYREPO									= "-deployrepo";
+	String					DONOTCOPY									= "-donotcopy";
+	String					DEBUG										= "-debug";
+	String					EXPORT_CONTENTS								= "-exportcontents";
+	String					FAIL_OK										= "-failok";
+	String					INCLUDE										= "-include";
+	String					INCLUDERESOURCE								= "-includeresource";
+	String					MAKE										= "-make";
+	String					METATYPE									= "-metatype";
+	String					MANIFEST									= "-manifest";
+	String					SAVEMANIFEST								= "-savemanifest";
+	String					NODEFAULTVERSION							= "-nodefaultversion";
+	String					NOEXTRAHEADERS								= "-noextraheaders";
+	String					NOMANIFEST									= "-nomanifest";
+	String					NOUSES										= "-nouses";
+	@Deprecated String		NOPE										= "-nope";
+	String					NOBUNDLES									= "-nobundles";
+	String					PEDANTIC									= "-pedantic";
+	String					PLUGIN										= "-plugin";
+	String					POM											= "-pom";
+	String					RELEASEREPO									= "-releaserepo";
+	String					REMOVEHEADERS								= "-removeheaders";
+	String					RESOURCEONLY								= "-resourceonly";
+	String					SOURCES										= "-sources";
+	String					SOURCEPATH									= "-sourcepath";
+	String					SUB											= "-sub";
+	String					RUNPROPERTIES								= "-runproperties";
+	String					RUNSYSTEMPACKAGES							= "-runsystempackages";
+	String					RUNBUNDLES									= "-runbundles";
+	String					RUNPATH										= "-runpath";
+	String					RUNSTORAGE									= "-runstorage";
+	String					RUNBUILDS									= "-runbuilds";
+	String					RUNPATH_MAIN_DIRECTIVE						= "main:";
+	String					RUNPATH_LAUNCHER_DIRECTIVE					= "launcher:";
+	String					RUNVM										= "-runvm";
+	String					RUNTRACE									= "-runtrace";
+	String					RUNFRAMEWORK								= "-runframework";
+	String					RUNTIMEOUT									= "-runtimeout";
+	String					SNAPSHOT									= "-snapshot";
+	String					RUNFRAMEWORK_SERVICES						= "services";
+	String					RUNFRAMEWORK_NONE							= "none";
+	String					REPORTNEWER									= "-reportnewer";
+	String					SIGN										= "-sign";
+	String					TESTPACKAGES								= "-testpackages";
+	String					TESTREPORT									= "-testreport";
+	String					TESTPATH									= "-testpath";
+	String					TESTCONTINUOUS								= "-testcontinuous";
+	String					UNDERTEST									= "-undertest";
+	String					VERBOSE										= "-verbose";
+	@Deprecated String		VERSIONPOLICY_IMPL							= "-versionpolicy-impl";
+	@Deprecated String		VERSIONPOLICY_USES							= "-versionpolicy-uses";
+	String					PROVIDER_POLICY								= "-provider-policy";
+	String					CONSUMER_POLICY								= "-consumer-policy";
+	@Deprecated String		VERSIONPOLICY								= "-versionpolicy";
+	String					WAB											= "-wab";
+	String					WABLIB										= "-wablib";
+	String					REQUIRE_BND									= "-require-bnd";
+
+	// Deprecated
+	String					CLASSPATH									= "-classpath";
+
+	String					options[]									= { BUILDPATH, BUMPPOLICY,
+			CONDUIT, CLASSPATH, CONSUMER_POLICY, DEPENDSON, DONOTCOPY, EXPORT_CONTENTS, FAIL_OK,
+			INCLUDE, INCLUDERESOURCE, MAKE, MANIFEST, NOEXTRAHEADERS, NOUSES, NOBUNDLES, PEDANTIC,
+			PLUGIN, POM, PROVIDER_POLICY, REMOVEHEADERS, RESOURCEONLY, SOURCES, SOURCEPATH,
+			SOURCES, SOURCEPATH, SUB, RUNBUNDLES, RUNPATH, RUNSYSTEMPACKAGES, RUNPROPERTIES,
+			REPORTNEWER, UNDERTEST, TESTPATH, TESTPACKAGES, TESTREPORT, VERBOSE, NOMANIFEST,
+			DEPLOYREPO, RELEASEREPO, SAVEMANIFEST, RUNVM, WAB, WABLIB, RUNFRAMEWORK, RUNTRACE,
+			TESTCONTINUOUS, SNAPSHOT												};
+
+	// Ignore bundle specific headers. These bundles do not make
+	// a lot of sense to inherit
+	String[]				BUNDLE_SPECIFIC_HEADERS						= new String[] {
+			INCLUDE_RESOURCE, BUNDLE_ACTIVATOR, BUNDLE_CLASSPATH, BUNDLE_NAME, BUNDLE_NATIVECODE,
+			BUNDLE_SYMBOLICNAME, IMPORT_PACKAGE, EXPORT_PACKAGE, DYNAMICIMPORT_PACKAGE,
+			FRAGMENT_HOST, REQUIRE_BUNDLE, PRIVATE_PACKAGE, EXPORT_CONTENTS, TESTCASES, NOMANIFEST,
+			SIGNATURE_TEST, WAB, WABLIB								};
+
+	char					DUPLICATE_MARKER							= '~';
+	String					SPECIFICATION_VERSION						= "specification-version";
+	String					SPLIT_PACKAGE_DIRECTIVE						= "-split-package:";
+	String					IMPORT_DIRECTIVE							= "-import:";
+	String					NO_IMPORT_DIRECTIVE							= "-noimport:";
+	String					REMOVE_ATTRIBUTE_DIRECTIVE					= "-remove-attribute:";
+	String					LIB_DIRECTIVE								= "lib:";
+	String					NOANNOTATIONS								= "-noannotations";
+	String					COMMAND_DIRECTIVE							= "command:";
+	String					USES_DIRECTIVE								= "uses:";
+	String					MANDATORY_DIRECTIVE							= "mandatory:";
+	String					INCLUDE_DIRECTIVE							= "include:";
+	String					PROVIDE_DIRECTIVE							= "provide:";
+	String					EXCLUDE_DIRECTIVE							= "exclude:";
+	String					PRESENCE_DIRECTIVE							= "presence:";
+	String					PRIVATE_DIRECTIVE							= "private:";
+	String					SINGLETON_DIRECTIVE							= "singleton:";
+	String					EXTENSION_DIRECTIVE							= "extension:";
+	String					VISIBILITY_DIRECTIVE						= "visibility:";
+	String					FRAGMENT_ATTACHMENT_DIRECTIVE				= "fragment-attachment:";
+	String					RESOLUTION_DIRECTIVE						= "resolution:";
+	String					PATH_DIRECTIVE								= "path:";
+	String					SIZE_ATTRIBUTE								= "size";
+	String					LINK_ATTRIBUTE								= "link";
+	String					NAME_ATTRIBUTE								= "name";
+	String					DESCRIPTION_ATTRIBUTE						= "description";
+	String					OSNAME_ATTRIBUTE							= "osname";
+	String					OSVERSION_ATTRIBUTE							= "osversion";
+	String					PROCESSOR_ATTRIBUTE							= "processor";
+	String					LANGUAGE_ATTRIBUTE							= "language";
+	String					SELECTION_FILTER_ATTRIBUTE					= "selection-filter";
+	String					BLUEPRINT_WAIT_FOR_DEPENDENCIES_ATTRIBUTE	= "blueprint.wait-for-dependencies";
+	String					BLUEPRINT_TIMEOUT_ATTRIBUTE					= "blueprint.timeout";
+	String					VERSION_ATTRIBUTE							= "version";
+	String					BUNDLE_SYMBOLIC_NAME_ATTRIBUTE				= "bundle-symbolic-name";
+	String					BUNDLE_VERSION_ATTRIBUTE					= "bundle-version";
+	String					FROM_DIRECTIVE								= "from:";
+
+	String					KEYSTORE_LOCATION_DIRECTIVE					= "keystore:";
+	String					KEYSTORE_PROVIDER_DIRECTIVE					= "provider:";
+	String					KEYSTORE_PASSWORD_DIRECTIVE					= "password:";
+	String					SIGN_PASSWORD_DIRECTIVE						= "sign-password:";
+
+	String					NONE										= "none";
+
+	String					directives[]								= {
+			SPLIT_PACKAGE_DIRECTIVE, NO_IMPORT_DIRECTIVE, IMPORT_DIRECTIVE, RESOLUTION_DIRECTIVE,
+			INCLUDE_DIRECTIVE, USES_DIRECTIVE, EXCLUDE_DIRECTIVE, KEYSTORE_LOCATION_DIRECTIVE,
+			KEYSTORE_PROVIDER_DIRECTIVE, KEYSTORE_PASSWORD_DIRECTIVE, SIGN_PASSWORD_DIRECTIVE,
+			COMMAND_DIRECTIVE, NOANNOTATIONS, LIB_DIRECTIVE, RUNPATH_LAUNCHER_DIRECTIVE,
+			FROM_DIRECTIVE, PRIVATE_DIRECTIVE
+
+																		// TODO
+																		};
+
+	String					USES_USES									= "<<USES>>";
+	String					CURRENT_USES								= "@uses";
+	String					IMPORT_REFERENCE							= "reference";
+	String					IMPORT_PRIVATE								= "private";
+	String[]				importDirectives							= { IMPORT_REFERENCE,
+			IMPORT_PRIVATE												};
+
+	static final Pattern	VALID_PROPERTY_TYPES						= Pattern
+																				.compile("(String|Long|Double|Float|Integer|Byte|Character|Boolean|Short)");
+
+	String					DEFAULT_BND_EXTENSION						= ".bnd";
+	String					DEFAULT_JAR_EXTENSION						= ".jar";
+	String					DEFAULT_BAR_EXTENSION						= ".bar";
+	String					DEFAULT_BNDRUN_EXTENSION					= ".bndrun";
+	String[]				METAPACKAGES								= { "META-INF", "OSGI-INF",
+			"OSGI-OPT"													};
+
+	String					CURRENT_VERSION								= "@";
+	String					CURRENT_PACKAGE								= "@package";
+
+	String					BUILDFILES									= "buildfiles";
+
+	String					EMPTY_HEADER								= "<<EMPTY>>";
+
+	String					EMBEDDED_REPO								= "/embedded-repo.jar";
+	String					LAUNCHER_PLUGIN								= "Launcher-Plugin";
+	String					TESTER_PLUGIN								= "Tester-Plugin";
+
+	String					DEFAULT_LAUNCHER_BSN						= "biz.aQute.launcher";
+	String					DEFAULT_TESTER_BSN							= "biz.aQute.junit";
+
+	String					DEFAULT_DO_NOT_COPY							= "CVS|\\.svn|\\.git|\\.DS_Store";
+
+	Charset					DEFAULT_CHARSET								= Charset.forName("UTF8");
+	String					VERSION_FILTER	= "version";
+}
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..cb302da
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/EmbeddedResource.java
@@ -0,0 +1,86 @@
+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 Exception {
+			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..4c57321
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/FileResource.java
@@ -0,0 +1,84 @@
+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 Exception {
+		copy(this, out);
+	}
+
+	static synchronized void copy(Resource resource, OutputStream out)
+			throws Exception {
+		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 != null && 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..f466f57
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java
@@ -0,0 +1,130 @@
+package aQute.lib.osgi;
+
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.libg.generics.*;
+
+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;
+    }
+
+    public static Map<Instruction, Map<String, String>> replaceWithInstruction(
+            Map<String, Map<String, String>> header) {
+        Map<Instruction, Map<String, String>> map = Processor.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 = getPattern(pattern);
+            String presence = entry.getValue()
+                    .get(Constants.PRESENCE_DIRECTIVE);
+            if ("optional".equals(presence))
+                instr.setOptional();
+            map.put(instr, entry.getValue());
+        }
+        return map;
+    }
+
+    public static <T> Collection<T> select(Collection<Instruction> matchers,
+            Collection<T> targets) {
+        Collection<T> result = Create.list();
+        outer: for (T t : targets) {
+            String s = t.toString();
+            for (Instruction i : matchers) {
+                if (i.matches(s)) {
+                    if (!i.isNegated())
+                        result.add(t);
+                    continue outer;
+                }
+            }
+        }
+        return result;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/InstructionFilter.java b/bundleplugin/src/main/java/aQute/lib/osgi/InstructionFilter.java
new file mode 100644
index 0000000..83f85ee
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/InstructionFilter.java
@@ -0,0 +1,37 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.regex.*;
+
+public class InstructionFilter implements FileFilter {
+
+	private Instruction instruction;
+	private boolean recursive;
+	private Pattern doNotCopy;
+	
+	public InstructionFilter (Instruction instruction, boolean recursive, Pattern doNotCopy) {
+		this.instruction = instruction;
+		this.recursive = recursive;
+		this.doNotCopy = doNotCopy;
+	}
+	public InstructionFilter (Instruction instruction, boolean recursive) {
+		this(instruction, recursive, Pattern.compile(Constants.DEFAULT_DO_NOT_COPY));
+	}
+	public boolean isRecursive() {
+		return recursive;
+	}
+	public boolean accept(File pathname) {
+		if (doNotCopy != null && doNotCopy.matcher(pathname.getName()).matches()) {
+			return false;
+		}
+
+		if (pathname.isDirectory() && isRecursive()) {
+			return true;
+		}
+		
+		if (instruction == null) {
+			return true;
+		}
+		return !instruction.isNegated() == instruction.matches(pathname.getName());
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java b/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
new file mode 100644
index 0000000..c8b2359
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
@@ -0,0 +1,690 @@
+package aQute.lib.osgi;
+
+import static aQute.lib.io.IO.*;
+
+import java.io.*;
+import java.security.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+import java.util.zip.*;
+
+import aQute.lib.base64.*;
+import aQute.libg.reporter.*;
+
+public class Jar implements Closeable {
+	public static final Object[]		EMPTY_ARRAY	= new Jar[0];
+	Map<String, Resource>				resources	= new TreeMap<String, Resource>();
+	Map<String, Map<String, Resource>>	directories	= new TreeMap<String, Map<String, Resource>>();
+	Manifest							manifest;
+	boolean								manifestFirst;
+	String								name;
+	File								source;
+	ZipFile								zipFile;
+	long								lastModified;
+	String								lastModifiedReason;
+	Reporter							reporter;
+	boolean								doNotTouchManifest;
+	boolean								nomanifest;
+
+	public Jar(String name) {
+		this.name = name;
+	}
+
+	public Jar(String name, File dirOrFile, Pattern doNotCopy) throws ZipException, IOException {
+		this(name);
+		source = dirOrFile;
+		if (dirOrFile.isDirectory())
+			FileResource.build(this, dirOrFile, doNotCopy);
+		else if (dirOrFile.isFile()) {
+			zipFile = ZipResource.build(this, dirOrFile);
+		} else {
+			throw new IllegalArgumentException("A Jar can only accept a valid file or directory: "
+					+ 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 f) throws IOException {
+		this(getName(f), f, null);
+	}
+
+	/**
+	 * 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 Jar(String string, File file) throws ZipException, IOException {
+		this(string, file, Pattern.compile(Constants.DEFAULT_DO_NOT_COPY));
+	}
+
+	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);
+		while (path.startsWith("/"))
+			path = path.substring(1);
+
+		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 Exception {
+		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 Exception {
+		ZipOutputStream jout = nomanifest || doNotTouchManifest ? new ZipOutputStream(out)
+				: new JarOutputStream(out);
+		Set<String> done = new HashSet<String>();
+
+		Set<String> directories = new HashSet<String>();
+		if (doNotTouchManifest) {
+			Resource r = getResource("META-INF/MANIFEST.MF");
+			if (r != null) {
+				writeResource(jout, directories, "META-INF/MANIFEST.MF", r);
+				done.add("META-INF/MANIFEST.MF");
+			}
+		} else
+			doManifest(done, jout);
+
+		for (Map.Entry<String, Resource> entry : getResources().entrySet()) {
+			// Skip metainf contents
+			if (!done.contains(entry.getKey()))
+				writeResource(jout, directories, (String) entry.getKey(),
+						(Resource) entry.getValue());
+		}
+		jout.finish();
+	}
+
+	private void doManifest(Set<String> done, ZipOutputStream jout) throws Exception {
+		if (nomanifest)
+			return;
+
+		JarEntry ze = new JarEntry("META-INF/MANIFEST.MF");
+		jout.putNextEntry(ze);
+		writeManifest(jout);
+		jout.closeEntry();
+		done.add(ze.getName());
+	}
+
+	/**
+	 * Cleanup the manifest for writing. Cleaning up consists of adding a space
+	 * after any \n to prevent the manifest to see this newline as a delimiter.
+	 * 
+	 * @param out
+	 *            Output
+	 * @throws IOException
+	 */
+
+	public void writeManifest(OutputStream out) throws Exception {
+		writeManifest(getManifest(), out);
+	}
+
+	public static void writeManifest(Manifest manifest, OutputStream out) throws IOException {
+		if (manifest == null)
+			return;
+
+		manifest = clean(manifest);
+		outputManifest(manifest, out);
+	}
+
+	/**
+	 * Unfortunately we have to write our own manifest :-( because of a stupid
+	 * bug in the manifest code. It tries to handle UTF-8 but the way it does it
+	 * it makes the bytes platform dependent.
+	 * 
+	 * So the following code outputs the manifest.
+	 * 
+	 * A Manifest consists of
+	 * 
+	 * <pre>
+	 *   'Manifest-Version: 1.0\r\n'
+	 *   main-attributes *
+	 *   \r\n
+	 *   name-section
+	 *   
+	 *   main-attributes ::= attributes
+	 *   attributes      ::= key ': ' value '\r\n'
+	 *   name-section    ::= 'Name: ' name '\r\n' attributes
+	 * </pre>
+	 * 
+	 * Lines in the manifest should not exceed 72 bytes (! this is where the
+	 * manifest screwed up as well when 16 bit unicodes were used).
+	 * 
+	 * <p>
+	 * As a bonus, we can now sort the manifest!
+	 */
+	static byte[]	CONTINUE	=  new byte[] {'\r','\n', ' '};
+
+	/**
+	 * Main function to output a manifest properly in UTF-8.
+	 * 
+	 * @param manifest
+	 *            The manifest to output
+	 * @param out
+	 *            The output stream
+	 * @throws IOException
+	 *             when something fails
+	 */
+	public static void outputManifest(Manifest manifest, OutputStream out) throws IOException {
+		writeEntry(out, "Manifest-Version", "1.0");
+		attributes(manifest.getMainAttributes(), out);
+
+		TreeSet<String> keys = new TreeSet<String>();
+		for (Object o : manifest.getEntries().keySet())
+			keys.add(o.toString());
+
+		for (String key : keys) {
+			write(out, 0, "\r\n");
+			writeEntry(out, "Name", key);
+			attributes(manifest.getAttributes(key), out);
+		}
+	}
+
+	/**
+	 * Write out an entry, handling proper unicode and line length constraints
+	 * 
+	 */
+	private static void writeEntry(OutputStream out, String name, String value) throws IOException {
+		int n = write(out, 0, name + ": ");
+		n = write(out, n, value);
+		write(out, 0, "\r\n");
+	}
+
+	/**
+	 * Convert a string to bytes with UTF8 and then output in max 72 bytes
+	 * 
+	 * @param out
+	 *            the output string
+	 * @param i
+	 *            the current width
+	 * @param s
+	 *            the string to output
+	 * @return the new width
+	 * @throws IOException
+	 *             when something fails
+	 */
+	private static int write(OutputStream out, int i, String s) throws IOException {
+		byte[] bytes = s.getBytes("UTF8");
+		return write(out, i, bytes);
+	}
+
+	/**
+	 * Write the bytes but ensure that the line length does not exceed 72
+	 * characters. If it is more than 70 characters, we just put a cr/lf +
+	 * space.
+	 * 
+	 * @param out
+	 *            The output stream
+	 * @param width
+	 *            The nr of characters output in a line before this method
+	 *            started
+	 * @param bytes
+	 *            the bytes to output
+	 * @return the nr of characters in the last line
+	 * @throws IOException
+	 *             if something fails
+	 */
+	private static int write(OutputStream out, int width, byte[] bytes) throws IOException {
+		for (int i = 0; i < bytes.length; i++) {
+			if (width >= 72) { // we need to add the \n\r!
+				out.write(CONTINUE);
+				width = 1;
+			}
+			out.write(bytes[i]);
+			width++;
+		}
+		return width;
+	}
+
+	/**
+	 * Output an Attributes map. We will sort this map before outputing.
+	 * 
+	 * @param value
+	 *            the attrbutes
+	 * @param out
+	 *            the output stream
+	 * @throws IOException
+	 *             when something fails
+	 */
+	private static void attributes(Attributes value, OutputStream out) throws IOException {
+		TreeMap<String, String> map = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+		for (Map.Entry<Object, Object> entry : value.entrySet()) {
+			map.put(entry.getKey().toString(), entry.getValue().toString());
+		}
+
+		map.remove("Manifest-Version"); // get rid of
+		// manifest
+		// version
+		for (Map.Entry<String, String> entry : map.entrySet()) {
+			writeEntry(out, entry.getKey(), entry.getValue());
+		}
+	}
+
+	private static Manifest clean(Manifest org) {
+
+		Manifest result = new Manifest();
+		for (Map.Entry<?, ?> entry : org.getMainAttributes().entrySet()) {
+			String nice = clean((String) entry.getValue());
+			result.getMainAttributes().put(entry.getKey(), nice);
+		}
+		for (String name : org.getEntries().keySet()) {
+			Attributes attrs = result.getAttributes(name);
+			if (attrs == null) {
+				attrs = new Attributes();
+				result.getEntries().put(name, attrs);
+			}
+
+			for (Map.Entry<?, ?> entry : org.getAttributes(name).entrySet()) {
+				String nice = clean((String) entry.getValue());
+				attrs.put((Attributes.Name) entry.getKey(), nice);
+			}
+		}
+		return result;
+	}
+
+	private static String clean(String s) {
+		if (s.indexOf('\n') < 0)
+			return s;
+
+		StringBuffer sb = new StringBuffer(s);
+		for (int i = 0; i < sb.length(); i++) {
+			if (sb.charAt(i) == '\n')
+				sb.insert(++i, ' ');
+		}
+		return sb.toString();
+	}
+
+	private void writeResource(ZipOutputStream jout, Set<String> directories, String path,
+			Resource resource) throws Exception {
+		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);
+		resource.write(jout);
+		jout.closeEntry();
+	}
+
+	void createDirectories(Set<String> directories, ZipOutputStream zip, String name)
+			throws IOException {
+		int index = name.lastIndexOf('/');
+		if (index > 0) {
+			String path = name.substring(0, index);
+			if (directories.contains(path))
+				return;
+			createDirectories(directories, zip, path);
+			ZipEntry ze = new ZipEntry(path + '/');
+			zip.putNextEntry(ze);
+			zip.closeEntry();
+			directories.add(path);
+		}
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Add all the resources in the given jar that match the given filter.
+	 * 
+	 * @param sub
+	 *            the jar
+	 * @param filter
+	 *            a pattern that should match the resoures in sub to be added
+	 */
+	public boolean addAll(Jar sub, Instruction filter) {
+		return addAll(sub, filter, "");
+	}
+
+	/**
+	 * 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, Instruction filter, String destination) {
+		boolean dupl = false;
+		for (String name : sub.getResources().keySet()) {
+			if ("META-INF/MANIFEST.MF".equals(name))
+				continue;
+
+			if (filter == null || filter.matches(name) != filter.isNegated())
+				dupl |= putResource(Processor.appendPath(destination, 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 (Map.Entry<String, Map<String, Resource>> i : directories.entrySet()) {
+			if (i.getValue() != null) {
+				String path = i.getKey();
+				String pack = path.replace('/', '.');
+				list.add(pack);
+			}
+		}
+		return list;
+	}
+
+	public File getSource() {
+		return source;
+	}
+
+	public boolean addAll(Jar src) {
+		return addAll(src, null);
+	}
+
+	public boolean rename(String oldPath, String newPath) {
+		Resource resource = remove(oldPath);
+		if (resource == null)
+			return false;
+
+		return putResource(newPath, resource);
+	}
+
+	public Resource remove(String path) {
+		Resource resource = resources.remove(path);
+		String dir = getDirectory(path);
+		Map<String, Resource> mdir = directories.get(dir);
+		// must be != null
+		mdir.remove(path);
+		return resource;
+	}
+
+	/**
+	 * Make sure nobody touches the manifest! If the bundle is signed, we do not
+	 * want anybody to touch the manifest after the digests have been
+	 * calculated.
+	 */
+	public void setDoNotTouchManifest() {
+		doNotTouchManifest = true;
+	}
+
+	/**
+	 * Calculate the checksums and set them in the manifest.
+	 */
+
+	public void calcChecksums(String algorithms[]) throws Exception {
+		if (algorithms == null)
+			algorithms = new String[] { "SHA", "MD5" };
+
+		Manifest m = getManifest();
+		if ( m == null) {
+			m= new Manifest();
+			setManifest(m);
+		}
+		
+		MessageDigest digests[] = new MessageDigest[algorithms.length];
+		int n = 0;
+		for (String algorithm : algorithms)
+			digests[n++] = MessageDigest.getInstance(algorithm);
+
+		byte buffer[] = new byte[30000];
+
+		for (Map.Entry<String, Resource> entry : resources.entrySet()) {
+			
+			// Skip the manifest
+			if (entry.getKey().equals("META-INF/MANIFEST.MF"))
+				continue;
+
+			Resource r = entry.getValue();
+			Attributes attributes = m.getAttributes(entry.getKey());
+			if (attributes == null) {
+				attributes = new Attributes();
+				getManifest().getEntries().put(entry.getKey(), attributes);
+			}
+			InputStream in = r.openInputStream();
+			try {
+				for (MessageDigest d : digests)
+					d.reset();
+				int size = in.read(buffer);
+				while (size > 0) {
+					for (MessageDigest d : digests)
+						d.update(buffer, 0, size);
+					size = in.read(buffer);
+				}
+			} finally {
+				in.close();
+			}
+			for (MessageDigest d : digests)
+				attributes.putValue(d.getAlgorithm() + "-Digest", Base64.encodeBase64(d.digest()));
+		}
+	}
+
+	Pattern	BSN	= Pattern.compile("\\s*([-\\w\\d\\._]+)\\s*;?.*");
+
+	public String getBsn() throws Exception {
+		Manifest m = getManifest();
+		if (m == null)
+			return null;
+
+		String s = m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
+		Matcher matcher = BSN.matcher(s);
+		if (matcher.matches()) {
+			return matcher.group(1);
+		}
+		return null;
+	}
+
+	public String getVersion() throws Exception {
+		Manifest m = getManifest();
+		if (m == null)
+			return null;
+
+		String s = m.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
+		if (s == null)
+			return null;
+
+		return s.trim();
+	}
+
+	/**
+	 * Expand the JAR file to a directory.
+	 * 
+	 * @param dir
+	 *            the dst directory, is not required to exist
+	 * @throws Exception
+	 *             if anything does not work as expected.
+	 */
+	public void expand(File dir) throws Exception {
+		dir = dir.getAbsoluteFile();
+		dir.mkdirs();
+		if (!dir.isDirectory()) {
+			throw new IllegalArgumentException("Not a dir: " + dir.getAbsolutePath());
+		}
+
+		for (Map.Entry<String, Resource> entry : getResources().entrySet()) {
+			File f = getFile(dir, entry.getKey());
+			f.getParentFile().mkdirs();
+			copy(entry.getValue().openInputStream(), f);
+		}
+	}
+
+	/**
+	 * Make sure we have a manifest
+	 * @throws Exception
+	 */
+	public void ensureManifest() throws Exception {
+		if ( getManifest() != null)
+			return;
+		manifest = new Manifest();
+	}
+
+}
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..706094f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/JarResource.java
@@ -0,0 +1,46 @@
+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 Exception {
+		jar.write(out);
+	}
+	
+	public InputStream openInputStream() throws Exception {
+		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;
+	}
+	
+	public String toString() {
+	    return ":" + jar.getName() + ":";
+	}
+
+}
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..d18a2a2
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Macro.java
@@ -0,0 +1,952 @@
+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.lib.io.*;
+import aQute.libg.sed.*;
+import aQute.libg.version.*;
+
+/**
+ * Provide a macro processor. This processor can replace variables in strings
+ * based on a properties and a domain. The domain can implement functions that
+ * start with a "_" and take args[], the names of these functions are available
+ * as functions in the macro processor (without the _). Macros can nest to any
+ * depth but may not contain loops.
+ * 
+ * Add POSIX macros:
+ * ${#parameter}
+    String length.
+
+${parameter%word}
+    Remove smallest suffix pattern.
+
+${parameter%%word}
+    Remove largest suffix pattern.
+
+${parameter#word}
+    Remove smallest prefix pattern.
+
+${parameter##word}
+    Remove largest prefix pattern. 
+ */
+public class Macro implements Replacer {
+	Processor	domain;
+	Object		targets[];
+	boolean		flattening;
+
+	public Macro(Processor domain, Object... targets) {
+		this.domain = domain;
+		this.targets = targets;
+		if (targets != null) {
+			for (Object o : targets) {
+				assert o != null;
+			}
+		}
+	}
+
+	public String process(String line, Processor source) {
+		return process(line, new Link(source,null,line));
+	}
+
+	String process(String line, Link link) {
+		StringBuffer sb = new StringBuffer();
+		process(line, 0, '\u0000', '\u0000', sb, link);
+		return sb.toString();
+	}
+
+	int process(CharSequence org, int index, char begin, char end, StringBuffer result, Link link) {
+		StringBuilder line = new StringBuilder(org);
+		int nesting = 1;
+
+		StringBuffer variable = new StringBuffer();
+		outer: while (index < line.length()) {
+			char c1 = line.charAt(index++);
+			if (c1 == end) {
+				if (--nesting == 0) {
+					result.append(replace(variable.toString(), link));
+					return index;
+				}
+			} else if (c1 == begin)
+				nesting++;
+			else if (c1 == '\\' && index < line.length() - 1 && line.charAt(index) == '$') {
+				// remove the escape backslash and interpret the dollar as a
+				// literal
+				index++;
+				variable.append('$');
+				continue outer;
+			} else if (c1 == '$' && index < line.length() - 2) {
+				char c2 = line.charAt(index);
+				char terminator = getTerminator(c2);
+				if (terminator != 0) {
+					index = process(line, index + 1, c2, terminator, variable, link);
+					continue outer;
+				}
+			}
+			variable.append(c1);
+		}
+		result.append(variable);
+		return index;
+	}
+
+	public static char getTerminator(char c) {
+		switch (c) {
+		case '(':
+			return ')';
+		case '[':
+			return ']';
+		case '{':
+			return '}';
+		case '<':
+			return '>';
+		case '\u00ab': // Guillemet double << >>
+			return '\u00bb';
+		case '\u2039': // Guillemet single
+			return '\u203a';
+		}
+		return 0;
+	}
+
+	protected String replace(String key, Link link) {
+		if (link != null && link.contains(key))
+			return "${infinite:" + link.toString() + "}";
+
+		if (key != null) {
+			key = key.trim();
+			if (key.length() > 0) {
+				Processor source = domain;
+				String value = null;
+				while( source != null) {
+					value = source.getProperties().getProperty(key);
+					if ( value != null )
+						break;
+					
+					source = source.getParent();
+				}
+				
+				if (value != null)
+					return process(value, new Link(source,link, key));
+
+				value = doCommands(key, link);
+				if (value != null)
+					return process(value, new Link(source, 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, Link source) {
+		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("\\\\;", ";");
+
+		
+		if ( args[0].startsWith("^")) {
+			String varname = args[0].substring(1).trim();
+			
+			Processor parent = source.start.getParent();
+			if ( parent != null)
+				return parent.getProperty(varname);
+			else
+				return null;
+		}
+		
+		
+		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) {
+				if ( e.getCause() instanceof IllegalArgumentException ) {
+					domain.error("%s, for cmd: %s, arguments; %s", e.getMessage(), method, Arrays.toString(args));
+				} else {
+					domain.warning("Exception in replace: " + e.getCause());
+					e.getCause().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 _pathseparator(String args[]) {
+		return File.pathSeparator;
+	}
+
+	public String _separator(String args[]) {
+		return File.separator;
+	}
+
+	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");
+
+		return domain.getProperty(args[1], "");
+	}
+
+	/**
+	 * 
+	 * replace ; <list> ; regex ; replace
+	 * 
+	 * @param args
+	 * @return
+	 */
+	public String _replace(String args[]) {
+		if (args.length != 4) {
+			domain.warning("Invalid nr of arguments to replace " + Arrays.asList(args));
+			return null;
+		}
+
+		String list[] = args[1].split("\\s*,\\s*");
+		StringBuffer sb = new StringBuffer();
+		String del = "";
+		for (int i = 0; i < list.length; i++) {
+			String element = list[i].trim();
+			if (!element.equals("")) {
+				sb.append(del);
+				sb.append(element.replaceAll(args[2], args[3]));
+				del = ", ";
+			}
+		}
+
+		return sb.toString();
+	}
+
+	public String _warning(String args[]) {
+		for (int i = 1; i < args.length; i++) {
+			domain.warning(process(args[i]));
+		}
+		return "";
+	}
+
+	public String _error(String args[]) {
+		for (int i = 1; i < args.length; i++) {
+			domain.error(process(args[i]));
+		}
+		return "";
+	}
+
+	/**
+	 * toclassname ; <path>.class ( , <path>.class ) *
+	 * 
+	 * @param args
+	 * @return
+	 */
+	static String	_toclassnameHelp	= "${classname;<list of class names>}, convert class paths to FQN class names ";
+
+	public String _toclassname(String args[]) {
+		verifyCommand(args, _toclassnameHelp, null, 2, 2);
+		Collection<String> paths = Processor.split(args[1]);
+
+		List<String> names = new ArrayList<String>(paths.size());
+		for (String path : paths) {
+			if (path.endsWith(".class")) {
+				String name = path.substring(0, path.length() - 6).replace('/', '.');
+				names.add(name);
+			} else if (path.endsWith(".java")) {
+				String name = path.substring(0, path.length() - 5).replace('/', '.');
+				names.add(name);
+			} else {
+				domain.warning("in toclassname, " + args[1]
+						+ " is not a class path because it does not end in .class");
+			}
+		}
+		return Processor.join(names, ",");
+	}
+
+	/**
+	 * toclassname ; <path>.class ( , <path>.class ) *
+	 * 
+	 * @param args
+	 * @return
+	 */
+
+	static String	_toclasspathHelp	= "${toclasspath;<list>[;boolean]}, convert a list of class names to paths";
+
+	public String _toclasspath(String args[]) {
+		verifyCommand(args, _toclasspathHelp, null, 2, 3);
+		boolean cl = true;
+		if (args.length > 2)
+			cl = new Boolean(args[2]);
+
+		Collection<String> names = Processor.split(args[1]);
+		Collection<String> paths = new ArrayList<String>(names.size());
+		for (String name : names) {
+			String path = name.replace('.', '/') + (cl ? ".class" : "");
+			paths.add(path);
+		}
+		return Processor.join(paths, ",");
+	}
+
+	public String _dir(String args[]) {
+		if (args.length < 2) {
+			domain.warning("Need at least one file name for ${dir;...}");
+			return null;
+		} else {
+			String del = "";
+			StringBuffer sb = new StringBuffer();
+			for (int i = 1; i < args.length; i++) {
+				File f = domain.getFile(args[i]);
+				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 = domain.getFile(args[i]);
+				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
+	 * 
+	 * ${lsr;<dir>;<list>(;<list>)*} ${lsa;<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 = domain.getFile(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
+	 */
+	final static String		MASK_STRING			= "[\\-+=~0123456789]{0,3}[=~]?";
+	final static Pattern	MASK				= Pattern.compile(MASK_STRING);
+	final static String		_versionHelp		= "${version;<mask>;<version>}, modify a version\n"
+														+ "<mask> ::= [ M [ M [ M [ MQ ]]]\n"
+														+ "M ::= '+' | '-' | MQ\n"
+														+ "MQ ::= '~' | '='";
+	final static Pattern	_versionPattern[]	= new Pattern[] { null, null, MASK,
+			Verifier.VERSION					};
+
+	public String _version(String args[]) {
+		verifyCommand(args, _versionHelp, null, 2, 3);
+
+		String mask = args[1];
+
+		Version version = null;
+		if (args.length >= 3)
+			version = new Version(args[2]);
+
+		return version(version, mask);
+	}
+
+	String version(Version version, String mask) {
+		if (version == null) {
+			String v = domain.getProperty("@");
+			if (v == null) {
+				domain
+						.error(
+								"No version specified for ${version} or ${range} and no implicit version ${@} either, mask=%s",
+								mask);
+				v = "0";
+			}
+			version = new Version(v);
+		}
+
+		StringBuilder sb = new StringBuilder();
+		String del = "";
+
+		for (int i = 0; i < mask.length(); i++) {
+			char c = mask.charAt(i);
+			String result = null;
+			if (c != '~') {
+				if (i == 3) {
+					result = version.getQualifier();
+				} else if (Character.isDigit(c)) {
+					// Handle masks like +00, =+0
+					result = String.valueOf(c);
+				} else {
+					int x = version.get(i);
+					switch (c) {
+					case '+':
+						x++;
+						break;
+					case '-':
+						x--;
+						break;
+					case '=':
+						break;
+					}
+					result = Integer.toString(x);
+				}
+				if (result != null) {
+					sb.append(del);
+					del = ".";
+					sb.append(result);
+				}
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Schortcut for version policy
+	 * 
+	 * <pre>
+	 * -provide-policy : ${policy;[==,=+)}
+	 * -consume-policy : ${policy;[==,+)}
+	 * </pre>
+	 * 
+	 * @param args
+	 * @return
+	 */
+
+	static Pattern	RANGE_MASK		= Pattern.compile("(\\[|\\()(" + MASK_STRING + "),(" + MASK_STRING +")(\\]|\\))");
+	static String	_rangeHelp		= "${range;<mask>[;<version>]}, range for version, if version not specified lookyp ${@}\n"
+											+ "<mask> ::= [ M [ M [ M [ MQ ]]]\n"
+											+ "M ::= '+' | '-' | MQ\n" + "MQ ::= '~' | '='";
+	static Pattern	_rangePattern[]	= new Pattern[] { null, RANGE_MASK };
+
+	public String _range(String args[]) {
+		verifyCommand(args, _rangeHelp, _rangePattern, 2, 3);
+		Version version = null;
+		if (args.length >= 3)
+			version = new Version(args[2]);
+
+		String spec = args[1];
+
+		Matcher m = RANGE_MASK.matcher(spec);
+		m.matches();
+		String floor = m.group(1);
+		String floorMask = m.group(2);
+		String ceilingMask = m.group(3);
+		String ceiling = m.group(4);
+
+		StringBuilder sb = new StringBuilder();
+		sb.append(floor);
+		sb.append(version(version, floorMask));
+		sb.append(",");
+		sb.append(version(version, ceilingMask));
+		sb.append(ceiling);
+
+		String s = sb.toString();
+		VersionRange vr = new VersionRange(s);
+		if (!(vr.includes(vr.getHigh()) || vr.includes(vr.getLow()))) {
+			domain.error("${range} macro created an invalid range %s from %s and mask %s", s,
+					version, spec);
+		}
+		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 = IO.collect(process.getInputStream(), "UTF-8");
+		int exitValue = process.waitFor();
+		if (exitValue != 0) {
+			domain.error("System command " + command + " failed with " + exitValue);
+		}
+		return s.trim();
+	}
+
+	public String _env(String args[]) {
+		verifyCommand(args, "${env;<name>}, get the environmet variable", null, 2, 2);
+
+		try {
+			return System.getenv(args[1]);
+		} catch (Throwable t) {
+			return null;
+		}
+	}
+
+	/**
+	 * 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()) {
+			return IO.collect(f);
+		} else if (f.isDirectory()) {
+			return Arrays.toString(f.list());
+		} else {
+			try {
+				URL url = new URL(args[1]);
+				return IO.collect(url, "UTF-8");
+			} catch (MalformedURLException mfue) {
+				// Ignore here
+			}
+			return null;
+		}
+	}
+
+	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; i++) {
+				if (patterns[i] != null) {
+					Matcher m = patterns[i].matcher(args[i]);
+					if (!m.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;
+		Processor start;
+
+		public Link(Processor start, Link previous, String key) {
+			this.previous = previous;
+			this.key = key;
+			this.start = start;
+		}
+
+		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();
+			Properties source = domain.getProperties();
+			for (Enumeration<?> e = source.propertyNames(); e.hasMoreElements();) {
+				String key = (String) e.nextElement();
+				if (!key.startsWith("_"))
+					if (key.startsWith("-"))
+						flattened.put(key, source.getProperty(key));
+					else
+						flattened.put(key, process(source.getProperty(key)));
+			}
+			return flattened;
+		} finally {
+			flattening = false;
+		}
+	};
+
+	public static String	_fileHelp	= "${file;<base>;<paths>...}, create correct OS dependent path";
+
+	public String _osfile(String args[]) {
+		verifyCommand(args, _fileHelp, null, 3, 3);
+		File base = new File(args[1]);
+		File f = Processor.getFile(base, args[2]);
+		return f.getAbsolutePath();
+	}
+
+	public String _path(String args[]) {
+		List<String> list = new ArrayList<String>();
+		for (int i = 1; i < args.length; i++) {
+			list.addAll(Processor.split(args[i]));
+		}
+		return Processor.join(list, File.pathSeparator);
+	}
+
+	public static Properties getParent(Properties p) {
+		try {
+			Field f = Properties.class.getDeclaredField("defaults");
+			f.setAccessible(true);
+			return (Properties) f.get(p);
+		} catch (Exception e) {
+			Field[] fields = Properties.class.getFields();
+			System.out.println(Arrays.toString(fields));
+			return null;
+		}
+	}
+
+	public String process(String line) {
+		return process(line,domain);
+	}
+
+}
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..e77f811
--- /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 Exception {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream(2000);
+        OutputStreamWriter osw = new OutputStreamWriter(bout, Constants.DEFAULT_CHARSET);
+        PrintWriter pw = new PrintWriter(osw);
+        InputStream in = resource.openInputStream();
+        try {
+            BufferedReader rdr = new BufferedReader(new InputStreamReader(in,"UTF8"));
+            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..b2352f0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java
@@ -0,0 +1,1373 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.io.*;
+import aQute.libg.generics.*;
+import aQute.libg.header.*;
+import aQute.libg.reporter.*;
+
+public class Processor implements Reporter, Registry, Constants, Closeable {
+	static ThreadLocal<Processor>	current			= new ThreadLocal<Processor>();
+	static ExecutorService			executor		= Executors.newCachedThreadPool();
+	static Random					random			= new Random();
+
+	// TODO handle include files out of date
+	// TODO make splitter skip eagerly whitespace so trim is not necessary
+	public static String			LIST_SPLITTER	= "\\s*,\\s*";
+	final List<String>				errors			= new ArrayList<String>();
+	final List<String>				warnings		= new ArrayList<String>();
+	final Set<Object>				basicPlugins	= new HashSet<Object>();
+	final Set<Closeable>			toBeClosed		= new HashSet<Closeable>();
+	Set<Object>						plugins;
+
+	boolean							pedantic;
+	boolean							trace;
+	boolean							exceptions;
+	boolean							fileMustExist	= true;
+
+	private File					base			= new File("").getAbsoluteFile();
+
+	Properties						properties;
+	private Macro					replacer;
+	private long					lastModified;
+	private File					propertiesFile;
+	private boolean					fixup			= true;
+	long							modified;
+	Processor						parent;
+	Set<File>						included;
+	CL								pluginLoader;
+	Collection<String>				filter;
+	HashSet<String>					missingCommand;
+
+	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;
+		Properties ext = new Properties(processor.properties);
+		ext.putAll(this.properties);
+		this.properties = ext;
+	}
+
+	public Processor getParent() {
+		return parent;
+	}
+
+	public Processor getTop() {
+		if (parent == null)
+			return this;
+		else
+			return parent.getTop();
+	}
+
+	public void getInfo(Processor processor, String prefix) {
+		if (isFailOk())
+			addAll(warnings, processor.getErrors(), prefix);
+		else
+			addAll(errors, processor.getErrors(), prefix);
+		addAll(warnings, processor.getWarnings(), prefix);
+
+		processor.errors.clear();
+		processor.warnings.clear();
+	}
+
+	public void getInfo(Processor processor) {
+		getInfo(processor, "");
+	}
+
+	private <T> void addAll(List<String> to, List<? extends T> from, String prefix) {
+		for (T x : from) {
+			to.add(prefix + x);
+		}
+	}
+
+	/**
+	 * A processor can mark itself current for a thread.
+	 * 
+	 * @return
+	 */
+	private Processor current() {
+		Processor p = current.get();
+		if (p == null)
+			return this;
+		else
+			return p;
+	}
+
+	public void warning(String string, Object... args) {
+		Processor p = current();
+		String s = String.format(string, args);
+		if (!p.warnings.contains(s))
+			p.warnings.add(s);
+	}
+
+	public void error(String string, Object... args) {
+		Processor p = current();
+		if (p.isFailOk())
+			p.warning(string, args);
+		else {
+			String s = String.format(string, args);
+			if (!p.errors.contains(s))
+				p.errors.add(s);
+		}
+	}
+
+	public void error(String string, Throwable t, Object... args) {
+		Processor p = current();
+
+		if (p.isFailOk())
+			p.warning(string + ": " + t, args);
+		else {
+			p.errors.add("Exception: " + t.getMessage());
+			String s = String.format(string, args);
+			if (!p.errors.contains(s))
+				p.errors.add(s);
+		}
+		if (p.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
+	 */
+	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) {
+		trace(s, args);
+	}
+
+	public boolean isPedantic() {
+		return current().pedantic;
+	}
+
+	public void setPedantic(boolean pedantic) {
+		this.pedantic = pedantic;
+	}
+
+	public static File getFile(File base, String file) {
+		return IO.getFile(base, file);
+	}
+
+	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>();
+		Set<Object> all = getPlugins();
+		for (Object plugin : all) {
+			if (clazz.isInstance(plugin))
+				l.add(clazz.cast(plugin));
+		}
+		return l;
+	}
+
+	/**
+	 * Returns the first plugin it can find of the given type.
+	 * 
+	 * @param <T>
+	 * @param clazz
+	 * @return
+	 */
+	public <T> T getPlugin(Class<T> clazz) {
+		Set<Object> all = getPlugins();
+		for (Object plugin : all) {
+			if (clazz.isInstance(plugin))
+				return clazz.cast(plugin);
+		}
+		return null;
+	}
+
+	/**
+	 * Return a list of plugins. Plugins are defined with the -plugin command.
+	 * They are class names, optionally associated with attributes. Plugins can
+	 * implement the Plugin interface to see these attributes.
+	 * 
+	 * Any object can be a plugin.
+	 * 
+	 * @return
+	 */
+	protected synchronized Set<Object> getPlugins() {
+		if (this.plugins != null)
+			return this.plugins;
+
+		missingCommand = new HashSet<String>();
+		Set<Object> list = new LinkedHashSet<Object>();
+
+		// The owner of the plugin is always in there.
+		list.add(this);
+		setTypeSpecificPlugins(list);
+
+		if (parent != null)
+			list.addAll(parent.getPlugins());
+
+		// We only use plugins now when they are defined on our level
+		// and not if it is in our parent. We inherit from our parent
+		// through the previous block.
+
+		if (properties.containsKey(PLUGIN)) {
+			String spe = getProperty(PLUGIN);
+			if (spe.equals(NONE))
+				return new LinkedHashSet<Object>();
+
+			loadPlugins(list, spe);
+		}
+
+		return this.plugins = list;
+	}
+
+	/**
+	 * @param list
+	 * @param spe
+	 */
+	protected void loadPlugins(Set<Object> list, String spe) {
+		Map<String, Map<String, String>> plugins = parseHeader(spe);
+		for (Map.Entry<String, Map<String, String>> entry : plugins.entrySet()) {
+			String key = (String) entry.getKey();
+
+			try {
+				CL loader = getLoader();
+				String path = entry.getValue().get(PATH_DIRECTIVE);
+				if (path != null) {
+					String parts[] = path.split("\\s*,\\s*");
+					for (String p : parts) {
+						File f = getFile(p).getAbsoluteFile();
+						loader.add(f.toURI().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);
+
+				try {
+					Class<?> c = (Class<?>) loader.loadClass(key);
+					Object plugin = c.newInstance();
+					customize(plugin, entry.getValue());
+					list.add(plugin);
+				} catch (Throwable t) {
+					// We can defer the error if the plugin specifies
+					// a command name. In that case, we'll verify that
+					// a bnd file does not contain any references to a
+					// plugin
+					// command. The reason this feature was added was
+					// to compile plugin classes with the same build.
+					String commands = entry.getValue().get(COMMAND_DIRECTIVE);
+					if (commands == null)
+						error("Problem loading the plugin: %s exception: (%s)", key, t);
+					else {
+						Collection<String> cs = split(commands);
+						missingCommand.addAll(cs);
+					}
+				}
+			} catch (Throwable e) {
+				error("Problem loading the plugin: " + key + " exception: " + e);
+			}
+		}
+	}
+
+	protected void setTypeSpecificPlugins(Set<Object> list) {
+		list.add(executor);
+		list.add(random);
+		list.addAll(basicPlugins);
+	}
+
+	/**
+	 * @param plugin
+	 * @param entry
+	 */
+	protected <T> T customize(T plugin, Map<String, String> map) {
+		if (plugin instanceof Plugin) {
+			if (map != null)
+				((Plugin) plugin).setProperties(map);
+
+			((Plugin) plugin).setReporter(this);
+		}
+		if (plugin instanceof RegistryPlugin) {
+			((RegistryPlugin) plugin).setRegistry(this);
+		}
+		return plugin;
+	}
+
+	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) {
+		Processor p = current();
+		if (p.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.clear();
+	}
+
+	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);
+		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
+	 * @throws IOException
+	 */
+
+	private void doIncludes(File ubase, Properties p) {
+		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() && fileMustExist) {
+						error("Included file " + file
+								+ (file.exists() ? " does not exist" : " is directory"));
+					} else
+						doIncludeFile(file, overwrite, p);
+				} catch (Exception e) {
+					if (fileMustExist)
+						error("Error in processing included file: " + value, e);
+				}
+			}
+		}
+	}
+
+	/**
+	 * @param file
+	 * @param parent
+	 * @param done
+	 * @param overwrite
+	 * @throws FileNotFoundException
+	 * @throws IOException
+	 */
+	public void doIncludeFile(File file, boolean overwrite, Properties target) throws Exception {
+		if (included != null && included.contains(file)) {
+			error("Cyclic or multiple include of " + file);
+		} else {
+			addIncluded(file);
+			updateModified(file.lastModified(), file.toString());
+			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);
+			// make sure we do not override properties
+			for (Map.Entry<?, ?> entry : sub.entrySet()) {
+				if (overwrite || !target.containsKey(entry.getKey()))
+					target.setProperty((String) entry.getKey(), (String) entry.getValue());
+			}
+		}
+	}
+
+	public void unsetProperty(String string) {
+		getProperties().remove(string);
+
+	}
+
+	public boolean refresh() {
+		plugins = null; // We always refresh our plugins
+
+		if (propertiesFile == null)
+			return false;
+
+		updateModified(propertiesFile.lastModified(), "properties file");
+		boolean changed = false;
+		if (included != null) {
+			for (File file : included) {
+
+				if (file.exists() == false || file.lastModified() > modified) {
+					updateModified(file.lastModified(), "include file: " + file);
+					changed = true;
+				}
+			}
+		}
+
+		// System.out.println("Modified " + modified + " file: "
+		// + propertiesFile.lastModified() + " diff "
+		// + (modified - propertiesFile.lastModified()));
+
+		// Date last = new Date(propertiesFile.lastModified());
+		// Date current = new Date(modified);
+		changed |= modified < propertiesFile.lastModified();
+		if (changed) {
+			included = null;
+			properties.clear();
+			setProperties(propertiesFile, base);
+			propertiesChanged();
+			return true;
+		}
+		return false;
+	}
+
+	public void propertiesChanged() {
+	}
+
+	/**
+	 * Set the properties by file. Setting the properties this way will also set
+	 * the base for this analyzer. After reading the properties, this will call
+	 * setProperties(Properties) which will handle the includes.
+	 * 
+	 * @param propertiesFile
+	 * @throws FileNotFoundException
+	 * @throws IOException
+	 */
+	public void setProperties(File propertiesFile) throws IOException {
+		propertiesFile = propertiesFile.getAbsoluteFile();
+		setProperties(propertiesFile, propertiesFile.getParentFile());
+	}
+
+	public void setProperties(File propertiesFile, File base) {
+		this.propertiesFile = propertiesFile.getAbsoluteFile();
+		setBase(base);
+		try {
+			if (propertiesFile.isFile()) {
+				// System.out.println("Loading properties " + propertiesFile);
+				long modified = propertiesFile.lastModified();
+				if (modified > System.currentTimeMillis() + 100) {
+					System.out.println("Huh? This is in the future " + propertiesFile);
+					this.modified = System.currentTimeMillis();
+				} else
+					this.modified = modified;
+
+				included = null;
+				Properties p = loadProperties(propertiesFile);
+				setProperties(p);
+			} else {
+				if (fileMustExist) {
+					error("No such properties file: " + propertiesFile);
+				}
+			}
+		} catch (IOException e) {
+			error("Could not load properties " + propertiesFile);
+		}
+	}
+
+	protected void begin() {
+		if (isTrue(getProperty(PEDANTIC)))
+			setPedantic(true);
+	}
+
+	public static boolean isTrue(String value) {
+		if (value == null)
+			return false;
+
+		return !"false".equalsIgnoreCase(value);
+	}
+
+	/**
+	 * Get a property with a proper default
+	 * 
+	 * @param headerName
+	 * @param deflt
+	 * @return
+	 */
+	public String getProperty(String key, String deflt) {
+		String value = null;
+		Processor source = this;
+
+		if (filter != null && filter.contains(key)) {
+			value = (String) getProperties().get(key);
+		} else {
+			while (source != null) {
+				value = (String) source.getProperties().get(key);
+				if (value != null)
+					break;
+
+				source = source.getParent();
+			}
+		}
+
+		if (value != null)
+			return getReplacer().process(value, source);
+		else if (deflt != null)
+			return getReplacer().process(deflt, this);
+		else
+			return null;
+	}
+
+	/**
+	 * Helper to load a properties file from disk.
+	 * 
+	 * @param file
+	 * @return
+	 * @throws IOException
+	 */
+	public Properties loadProperties(File file) throws IOException {
+		updateModified(file.lastModified(), "Properties file: " + file);
+		InputStream in = new FileInputStream(file);
+		Properties p = loadProperties(in, file.getAbsolutePath());
+		in.close();
+		return p;
+	}
+
+	Properties loadProperties(InputStream in, String name) throws IOException {
+		int n = name.lastIndexOf('/');
+		if (n > 0)
+			name = name.substring(0, n);
+		if (name.length() == 0)
+			name = ".";
+
+		try {
+			Properties p = new Properties();
+			p.load(in);
+			return replaceAll(p, "\\$\\{\\.\\}", name);
+		} catch (Exception e) {
+			error("Error during loading properties file: " + name + ", error:" + e);
+			return new Properties();
+		}
+	}
+
+	/**
+	 * Replace a string in all the values of the map. This can be used to
+	 * preassign variables that change. I.e. the base directory ${.} for a
+	 * loaded properties
+	 */
+
+	public static Properties replaceAll(Properties p, String pattern, String replacement) {
+		Properties result = new Properties();
+		for (Iterator<Map.Entry<Object, Object>> i = p.entrySet().iterator(); i.hasNext();) {
+			Map.Entry<Object, Object> entry = i.next();
+			String key = (String) entry.getKey();
+			String value = (String) entry.getValue();
+			value = value.replaceAll(pattern, replacement);
+			result.put(key, value);
+		}
+		return result;
+	}
+
+	/**
+	 * Merge the attributes of two maps, where the first map can contain
+	 * wildcarded names. The idea is that the first map contains patterns (for
+	 * example *) with a set of attributes. These patterns are matched against
+	 * the found packages in actual. If they match, the result is set with the
+	 * merged set of attributes. It is expected that the instructions are
+	 * ordered so that the instructor can define which pattern matches first.
+	 * Attributes in the instructions override any attributes from the actual.<br/>
+	 * 
+	 * A pattern is a modified regexp so it looks like globbing. The * becomes a
+	 * .* just like the ? becomes a .?. '.' are replaced with \\. Additionally,
+	 * if the pattern starts with an exclamation mark, it will remove that
+	 * matches for that pattern (- the !) from the working set. So the following
+	 * patterns should work:
+	 * <ul>
+	 * <li>com.foo.bar</li>
+	 * <li>com.foo.*</li>
+	 * <li>com.foo.???</li>
+	 * <li>com.*.[^b][^a][^r]</li>
+	 * <li>!com.foo.* (throws away any match for com.foo.*)</li>
+	 * </ul>
+	 * Enough rope to hang the average developer I would say.
+	 * 
+	 * 
+	 * @param instructions
+	 *            the instructions with patterns. A
+	 * @param actual
+	 *            the actual found packages
+	 */
+
+	public static Map<String, Map<String, String>> merge(String type,
+			Map<String, Map<String, String>> instructions, Map<String, Map<String, String>> actual,
+			Set<String> superfluous, Map<String, Map<String, String>> ignored) {
+		Map<String, Map<String, String>> toVisit = new HashMap<String, Map<String, String>>(actual); // we
+		// do
+		// not
+		// want
+		// to
+		// ruin
+		// our
+		// original
+		Map<String, Map<String, String>> result = newMap();
+		for (Iterator<String> i = instructions.keySet().iterator(); i.hasNext();) {
+			String instruction = i.next();
+			String originalInstruction = instruction;
+
+			Map<String, String> instructedAttributes = instructions.get(instruction);
+
+			// Check if we have a fixed (starts with '=') or a
+			// duplicate name. A fixed name is added to the output without
+			// checking against the contents. Duplicates are marked
+			// at the end. In that case we do not pick up any contained
+			// information but just add them to the output including the
+			// marker.
+			if (instruction.startsWith("=")) {
+				result.put(instruction.substring(1), instructedAttributes);
+				superfluous.remove(originalInstruction);
+				continue;
+			}
+			if (isDuplicate(instruction)) {
+				result.put(instruction, instructedAttributes);
+				superfluous.remove(originalInstruction);
+				continue;
+			}
+
+			Instruction instr = Instruction.getPattern(instruction);
+
+			for (Iterator<String> p = toVisit.keySet().iterator(); p.hasNext();) {
+				String packageName = p.next();
+
+				if (instr.matches(packageName)) {
+					superfluous.remove(originalInstruction);
+					if (!instr.isNegated()) {
+						Map<String, String> newAttributes = new HashMap<String, String>();
+						newAttributes.putAll(actual.get(packageName));
+						newAttributes.putAll(instructedAttributes);
+						result.put(packageName, newAttributes);
+					} else if (ignored != null) {
+						ignored.put(packageName, new HashMap<String, String>());
+					}
+					p.remove(); // Can never match again for another pattern
+				}
+			}
+
+		}
+		return result;
+	}
+
+	/**
+	 * Print a standard Map based OSGi header.
+	 * 
+	 * @param exports
+	 *            map { name => Map { attribute|directive => value } }
+	 * @return the clauses
+	 */
+	public static String printClauses(Map<String, Map<String, String>> exports) {
+		return printClauses(exports, false);
+	}
+
+	public static String printClauses(Map<String, Map<String, String>> exports,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,  sb);
+			del = ",";
+		}
+		return sb.toString();
+	}
+
+	public static void printClause(Map<String, String> map, 
+			StringBuffer sb) {
+
+		for (Iterator<String> j = map.keySet().iterator(); j.hasNext();) {
+			String key = j.next();
+
+			// Skip directives we do not recognize
+			if (key.equals(NO_IMPORT_DIRECTIVE) || key.equals(PROVIDE_DIRECTIVE) || key.equals(SPLIT_PACKAGE_DIRECTIVE) || key.equals(FROM_DIRECTIVE))
+				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(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, "UTF8");
+		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) {
+		return join(delimeter, list);
+	}
+
+	public static String join(String delimeter, Collection<?>... list) {
+		StringBuilder sb = new StringBuilder();
+		String del = "";
+		for (Collection<?> l : list) {
+			if (list != null) {
+				for (Object item : l) {
+					sb.append(del);
+					sb.append(item);
+					del = delimeter;
+				}
+			}
+		}
+		return sb.toString();
+	}
+
+	public static String join(Object[] list, String delimeter) {
+		if (list == null)
+			return "";
+		StringBuilder sb = new StringBuilder();
+		String del = "";
+		for (Object item : list) {
+			sb.append(del);
+			sb.append(item);
+			del = delimeter;
+		}
+		return sb.toString();
+	}
+
+	public static String join(Collection<?>... list) {
+		return join(",", list);
+	}
+
+	public static <T> String join(T list[]) {
+		return join(list, ",");
+	}
+
+	public static void split(String s, Collection<String> set) {
+
+		String elements[] = s.trim().split(LIST_SPLITTER);
+		for (String element : elements) {
+			if (element.length() > 0)
+				set.add(element);
+		}
+	}
+
+	public static Collection<String> split(String s) {
+		return split(s, LIST_SPLITTER);
+	}
+
+	public static Collection<String> split(String s, String splitter) {
+		if (s != null)
+			s = s.trim();
+		if (s == null || s.trim().length() == 0)
+			return Collections.emptyList();
+
+		return Arrays.asList(s.split(splitter));
+	}
+
+	public static String merge(String... strings) {
+		ArrayList<String> result = new ArrayList<String>();
+		for (String s : strings) {
+			if (s != null)
+				split(s, result);
+		}
+		return join(result);
+	}
+
+	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);
+		}
+
+		public Class<?> loadClass(String name) throws NoClassDefFoundError {
+			try {
+				Class<?> c = super.loadClass(name);
+				return c;
+			} catch (Throwable t) {
+				StringBuilder sb = new StringBuilder();
+				sb.append(name);
+				sb.append(" not found, parent:  ");
+				sb.append(getParent());
+				sb.append(" urls:");
+				sb.append(Arrays.toString(getURLs()));
+				sb.append(" exception:");
+				sb.append(t);
+				throw new NoClassDefFoundError(sb.toString());
+			}
+		}
+	}
+
+	private CL getLoader() {
+		if (pluginLoader == null) {
+			pluginLoader = new CL();
+		}
+		return pluginLoader;
+	}
+
+	/*
+	 * Check if this is a valid project.
+	 */
+	public boolean exists() {
+		return base != null && base.isDirectory() && propertiesFile != null
+				&& propertiesFile.isFile();
+	}
+
+	public boolean isOk() {
+		return isFailOk() || (getErrors().size() == 0);
+	}
+
+	public boolean isPerfect() {
+		return getErrors().size() == 0 && getWarnings().size() == 0;
+	}
+
+	public void setForceLocal(Collection<String> local) {
+		filter = local;
+	}
+
+	/**
+	 * Answer if the name is a missing plugin's command name. If a bnd file
+	 * contains the command name of a plugin, and that plugin is not available,
+	 * then an error is reported during manifest calculation. This allows the
+	 * plugin to fail to load when it is not needed.
+	 * 
+	 * We first get the plugins to ensure it is properly initialized.
+	 * 
+	 * @param name
+	 * @return
+	 */
+	public boolean isMissingPlugin(String name) {
+		getPlugins();
+		return missingCommand != null && missingCommand.contains(name);
+	}
+
+	/**
+	 * Append two strings to for a path in a ZIP or JAR file. It is guaranteed
+	 * to return a string that does not start, nor ends with a '/', while it is
+	 * properly separated with slashes. Double slashes are properly removed.
+	 * 
+	 * <pre>
+	 *  &quot;/&quot; + &quot;abc/def/&quot; becomes &quot;abc/def&quot;
+	 *  
+	 * &#064;param prefix
+	 * &#064;param suffix
+	 * &#064;return
+	 * 
+	 */
+	public static String appendPath(String... parts) {
+		StringBuilder sb = new StringBuilder();
+		boolean lastSlash = true;
+		for (String part : parts) {
+			for (int i = 0; i < part.length(); i++) {
+				char c = part.charAt(i);
+				if (c == '/') {
+					if (!lastSlash)
+						sb.append('/');
+					lastSlash = true;
+				} else {
+					sb.append(c);
+					lastSlash = false;
+				}
+			}
+			if (!lastSlash & sb.length() > 0) {
+				sb.append('/');
+				lastSlash = true;
+			}
+		}
+		if (lastSlash && sb.length() > 0)
+			sb.deleteCharAt(sb.length() - 1);
+
+		return sb.toString();
+	}
+
+	/**
+	 * Parse the a=b strings and return a map of them.
+	 * 
+	 * @param attrs
+	 * @param clazz
+	 * @return
+	 */
+	public static Map<String, String> doAttrbutes(Object[] attrs, Clazz clazz, Macro macro) {
+		if (attrs == null || attrs.length == 0)
+			return Collections.emptyMap();
+
+		Map<String, String> map = newMap();
+		for (Object a : attrs) {
+			String attr = (String) a;
+			int n = attr.indexOf("=");
+			if (n > 0) {
+				map.put(attr.substring(0, n), macro.process(attr.substring(n + 1)));
+			} else
+				throw new IllegalArgumentException(String.format(
+						"Invalid attribute on package-info.java in %s , %s. Must be <key>=<name> ",
+						clazz, attr));
+		}
+		return map;
+	}
+
+	public static String append(String... strings) {
+		List<String> result = Create.list();
+		for (String s : strings) {
+			result.addAll(split(s));
+		}
+		return join(result);
+	}
+
+	public synchronized Class<?> getClass(String type, File jar) throws Exception {
+		CL cl = getLoader();
+		cl.add(jar.toURI().toURL());
+		return cl.loadClass(type);
+	}
+
+	public boolean isTrace() {
+		return current().trace;
+	}
+
+	public static long getDuration(String tm, long dflt) {
+		if (tm == null)
+			return dflt;
+
+		tm = tm.toUpperCase();
+		TimeUnit unit = TimeUnit.MILLISECONDS;
+		Matcher m = Pattern
+				.compile(
+						"\\s*(\\d+)\\s*(NANOSECONDS|MICROSECONDS|MILLISECONDS|SECONDS|MINUTES|HOURS|DAYS)?")
+				.matcher(tm);
+		if (m.matches()) {
+			long duration = Long.parseLong(tm);
+			String u = m.group(2);
+			if (u != null)
+				unit = TimeUnit.valueOf(u);
+			duration = TimeUnit.MILLISECONDS.convert(duration, unit);
+			return duration;
+		}
+		return dflt;
+	}
+
+	/**
+	 * Generate a random string, which is guaranteed to be a valid Java
+	 * identifier (first character is an ASCII letter, subsequent characters are
+	 * ASCII letters or numbers). Takes an optional parameter for the length of
+	 * string to generate; default is 8 characters.
+	 */
+	public String _random(String[] args) {
+		int numchars = 8;
+		if (args.length > 1) {
+			try {
+				numchars = Integer.parseInt(args[1]);
+			} catch (NumberFormatException e) {
+				throw new IllegalArgumentException(
+						"Invalid character count parameter in ${random} macro.");
+			}
+		}
+
+		if (random == null)
+			random = new Random();
+
+		char[] letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+		char[] alphanums = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+				.toCharArray();
+
+		char[] array = new char[numchars];
+		for (int i = 0; i < numchars; i++) {
+			char c;
+			if (i == 0)
+				c = letters[random.nextInt(letters.length)];
+			else
+				c = alphanums[random.nextInt(alphanums.length)];
+			array[i] = c;
+		}
+
+		return new String(array);
+	}
+
+	/**
+	 * Set the current command thread. This must be balanced with the
+	 * {@link #end(Processor)} method. The method returns the previous command
+	 * owner or null.
+	 * 
+	 * The command owner will receive all warnings and error reports.
+	 */
+
+	protected Processor beginHandleErrors(String message) {
+		trace("begin %s", message);
+		Processor previous = current.get();
+		current.set(this);
+		return previous;
+	}
+
+	/**
+	 * End a command. Will restore the previous command owner.
+	 * 
+	 * @param previous
+	 */
+	protected void endHandleErrors(Processor previous) {
+		trace("end");
+		current.set(previous);
+	}
+
+	public static Executor getExecutor() {
+		return executor;
+	}
+
+	/**
+	 * These plugins are added to the total list of plugins. The separation
+	 * is necessary because the list of plugins is refreshed now and then
+	 * so we need to be able to add them at any moment in time.
+	 * 
+	 * @param plugin
+	 */
+	public synchronized void addBasicPlugin(Object plugin) {
+		basicPlugins.add(plugin);
+		if (plugins != null)
+			plugins.add(plugin);
+	}
+
+	public synchronized void removeBasicPlugin(Object plugin) {
+		basicPlugins.remove(plugin);
+		if (plugins != null)
+			plugins.remove(plugin);
+	}
+}
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..85756d5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Resource.java
@@ -0,0 +1,11 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+
+public interface Resource {
+	InputStream openInputStream() throws Exception ;
+	void write(OutputStream out) throws Exception;
+	long lastModified();
+	void setExtra(String extra);
+	String getExtra();
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/TagResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/TagResource.java
new file mode 100644
index 0000000..a793326
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/TagResource.java
@@ -0,0 +1,56 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+
+import aQute.lib.io.*;
+import aQute.lib.tag.*;
+
+public class TagResource implements Resource {
+	final Tag	tag;
+	String		extra;
+
+	public TagResource(Tag tag) {
+		this.tag = tag;
+	}
+
+	public InputStream openInputStream() throws Exception {
+		final PipedInputStream pin = new PipedInputStream();
+		final PipedOutputStream pout = new PipedOutputStream(pin);
+		Processor.getExecutor().execute(new Runnable() {
+			public void run() {
+				try {
+					write(pout);
+				} catch (Exception e) {
+					e.printStackTrace();
+					// ignore
+				}
+				IO.close(pout);
+			}
+		});
+		return pin;
+	}
+
+	public void write(OutputStream out) throws UnsupportedEncodingException {
+		OutputStreamWriter ow = new OutputStreamWriter(out, "UTF-8");
+		PrintWriter pw = new PrintWriter(ow);
+		pw.println("<?xml version='1.1'?>");
+		try {
+			tag.print(0, pw);
+		} finally {
+			pw.flush();
+		}
+	}
+
+	public long lastModified() {
+		return 0;
+	}
+
+	public void setExtra(String extra) {
+		this.extra = extra;
+	}
+
+	public String getExtra() {
+		return extra;
+	}
+
+}
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..9f0af59
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/URLResource.java
@@ -0,0 +1,37 @@
+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 Exception {
+		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..00cd67e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Verifier.java
@@ -0,0 +1,959 @@
+package aQute.lib.osgi;
+
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.libg.qtokens.*;
+
+public class Verifier extends Analyzer {
+
+    Jar                              dot;
+    Manifest                         manifest;
+    Map<String, Map<String, String>> referred  = newHashMap();
+    Map<String, Map<String, String>> contained = newHashMap();
+    Map<String, Set<String>>         uses      = newHashMap();
+    Map<String, Map<String, String>> mimports;
+    Map<String, Map<String, String>> mdynimports;
+    Map<String, Map<String, String>> mexports;
+    List<Jar>                        bundleClasspath;
+    Map<String, Map<String, String>> ignore    = newHashMap();                                    // Packages
+    // to
+    // ignore
+
+    Map<String, Clazz>               classSpace;
+    boolean                          r3;
+    boolean                          usesRequire;
+    boolean                          fragment;
+    Attributes                       main;
+
+    final static Pattern             EENAME    = Pattern
+                                                       .compile("CDC-1\\.0/Foundation-1\\.0"
+                                                               + "|CDC-1\\.1/Foundation-1\\.1"
+                                                               + "|OSGi/Minimum-1\\.[1-9]"
+                                                               + "|JRE-1\\.1"
+                                                               + "|J2SE-1\\.2"
+                                                               + "|J2SE-1\\.3"
+                                                               + "|J2SE-1\\.4"
+                                                               + "|J2SE-1\\.5"
+                                                               + "|JavaSE-1\\.6"
+                                                               + "|JavaSE-1\\.7"
+                                                               + "|PersonalJava-1\\.1"
+                                                               + "|PersonalJava-1\\.2"
+                                                               + "|CDC-1\\.0/PersonalBasis-1\\.0"
+                                                               + "|CDC-1\\.0/PersonalJava-1\\.0");
+
+    final static int                 V1_1      = 45;
+    final static int                 V1_2      = 46;
+    final static int                 V1_3      = 47;
+    final static int                 V1_4      = 48;
+    final static int                 V1_5      = 49;
+    final static int                 V1_6      = 50;
+    final static int                 V1_7      = 51;
+
+    static class EE {
+        String name;
+        int    target;
+
+        EE(String name, int source, int target) {
+            this.name = name;
+            this.target = target;
+        }
+    }
+
+    final static EE[]           ees                            = {
+            new EE("CDC-1.0/Foundation-1.0", V1_3, V1_1),
+            new EE("CDC-1.1/Foundation-1.1", V1_3, V1_2),
+            new EE("OSGi/Minimum-1.0", V1_3, V1_1),
+            new EE("OSGi/Minimum-1.1", V1_3, V1_2),
+            new EE("JRE-1.1", V1_1, V1_1), //
+            new EE("J2SE-1.2", V1_2, V1_1), //
+            new EE("J2SE-1.3", V1_3, V1_1), //
+            new EE("J2SE-1.4", V1_3, V1_2), //
+            new EE("J2SE-1.5", V1_5, V1_5), //
+            new EE("JavaSE-1.6", V1_6, V1_6),
+            new EE("PersonalJava-1.1", V1_1, V1_1),
+            new EE("PersonalJava-1.2", V1_1, V1_1),
+            new EE("CDC-1.0/PersonalBasis-1.0", V1_3, V1_1),
+            new EE("CDC-1.0/PersonalJava-1.0", V1_3, V1_1),
+            new EE("CDC-1.1/PersonalBasis-1.1", V1_3, V1_2),
+            new EE("CDC-1.1/PersonalJava-1.1", V1_3, V1_2)    };
+
+    final static Pattern        BUNDLEMANIFESTVERSION          = Pattern
+                                                                       .compile("2");
+    public final static String  SYMBOLICNAME_STRING            = "[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*";
+    public final static Pattern SYMBOLICNAME                   = Pattern
+                                                                       .compile(SYMBOLICNAME_STRING);
+
+    public final static String  VERSION_STRING                 = "[0-9]+(\\.[0-9]+(\\.[0-9]+(\\.[0-9A-Za-z_-]+)?)?)?";
+    public final static Pattern VERSION                        = Pattern
+                                                                       .compile(VERSION_STRING);
+    final static Pattern        FILTEROP                       = Pattern
+                                                                       .compile("=|<=|>=|~=");
+    public final static Pattern VERSIONRANGE                   = Pattern
+                                                                       .compile("((\\(|\\[)"
+                                                                               + VERSION_STRING
+                                                                               + ","
+                                                                               + VERSION_STRING
+                                                                               + "(\\]|\\)))|"
+                                                                               + VERSION_STRING);
+    final static Pattern        FILE                           = Pattern
+                                                                       .compile("/?[^/\"\n\r\u0000]+(/[^/\"\n\r\u0000]+)*");
+    final static Pattern        WILDCARDPACKAGE                = Pattern
+                                                                       .compile("((\\p{Alnum}|_)+(\\.(\\p{Alnum}|_)+)*(\\.\\*)?)|\\*");
+    public final static Pattern ISO639                         = Pattern
+                                                                       .compile("[A-Z][A-Z]");
+    public final static Pattern HEADER_PATTERN                 = Pattern
+                                                                       .compile("[A-Za-z0-9][-a-zA-Z0-9_]+");
+    public final static Pattern TOKEN                          = Pattern
+                                                                       .compile("[-a-zA-Z0-9_]+");
+
+    public final static Pattern NUMBERPATTERN                  = Pattern
+                                                                       .compile("\\d+");
+    public final static Pattern PATHPATTERN                    = Pattern
+                                                                       .compile(".*");
+    public final static Pattern FQNPATTERN                     = Pattern
+                                                                       .compile(".*");
+    public final static Pattern URLPATTERN                     = Pattern
+                                                                       .compile(".*");
+    public final static Pattern ANYPATTERN                     = Pattern
+                                                                       .compile(".*");
+    public final static Pattern FILTERPATTERN                  = Pattern
+                                                                       .compile(".*");
+    public final static Pattern TRUEORFALSEPATTERN             = Pattern
+                                                                       .compile("true|false|TRUE|FALSE");
+    public static final Pattern WILDCARDNAMEPATTERN            = Pattern
+                                                                       .compile(".*");
+    public static final Pattern BUNDLE_ACTIVATIONPOLICYPATTERN = Pattern
+                                                                       .compile("lazy");
+
+    public final static String  EES[]                          = {
+            "CDC-1.0/Foundation-1.0", "CDC-1.1/Foundation-1.1",
+            "OSGi/Minimum-1.0", "OSGi/Minimum-1.1", "OSGi/Minimum-1.2",
+            "JRE-1.1", "J2SE-1.2", "J2SE-1.3", "J2SE-1.4", "J2SE-1.5",
+            "JavaSE-1.6", "JavaSE-1.7", "PersonalJava-1.1", "PersonalJava-1.2",
+            "CDC-1.0/PersonalBasis-1.0", "CDC-1.0/PersonalJava-1.0" };
+
+    public final static String  OSNAMES[]                      = {
+            "AIX", // IBM
+            "DigitalUnix", // Compaq
+            "Embos", // Segger Embedded Software Solutions
+            "Epoc32", // SymbianOS Symbian OS
+            "FreeBSD", // Free BSD
+            "HPUX", // hp-ux Hewlett Packard
+            "IRIX", // Silicon Graphics
+            "Linux", // Open source
+            "MacOS", // Apple
+            "NetBSD", // Open source
+            "Netware", // Novell
+            "OpenBSD", // Open source
+            "OS2", // OS/2 IBM
+            "QNX", // procnto QNX
+            "Solaris", // Sun (almost an alias of SunOS)
+            "SunOS", // Sun Microsystems
+            "VxWorks", // WindRiver Systems
+            "Windows95", "Win32", "Windows98", "WindowsNT", "WindowsCE",
+            "Windows2000", // Win2000
+            "Windows2003", // Win2003
+            "WindowsXP", "WindowsVista",                      };
+
+    public final static String  PROCESSORNAMES[]               = { "68k", // Motorola
+            // 68000
+            "ARM_LE", // Intel Strong ARM. Deprecated because it does not
+            // specify the endianness. See the following two rows.
+            "arm_le", // Intel Strong ARM Little Endian mode
+            "arm_be", // Intel String ARM Big Endian mode
+            "Alpha", //
+            "ia64n",// Hewlett Packard 32 bit
+            "ia64w",// Hewlett Packard 64 bit mode
+            "Ignite", // psc1k PTSC
+            "Mips", // SGI
+            "PArisc", // Hewlett Packard
+            "PowerPC", // power ppc Motorola/IBM Power PC
+            "Sh4", // Hitachi
+            "Sparc", // SUN
+            "Sparcv9", // SUN
+            "S390", // IBM Mainframe 31 bit
+            "S390x", // IBM Mainframe 64-bit
+            "V850E", // NEC V850E
+            "x86", // pentium i386
+            "i486", // i586 i686 Intel& AMD 32 bit
+            "x86-64",                                         };
+
+    Properties                  properties;
+
+    public Verifier(Jar jar) throws Exception {
+        this(jar, null);
+    }
+
+    public Verifier(Jar jar, Properties properties) throws Exception {
+        this.dot = jar;
+        this.properties = properties;
+        this.manifest = jar.getManifest();
+        if (manifest == null) {
+            manifest = new Manifest();
+            error("This file contains no manifest and is therefore not a bundle");
+        }
+        main = this.manifest.getMainAttributes();
+        verifyHeaders(main);
+        r3 = getHeader(Analyzer.BUNDLE_MANIFESTVERSION) == null;
+        usesRequire = getHeader(Analyzer.REQUIRE_BUNDLE) != null;
+        fragment = getHeader(Analyzer.FRAGMENT_HOST) != null;
+
+        bundleClasspath = getBundleClassPath();
+        mimports = parseHeader(manifest.getMainAttributes().getValue(
+                Analyzer.IMPORT_PACKAGE));
+        mdynimports = parseHeader(manifest.getMainAttributes().getValue(
+                Analyzer.DYNAMICIMPORT_PACKAGE));
+        mexports = parseHeader(manifest.getMainAttributes().getValue(
+                Analyzer.EXPORT_PACKAGE));
+
+        ignore = parseHeader(manifest.getMainAttributes().getValue(
+                Analyzer.IGNORE_PACKAGE));
+    }
+
+    public Verifier() {
+        // TODO Auto-generated constructor stub
+    }
+
+    private void verifyHeaders(Attributes main) {
+        for (Object element : main.keySet()) {
+            Attributes.Name header = (Attributes.Name) element;
+            String h = header.toString();
+            if (!HEADER_PATTERN.matcher(h).matches())
+                error("Invalid Manifest header: " + h + ", pattern="
+                        + HEADER_PATTERN);
+        }
+    }
+
+    private List<Jar> getBundleClassPath() {
+        List<Jar> list = newList();
+        String bcp = getHeader(Analyzer.BUNDLE_CLASSPATH);
+        if (bcp == null) {
+            list.add(dot);
+        } else {
+            Map<String, Map<String, String>> entries = parseHeader(bcp);
+            for (Map.Entry<String, Map<String, String>> ex : entries.entrySet()) {
+                String jarOrDir = ex.getKey();
+                if (jarOrDir.equals(".")) {
+                    list.add(dot);
+                } else {
+                    if (jarOrDir.equals("/"))
+                        jarOrDir = "";
+                    if (jarOrDir.endsWith("/")) {
+                        error("Bundle-Classpath directory must not end with a slash: "
+                                + jarOrDir);
+                        jarOrDir = jarOrDir.substring(0, jarOrDir.length() - 1);
+                    }
+
+                    Resource resource = dot.getResource(jarOrDir);
+                    if (resource != null) {
+                        try {
+                            Jar sub = new Jar(jarOrDir);
+                            addClose(sub);
+                            EmbeddedResource.build(sub, resource);
+                            if (!jarOrDir.endsWith(".jar"))
+                                warning("Valid JAR file on Bundle-Classpath does not have .jar extension: "
+                                        + jarOrDir);
+                            list.add(sub);
+                        } catch (Exception e) {
+                            error("Invalid embedded JAR file on Bundle-Classpath: "
+                                    + jarOrDir + ", " + e);
+                        }
+                    } else if (dot.getDirectories().containsKey(jarOrDir)) {
+                        if (r3)
+                            error("R3 bundles do not support directories on the Bundle-ClassPath: "
+                                    + jarOrDir);
+
+                        try {
+                            Jar sub = new Jar(jarOrDir);
+                            addClose(sub);
+                            for (Map.Entry<String, Resource> entry : dot
+                                    .getResources().entrySet()) {
+                                if (entry.getKey().startsWith(jarOrDir))
+                                    sub.putResource(entry.getKey().substring(
+                                            jarOrDir.length() + 1), entry
+                                            .getValue());
+                            }
+                            list.add(sub);
+                        } catch (Exception e) {
+                            error("Invalid embedded directory file on Bundle-Classpath: "
+                                    + jarOrDir + ", " + e);
+                        }
+                    } else {
+                        // Map<String, String> info = ex.getValue();
+                        // if (! "optional".equals(
+                        // info.get(RESOLUTION_DIRECTIVE)))
+                        // warning("Cannot find a file or directory for
+                        // Bundle-Classpath entry: %s",
+                        // 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 boolean verifyFilter(String value) {
+        try {
+            verifyFilter(value, 0);
+            return true;
+        } catch (Exception e) {
+            error("Not a valid filter: " + value + e.getMessage());
+            return false;
+        }
+    }
+
+    private void verifyActivator() {
+        String bactivator = getHeader("Bundle-Activator");
+        if (bactivator != null) {
+            Clazz cl = loadClass(bactivator);
+            if (cl == null) {
+                int n = bactivator.lastIndexOf('.');
+                if (n > 0) {
+                    String pack = bactivator.substring(0, n);
+                    if (mimports.containsKey(pack))
+                        return;
+                    error("Bundle-Activator not found on the bundle class path nor in imports: "
+                            + bactivator);
+                } else
+                    error("Activator uses default package and is not local (default package can not be imported): "
+                            + bactivator);
+            }
+        }
+    }
+
+    private Clazz loadClass(String className) {
+        String path = className.replace('.', '/') + ".class";
+        return (Clazz) classSpace.get(path);
+    }
+
+    private void verifyComponent() {
+        String serviceComponent = getHeader("Service-Component");
+        if (serviceComponent != null) {
+            Map<String, Map<String, String>> map = parseHeader(serviceComponent);
+            for (String component : map.keySet()) {
+                if (component.indexOf("*") < 0 && !dot.exists(component)) {
+                    error("Service-Component entry can not be located in JAR: "
+                            + component);
+                } else {
+                    // validate component ...
+                }
+            }
+        }
+    }
+
+    public void info() {
+        System.out.println("Refers                           : " + referred);
+        System.out.println("Contains                         : " + contained);
+        System.out.println("Manifest Imports                 : " + mimports);
+        System.out.println("Manifest Exports                 : " + mexports);
+    }
+
+    /**
+     * Invalid exports are exports mentioned in the manifest but not found on
+     * the classpath. This can be calculated with: exports - contains.
+     * 
+     * Unfortunately, we also must take duplicate names into account. These
+     * duplicates are of course no erroneous.
+     */
+    private void verifyInvalidExports() {
+        Set<String> invalidExport = newSet(mexports.keySet());
+        invalidExport.removeAll(contained.keySet());
+
+        // We might have duplicate names that are marked for it. These
+        // should not be counted. Should we test them against the contained
+        // set? Hmm. If someone wants to hang himself by using duplicates than
+        // I guess he can go ahead ... This is not a recommended practice
+        for (Iterator<String> i = invalidExport.iterator(); i.hasNext();) {
+            String pack = i.next();
+            if (isDuplicate(pack))
+                i.remove();
+        }
+
+        if (!invalidExport.isEmpty())
+            error("Exporting packages that are not on the Bundle-Classpath"
+                    + bundleClasspath + ": " + invalidExport);
+    }
+
+    /**
+     * Invalid imports are imports that we never refer to. They can be
+     * calculated by removing the refered packages from the imported packages.
+     * This leaves packages that the manifest imported but that we never use.
+     */
+    private void verifyInvalidImports() {
+        Set<String> invalidImport = newSet(mimports.keySet());
+        invalidImport.removeAll(referred.keySet());
+        // TODO Added this line but not sure why it worked before ...
+        invalidImport.removeAll(contained.keySet());
+        String bactivator = getHeader(Analyzer.BUNDLE_ACTIVATOR);
+        if (bactivator != null) {
+            int n = bactivator.lastIndexOf('.');
+            if (n > 0) {
+                invalidImport.remove(bactivator.substring(0, n));
+            }
+        }
+        if (isPedantic() && !invalidImport.isEmpty())
+            warning("Importing packages that are never refered to by any class on the Bundle-Classpath"
+                    + bundleClasspath + ": " + invalidImport);
+    }
+
+    /**
+     * Check for unresolved imports. These are referals that are not imported by
+     * the manifest and that are not part of our bundle classpath. The are
+     * calculated by removing all the imported packages and contained from the
+     * refered packages.
+     */
+    private void verifyUnresolvedReferences() {
+        Set<String> unresolvedReferences = new TreeSet<String>(referred
+                .keySet());
+        unresolvedReferences.removeAll(mimports.keySet());
+        unresolvedReferences.removeAll(contained.keySet());
+
+        // Remove any java.** packages.
+        for (Iterator<String> p = unresolvedReferences.iterator(); p.hasNext();) {
+            String pack = p.next();
+            if (pack.startsWith("java.") || ignore.containsKey(pack))
+                p.remove();
+            else {
+                // Remove any dynamic imports
+                if (isDynamicImport(pack))
+                    p.remove();
+            }
+        }
+
+        if (!unresolvedReferences.isEmpty()) {
+            // Now we want to know the
+            // classes that are the culprits
+            Set<String> culprits = new HashSet<String>();
+            for (Clazz clazz : classSpace.values()) {
+                if (hasOverlap(unresolvedReferences, clazz.getReferred()))
+                    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 Exception {
+        if (classSpace == null)
+            classSpace = analyzeBundleClasspath(dot,
+                    parseHeader(getHeader(Analyzer.BUNDLE_CLASSPATH)),
+                    contained, referred, uses);
+        
+        
+        verifyDirectives("Export-Package", "uses:|mandatory:|include:|exclude:|" + IMPORT_DIRECTIVE);
+        verifyDirectives("Import-Package", "resolution:");
+        verifyDirectives("Require-Bundle", "visibility:|resolution:");
+        verifyDirectives("Fragment-Host", "resolution:");
+        verifyDirectives("Provide-Capability", "effective:|uses:");
+        verifyDirectives("Require-Capability", "effective:|resolve:|filter:");
+        verifyDirectives("Bundle-SymbolicName", "singleton:|fragment-attachment:|mandatory:");
+        
+        
+        verifyManifestFirst();
+        verifyActivator();
+        verifyActivationPolicy();
+        verifyComponent();
+        verifyNative();
+        verifyInvalidExports();
+        verifyInvalidImports();
+        verifyUnresolvedReferences();
+        verifySymbolicName();
+        verifyListHeader("Bundle-RequiredExecutionEnvironment", EENAME, false);
+        verifyHeader("Bundle-ManifestVersion", BUNDLEMANIFESTVERSION, false);
+        verifyHeader("Bundle-Version", VERSION, true);
+        verifyListHeader("Bundle-Classpath", FILE, false);
+        verifyDynamicImportPackage();
+        verifyBundleClasspath();
+        verifyUses();
+        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");
+            }
+        }
+    }
+
+    /**
+     * Verify if the header does not contain any other directives
+     * 
+     * @param header
+     * @param directives
+     */
+    private void verifyDirectives(String header, String directives) {
+    	Pattern pattern = Pattern.compile(directives);
+    	Map<String,Map<String,String>> map = parseHeader(manifest.getMainAttributes().getValue(header));
+    	for ( Map.Entry<String, Map<String,String>> entry : map.entrySet()) {
+    		for ( String key : entry.getValue().keySet()) {
+    			if ( key.endsWith(":")) {
+    				if ( ! key.startsWith("x-")) {
+    					Matcher m = pattern.matcher(key);
+    					if ( m.matches())
+    						continue;
+    					
+    					warning("Unknown directive %s in %s, allowed directives are %s, and 'x-*'.", key, header, directives.replace('|', ','));
+    				}
+    			}
+    		}
+    	}
+	}
+
+	/**
+     * Verify the use clauses
+     */
+    private void verifyUses() {
+    }
+
+    public boolean verifyActivationPolicy() {
+        String policy = getHeader(Constants.BUNDLE_ACTIVATIONPOLICY);
+        if (policy == null)
+            return true;
+
+        return verifyActivationPolicy(policy);
+    }
+
+    public boolean verifyActivationPolicy(String policy) {
+        Map<String, Map<String, String>> map = parseHeader(policy);
+        if (map.size() == 0)
+            warning("Bundle-ActivationPolicy is set but has no argument %s",
+                    policy);
+        else if (map.size() > 1)
+            warning("Bundle-ActivationPolicy has too many arguments %s", policy);
+        else {
+            Map<String, String> s = map.get("lazy");
+            if (s == null)
+                warning(
+                        "Bundle-ActivationPolicy set but is not set to lazy: %s",
+                        policy);
+            else
+                return true;
+        }
+
+        return false;
+    }
+
+    public void verifyBundleClasspath() {
+        Map<String, Map<String, String>> bcp = parseHeader(getHeader(Analyzer.BUNDLE_CLASSPATH));
+        if (bcp.isEmpty() || bcp.containsKey("."))
+            return;
+
+        for ( String path : bcp.keySet() ) {
+            if ( path.endsWith("/"))
+                error("A Bundle-ClassPath entry must not end with '/': %s", path);
+            
+            if ( dot.getDirectories().containsKey(path))
+                // We assume that any classes are in a directory
+                // and therefore do not care when the bundle is included
+                return;
+        }
+        
+        for (String path : dot.getResources().keySet()) {
+            if (path.endsWith(".class")) {
+                warning("The Bundle-Classpath does not contain the actual bundle JAR (as specified with '.' in the Bundle-Classpath) but the JAR does contain classes. Is this intentional?");
+                return;
+            }
+        }
+    }
+
+    /**
+     * <pre>
+     *          DynamicImport-Package ::= dynamic-description
+     *              ( ',' dynamic-description )*
+     *              
+     *          dynamic-description::= wildcard-names ( ';' parameter )*
+     *          wildcard-names ::= wildcard-name ( ';' wildcard-name )*
+     *          wildcard-name ::= package-name 
+     *                         | ( package-name '.*' ) // See 1.4.2
+     *                         | '*'
+     * </pre>
+     */
+    private void verifyDynamicImportPackage() {
+        verifyListHeader("DynamicImport-Package", WILDCARDPACKAGE, true);
+        String dynamicImportPackage = getHeader("DynamicImport-Package");
+        if (dynamicImportPackage == null)
+            return;
+
+        Map<String, Map<String, String>> map = parseHeader(dynamicImportPackage);
+        for (String name : map.keySet()) {
+            name = name.trim();
+            if (!verify(name, WILDCARDPACKAGE))
+                error("DynamicImport-Package header contains an invalid package name: "
+                        + name);
+
+            Map<String, String> sub = map.get(name);
+            if (r3 && sub.size() != 0) {
+                error("DynamicPackage-Import has attributes on import: "
+                        + name
+                        + ". This is however, an <=R3 bundle and attributes on this header were introduced in R4. ");
+            }
+        }
+    }
+
+    private void verifyManifestFirst() {
+        if (!dot.manifestFirst) {
+            error("Invalid JAR stream: Manifest should come first to be compatible with JarInputStream, it was not");
+        }
+    }
+
+    private void verifySymbolicName() {
+        Map<String, Map<String, String>> bsn = parseHeader(getHeader(Analyzer.BUNDLE_SYMBOLICNAME));
+        if (!bsn.isEmpty()) {
+            if (bsn.size() > 1)
+                error("More than one BSN specified " + bsn);
+
+            String name = (String) bsn.keySet().iterator().next();
+            if (!SYMBOLICNAME.matcher(name).matches()) {
+                error("Symbolic Name has invalid format: " + name);
+            }
+        }
+    }
+
+    /**
+     * <pre>
+     *         filter ::= ’(’ filter-comp ’)’
+     *         filter-comp ::= and | or | not | operation
+     *         and ::= ’&amp;’ filter-list
+     *         or ::= ’|’ filter-list
+     *         not ::= ’!’ filter
+     *         filter-list ::= filter | filter filter-list
+     *         operation ::= simple | present | substring
+     *         simple ::= attr filter-type value
+     *         filter-type ::= equal | approx | greater | less
+     *         equal ::= ’=’
+     *         approx ::= ’&tilde;=’
+     *         greater ::= ’&gt;=’
+     *         less ::= ’&lt;=’
+     *         present ::= attr ’=*’
+     *         substring ::= attr ’=’ initial any final
+     *         inital ::= () | value
+     *         any ::= ’*’ star-value
+     *         star-value ::= () | value ’*’ star-value
+     *         final ::= () | value
+     *         value ::= &lt;see text&gt;
+     * </pre>
+     * 
+     * @param expr
+     * @param index
+     * @return
+     */
+
+    public static 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++; // skip (
+
+            while (Character.isWhitespace(expr.charAt(index)))
+                index++;
+
+            switch (expr.charAt(index)) {
+            case '!':
+                index++; // skip !
+                while (Character.isWhitespace(expr.charAt(index)))
+                    index++;
+
+                if (expr.charAt(index) != '(')
+                    throw new IllegalArgumentException(
+                            "Filter mismatch: ! (not) must have one sub expression "
+                                    + index + " : " + expr);
+                while (Character.isWhitespace(expr.charAt(index)))
+                    index++;
+
+                index = verifyFilter(expr, index);
+                while (Character.isWhitespace(expr.charAt(index)))
+                    index++;
+                if (expr.charAt(index) != ')')
+                    throw new IllegalArgumentException(
+                            "Filter mismatch: expected ) at position " + index
+                                    + " : " + expr);
+                return index + 1;
+
+            case '&':
+            case '|':
+                index++; // skip operator
+                while (Character.isWhitespace(expr.charAt(index)))
+                    index++;
+                while (expr.charAt(index) == '(') {
+                    index = verifyFilter(expr, index);
+                    while (Character.isWhitespace(expr.charAt(index)))
+                        index++;
+                }
+
+                if (expr.charAt(index) != ')')
+                    throw new IllegalArgumentException(
+                            "Filter mismatch: expected ) at position " + index
+                                    + " : " + expr);
+                return index + 1; // skip )
+
+            default:
+                index = verifyFilterOperation(expr, index);
+                if (expr.charAt(index) != ')')
+                    throw new IllegalArgumentException(
+                            "Filter mismatch: expected ) at position " + index
+                                    + " : " + expr);
+                return index + 1;
+            }
+        } catch (IndexOutOfBoundsException e) {
+            throw new IllegalArgumentException(
+                    "Filter mismatch: early EOF from " + index);
+        }
+    }
+
+    static 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 ("\\)(*".indexOf(expr.charAt(index + 1)) >= 0 )
+                    index++;
+                else
+                    throw new IllegalArgumentException(
+                            "Filter error, illegal use of backslash at index "
+                                    + index
+                                    + ". Backslash may only be used before * or () or \\");
+            }
+            sb.append(expr.charAt(index++));
+        }
+        return index;
+    }
+
+    private String getHeader(String string) {
+        return main.getValue(string);
+    }
+
+    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;
+    }
+
+    static private boolean verify(String value, Pattern regex) {
+        return regex.matcher(value).matches();
+    }
+
+    private boolean verifyListHeader(String name, Pattern regex, boolean error) {
+        String value = manifest.getMainAttributes().getValue(name);
+        if (value == null)
+            return false;
+
+        Map<String, Map<String, String>> map = parseHeader(value);
+        for (String header : map.keySet()) {
+            if (!regex.matcher(header).matches()) {
+                String msg = "Invalid value for " + name + ", " + value
+                        + " does not match " + regex.pattern();
+                if (error)
+                    error(msg);
+                else
+                    warning(msg);
+            }
+        }
+        return true;
+    }
+
+    public String getProperty(String key, String deflt) {
+        if (properties == null)
+            return deflt;
+        return properties.getProperty(key, deflt);
+    }
+
+    public void setClassSpace(Map<String, Clazz> classspace,
+            Map<String, Map<String, String>> contained,
+            Map<String, Map<String, String>> referred,
+            Map<String, Set<String>> uses) {
+        this.classSpace = classspace;
+        this.contained = contained;
+        this.referred = referred;
+        this.uses = uses;
+    }
+
+    public static boolean isVersion(String version) {
+        return VERSION.matcher(version).matches();
+    }
+
+    public static boolean isIdentifier(String value) {
+        if (value.length() < 1)
+            return false;
+
+        if (!Character.isJavaIdentifierStart(value.charAt(0)))
+            return false;
+
+        for (int i = 1; i < value.length(); i++) {
+            if (!Character.isJavaIdentifierPart(value.charAt(i)))
+                return false;
+        }
+        return true;
+    }
+
+    public static boolean isMember(String value, String[] matches) {
+        for (String match : matches) {
+            if (match.equals(value))
+                return true;
+        }
+        return false;
+    }
+
+	public static boolean isFQN(String name) {
+		if ( name.length() == 0)
+			return false;
+		if ( !Character.isJavaIdentifierStart(name.charAt(0)))
+			return false;
+		
+		for ( int i=1; i<name.length(); i++) {
+			char c = name.charAt(i);
+			if (Character.isJavaIdentifierPart(c) || c == '$' || c == '.')
+				continue;
+			
+			return false;
+		}
+		
+		return true;
+	}
+
+    /*
+     * public int verifyFilter(StringBuffer sb, String s, int rover) { rover =
+     * skip(s, rover); char c = s.charAt(rover); if (c == '(') { sb.append('(');
+     * char type; rover = skip(s, ++rover); c = s.charAt(rover); switch (c) {
+     * case '!': // not case '&': // and case '|': // or sb.append(c); type = c;
+     * while(true) { rover = skip(++rover); c = s.charAt(rover); if ( c != '(')
+     * break; rover = verifyFilter(s, rover); } break;
+     * 
+     * case ')': return rover + 1;
+     * 
+     * default: rover = skip(s,rover); c = s.charAt(rover); while (
+     * Character.isLetterOrDigit(c) || ) } } }
+     */
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/WriteResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/WriteResource.java
new file mode 100644
index 0000000..99f7dae
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/WriteResource.java
@@ -0,0 +1,42 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+
+public abstract class WriteResource implements Resource {
+	long 	lastModified;
+	String	extra;
+
+	public InputStream openInputStream() throws Exception {
+	    PipedInputStream pin = new PipedInputStream();
+	    final PipedOutputStream pout = new PipedOutputStream(pin);
+	    Thread t = new Thread() {
+	        public void run() {
+	            try {
+                    write(pout);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                } finally {
+                    try {
+                        pout.close();
+                    } catch (IOException e) {
+                        // Ignore
+                    }
+                }
+	        }
+	    };
+	    t.start();
+	    return pin;
+	}
+
+	public abstract void write(OutputStream out) throws IOException, Exception;
+	
+	public abstract long lastModified();
+
+	public String getExtra() {
+		return extra;
+	}
+
+	public void setExtra(String extra) {
+		this.extra = extra;
+	}
+}
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..83dcce3
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/ZipResource.java
@@ -0,0 +1,84 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+import java.util.zip.*;
+
+public class ZipResource implements Resource {
+    ZipFile  zip;
+    ZipEntry entry;
+    long     lastModified;
+    String   extra;
+
+    ZipResource(ZipFile zip, ZipEntry entry, long lastModified) {
+        this.zip = zip;
+        this.entry = entry;
+        this.lastModified = lastModified;
+        byte[] data = entry.getExtra();
+        if (data != null)
+            this.extra = new String(data);
+    }
+
+    public InputStream openInputStream() throws IOException {
+        return zip.getInputStream(entry);
+    }
+
+    public String toString() {
+        return ":" + zip.getName() + "(" + 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 (ZipException ze) {
+            throw new ZipException("The JAR/ZIP file ("
+                    + file.getAbsolutePath() + ") seems corrupted, error: "
+                    + ze.getMessage());
+        } catch (FileNotFoundException e) {
+            throw new IllegalArgumentException("Problem opening JAR: "
+                    + file.getAbsolutePath());
+        }
+    }
+
+    public void write(OutputStream out) throws Exception {
+        FileResource.copy(this, out);
+    }
+
+    public long lastModified() {
+        return lastModified;
+    }
+
+    public String getExtra() {
+        return extra;
+    }
+
+    public void setExtra(String extra) {
+        this.extra = extra;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/eclipse/EclipseClasspath.java b/bundleplugin/src/main/java/aQute/lib/osgi/eclipse/EclipseClasspath.java
new file mode 100644
index 0000000..47f441f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/eclipse/EclipseClasspath.java
@@ -0,0 +1,248 @@
+package aQute.lib.osgi.eclipse;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.xml.parsers.*;
+
+import org.w3c.dom.*;
+import org.xml.sax.*;
+
+import aQute.libg.reporter.*;
+
+/**
+ * Parse the Eclipse project information for the classpath. Unfortunately, it is
+ * impossible to read the variables. They are ignored but that can cause
+ * problems.
+ * 
+ * @version $Revision$
+ */
+public class EclipseClasspath {
+    static DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
+                                                                 .newInstance();
+    DocumentBuilder               db;
+    File                          project;
+    File                          workspace;
+    Set<File>                     sources                = new LinkedHashSet<File>();
+    Set<File>                     allSources                = new LinkedHashSet<File>();
+    
+    Set<File>                     classpath              = new LinkedHashSet<File>();
+    List<File>                    dependents             = new ArrayList<File>();
+    File                          output;
+    boolean                       recurse                = true;
+    Set<File>                     exports                = new LinkedHashSet<File>();
+    Map<String, String>           properties             = new HashMap<String, String>();
+    Reporter                      reporter;
+    int                           options;
+    Set<File>                     bootclasspath          = new LinkedHashSet<File>();
+
+    public final static int       DO_VARIABLES           = 1;
+
+    /**
+     * Parse an Eclipse project structure to discover the classpath.
+     * 
+     * @param workspace
+     *            Points to workspace
+     * @param project
+     *            Points to project
+     * @throws ParserConfigurationException
+     * @throws SAXException
+     * @throws IOException
+     */
+
+    public EclipseClasspath(Reporter reporter, File workspace, File project,
+            int options) throws Exception {
+        this.project = project.getCanonicalFile();
+        this.workspace = workspace.getCanonicalFile();
+        this.reporter = reporter;
+        db = documentBuilderFactory.newDocumentBuilder();
+        parse(this.project, true);
+        db = null;
+    }
+
+    public EclipseClasspath(Reporter reporter, File workspace, File project)
+            throws Exception {
+        this(reporter, workspace, project, 0);
+    }
+
+    /**
+     * Recursive routine to parse the files. If a sub project is detected, it is
+     * parsed before the parsing continues. This should give the right order.
+     * 
+     * @param project
+     *            Project directory
+     * @param top
+     *            If this is the top project
+     * @throws ParserConfigurationException
+     * @throws SAXException
+     * @throws IOException
+     */
+    void parse(File project, boolean top) throws ParserConfigurationException,
+            SAXException, IOException {
+        File file = new File(project, ".classpath");
+        if (!file.exists())
+            throw new FileNotFoundException(".classpath file not found: "
+                    + file.getAbsolutePath());
+
+        Document doc = db.parse(file);
+        NodeList nodelist = doc.getDocumentElement().getElementsByTagName(
+                "classpathentry");
+
+        if (nodelist == null)
+            throw new IllegalArgumentException(
+                    "Can not find classpathentry in classpath file");
+
+        for (int i = 0; i < nodelist.getLength(); i++) {
+            Node node = nodelist.item(i);
+            NamedNodeMap attrs = node.getAttributes();
+            String kind = get(attrs, "kind");
+            if ("src".equals(kind)) {
+                String path = get(attrs, "path");
+                // TODO boolean exported = "true".equalsIgnoreCase(get(attrs,
+                // "exported"));
+                if (path.startsWith("/")) {
+                    // We have another project
+                    File subProject = getFile(workspace, project, path);
+                    if (recurse)
+                        parse(subProject, false);
+                    dependents.add(subProject.getCanonicalFile());
+                } else {
+                    File src = getFile(workspace, project, path);
+                    allSources.add(src);
+                    if (top) {
+                        // We only want the sources for our own project
+                        // or we'll compile all at once. Not a good idea
+                        // because project settings can differ.
+                        sources.add(src);
+                    }
+                }
+            } else if ("lib".equals(kind)) {
+                String path = get(attrs, "path");
+                boolean exported = "true".equalsIgnoreCase(get(attrs,
+                        "exported"));
+                if (top || exported) {
+                    File jar = getFile(workspace, project, path);
+                    if (jar.getName().startsWith("ee."))
+                        bootclasspath.add(jar);
+                    else
+                        classpath.add(jar);
+                    if (exported)
+                        exports.add(jar);
+                }
+            } else if ("output".equals(kind)) {
+                String path = get(attrs, "path");
+                path = path.replace('/', File.separatorChar);
+                output = getFile(workspace, project, path);
+                classpath.add(output);
+                exports.add(output);
+            } else if ("var".equals(kind)) {
+                boolean exported = "true".equalsIgnoreCase(get(attrs,
+                        "exported"));
+                File lib = replaceVar(get(attrs, "path"));
+                File slib = replaceVar(get(attrs, "sourcepath"));
+                if (lib != null) {
+                    classpath.add(lib);
+                    if (exported)
+                        exports.add(lib);
+                }
+                if (slib != null)
+                    sources.add(slib);
+            } else if ("con".equals(kind)) {
+                // Should do something useful ...
+            }
+        }
+    }
+
+    private File getFile(File abs, File relative, String opath) {
+        String path = opath.replace('/', File.separatorChar);
+        File result = new File(path);
+        if (result.isAbsolute() && result.isFile()) {
+            return result;
+        }
+        if (path.startsWith(File.separator)) {
+            result = abs;
+            path = path.substring(1);
+        } else
+            result = relative;
+
+        StringTokenizer st = new StringTokenizer(path, File.separator);
+        while (st.hasMoreTokens()) {
+            String token = st.nextToken();
+            result = new File(result, token);
+        }
+
+        if (!result.exists())
+            System.err.println("File not found: project=" + project
+                    + " workspace=" + workspace + " path=" + opath + " file="
+                    + result);
+        return result;
+    }
+
+    static Pattern PATH = Pattern.compile("([A-Z_]+)/(.*)");
+
+    private File replaceVar(String path) {
+        if ((options & DO_VARIABLES) == 0)
+            return null;
+
+        Matcher m = PATH.matcher(path);
+        if (m.matches()) {
+            String var = m.group(1);
+            String remainder = m.group(2);
+            String base = (String) properties.get(var);
+            if (base != null) {
+                File b = new File(base);
+                File f = new File(b, remainder.replace('/', File.separatorChar));
+                return f;
+            } else
+                reporter.error("Can't find replacement variable for: " + path);
+        } else
+            reporter.error("Cant split variable path: " + path);
+        return null;
+    }
+
+    private String get(NamedNodeMap map, String name) {
+        Node node = map.getNamedItem(name);
+        if (node == null)
+            return null;
+
+        return node.getNodeValue();
+    }
+
+    public Set<File> getClasspath() {
+        return classpath;
+    }
+
+    public Set<File> getSourcepath() {
+        return sources;
+    }
+
+    public File getOutput() {
+        return output;
+    }
+
+    public List<File> getDependents() {
+        return dependents;
+    }
+
+    public void setRecurse(boolean recurse) {
+        this.recurse = recurse;
+    }
+
+    public Set<File> getExports() {
+        return exports;
+    }
+
+    public void setProperties(Map<String, String> map) {
+        this.properties = map;
+    }
+
+    public Set<File> getBootclasspath() {
+        return bootclasspath;
+    }
+
+    public Set<File> getAllSources() {
+        return allSources;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/packageinfo b/bundleplugin/src/main/java/aQute/lib/osgi/packageinfo
new file mode 100644
index 0000000..ec0efd4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/packageinfo
@@ -0,0 +1 @@
+version 1.43.1
diff --git a/bundleplugin/src/main/java/aQute/lib/putjar/DirectoryInputStream.java b/bundleplugin/src/main/java/aQute/lib/putjar/DirectoryInputStream.java
new file mode 100644
index 0000000..5bd8178
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/putjar/DirectoryInputStream.java
@@ -0,0 +1,281 @@
+package aQute.lib.putjar;
+
+import java.io.*;
+import java.util.zip.*;
+
+import aQute.libg.fileiterator.*;
+
+public class DirectoryInputStream extends InputStream {
+    final File               root;
+    final FileIterator       fi;
+    File                     element;
+    int                      entries   = 0;
+    int                      state     = START;
+    long                     where     = 0;
+
+    final static int         START     = 0;
+    final static int         HEADER    = 1;
+    final static int         DATA      = 2;
+    final static int         DIRECTORY = 4;
+    final static int         EOF       = 5;
+
+    final static InputStream eof       = new ByteArrayInputStream(new byte[0]);
+    ByteArrayOutputStream    directory = new ByteArrayOutputStream();
+    InputStream              current   = eof;
+
+    public DirectoryInputStream(File dir) {
+        root = dir;
+        fi = new FileIterator(dir);
+    }
+
+    @Override
+    public int read() throws IOException {
+        if (fi == null)
+            return -1;
+
+        int c = current.read();
+        if (c < 0) {
+            next();
+            c = current.read();
+        }
+        if (c >= 0)
+            where++;
+
+        return c;
+    }
+
+    void next() throws IOException {
+        switch (state) {
+        case START:
+        case DATA:
+            nextHeader();
+            break;
+
+        case HEADER:
+            if (element.isFile() && element.length() > 0) {
+                current = new FileInputStream(element);
+                state = DATA;
+            } else
+                nextHeader();
+            break;
+
+        case DIRECTORY:
+            state = EOF;
+            current = eof;
+            break;
+
+        case EOF:
+            break;
+        }
+    }
+
+    private void nextHeader() throws IOException {
+        if (fi.hasNext()) {
+            element = fi.next();
+            state = HEADER;
+            current = getHeader(root, element);
+            entries++;
+        } else {
+            current = getDirectory();
+            state = DIRECTORY;
+        }
+    }
+
+    /**
+     * <pre>
+     *     end of central dir signature    4 bytes  (0x06054b50)
+     *         number of this disk             2 bytes
+     *         number of the disk with the
+     *         start of the central directory  2 bytes
+     *         total number of entries in the
+     *         central directory on this disk  2 bytes
+     *         total number of entries in
+     *         the central directory           2 bytes
+     *         size of the central directory   4 bytes
+     *         offset of start of central
+     *         directory with respect to
+     *         the starting disk number        4 bytes
+     *         .ZIP file comment length        2 bytes
+     *         .ZIP file comment       (variable size)
+     * </pre>
+     * 
+     * @return
+     */
+    InputStream getDirectory() throws IOException {
+        long where = this.where;
+        int sizeDirectory = directory.size();
+
+        writeInt(directory, 0x504b0506); // Signature
+        writeShort(directory, 0); // # of disk
+        writeShort(directory, 0); // # of the disk with start of the central
+        // dir
+        writeShort(directory, entries); // # of entries
+        writeInt(directory, sizeDirectory); // Size of central dir
+        writeInt(directory, (int) where);
+        writeShort(directory, 0);
+
+        directory.close();
+
+        byte[] data = directory.toByteArray();
+        return new ByteArrayInputStream(data);
+    }
+
+    private void writeShort(OutputStream out, int v) throws IOException {
+        for (int i = 0; i < 2; i++) {
+            out.write((byte) (v & 0xFF));
+            v = v >> 8;
+        }
+    }
+
+    private void writeInt(OutputStream out, int v) throws IOException {
+        for (int i = 0; i < 4; i++) {
+            out.write((byte) (v & 0xFF));
+            v = v >> 8;
+        }
+    }
+
+    /**
+     * Local file header:
+     * 
+     * <pre>
+     * 
+     *         local file header signature     4 bytes  (0x04034b50)
+     *         version needed to extract       2 bytes
+     *         general purpose bit flag        2 bytes
+     *         compression method              2 bytes
+     *         last mod file time              2 bytes
+     *         last mod file date              2 bytes
+     *         crc-32                          4 bytes
+     *         compressed size                 4 bytes
+     *         uncompressed size               4 bytes
+     *         file name length                2 bytes
+     *         extra field length              2 bytes
+     * 
+     *         file name (variable size)
+     *         extra field (variable size)
+     * 
+     *     central file header signature   4 bytes  (0x02014b50)
+     *         version made by                 2 bytes
+     *         version needed to extract       2 bytes
+     *         general purpose bit flag        2 bytes
+     *         compression method              2 bytes
+     *         last mod file time              2 bytes
+     *         last mod file date              2 bytes
+     *         crc-32                          4 bytes
+     *         compressed size                 4 bytes
+     *         uncompressed size               4 bytes
+     *         file name length                2 bytes
+     *         extra field length              2 bytes
+     *         file comment length             2 bytes
+     *         disk number start               2 bytes
+     *         internal file attributes        2 bytes
+     *         external file attributes        4 bytes
+     *         relative offset of local header 4 bytes
+     * 
+     *         file name (variable size)
+     *         extra field (variable size)
+     *         file comment (variable size)
+     * </pre>
+     * </pre>
+     * 
+     * @param file
+     * @return
+     */
+    private InputStream getHeader(File root, File file) throws IOException {
+        long where = this.where;
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        // Signature
+        writeInt(bout, 0x04034b50);
+        writeInt(directory, 0x504b0102);
+
+        // Version needed to extract
+        writeShort(directory, 0);
+
+        // Version needed to extract
+        writeShort(bout, 10);
+        writeShort(directory, 10);
+
+        // General purpose bit flag (use descriptor)
+        writeShort(bout, 0); // descriptor follows data
+        writeShort(directory, 0); // descriptor follows data
+
+        // Compresson method (stored)
+        writeShort(bout, 0);
+        writeShort(directory, 0);
+
+        // Mod time
+        writeInt(bout, 0);
+        writeInt(directory, 0);
+
+        if (file.isDirectory()) {
+            writeInt(bout, 0); // CRC
+            writeInt(bout, 0); // Compressed size
+            writeInt(bout, 0); // Uncompressed Size
+            writeInt(directory, 0);
+            writeInt(directory, 0);
+            writeInt(directory, 0);
+        } else {
+            CRC32 crc = getCRC(file);
+            writeInt(bout, (int) crc.getValue());
+            writeInt(bout, (int) file.length());
+            writeInt(bout, (int) file.length());
+            writeInt(directory, (int) crc.getValue());
+            writeInt(directory, (int) file.length());
+            writeInt(directory, (int) file.length());
+        }
+
+        String p = getPath(root, file);
+        if (file.isDirectory())
+            p = p + "/";
+        byte[] path = p.getBytes("UTF-8");
+        writeShort(bout, path.length);
+        writeShort(directory, path.length);
+
+        writeShort(bout, 0); // extra length
+        writeShort(directory, 0);
+
+        bout.write(path);
+
+        writeShort(directory, 0); // File comment length
+        writeShort(directory, 0); // disk number start 2 bytes
+        writeShort(directory, 0); // internal file attributes 2 bytes
+        writeInt(directory, 0); // external file attributes 4 bytes
+        writeInt(directory, (int) where); // relative offset of local header 4
+        // bytes
+
+        directory.write(path);
+
+        byte[] bytes = bout.toByteArray();
+        return new ByteArrayInputStream(bytes);
+    }
+
+    private String getPath(File root, File file) {
+        if (file.equals(root))
+            return "";
+
+        String p = getPath(root, file.getParentFile());
+        if (p.length() == 0)
+            p = file.getName();
+        else {
+            p = p + "/" + file.getName();
+        }
+        return p;
+    }
+
+    private CRC32 getCRC(File file) throws IOException {
+        CRC32 crc = new CRC32();
+        FileInputStream in = new FileInputStream(file);
+        try {
+            byte data[] = new byte[10000];
+            int size = in.read(data);
+            while (size > 0) {
+                crc.update(data, 0, size);
+                size = in.read(data);
+            }
+        } finally {
+            in.close();
+        }
+        return crc;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/putjar/packageinfo b/bundleplugin/src/main/java/aQute/lib/putjar/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/putjar/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java b/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java
new file mode 100644
index 0000000..131709c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java
@@ -0,0 +1,25 @@
+package aQute.lib.spring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import aQute.lib.osgi.Analyzer;
+
+/**
+ * This component is called when we find a resource in the META-INF/*.xml
+ * pattern. We parse the resource and and the imports to the builder.
+ * 
+ * Parsing is done with XSLT (first time I see the use of having XML for the
+ * Spring configuration files!).
+ * 
+ * @author aqute
+ * 
+ */
+public class JPAComponent extends XMLTypeProcessor {
+    
+    protected List<XMLType> getTypes(Analyzer analyzer) throws Exception {
+        List<XMLType> types = new ArrayList<XMLType>();        
+        process(types,"jpa.xsl", "META-INF", "persistence.xml");
+        return types;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/SpringComponent.java b/bundleplugin/src/main/java/aQute/lib/spring/SpringComponent.java
new file mode 100644
index 0000000..3318a0e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/SpringComponent.java
@@ -0,0 +1,97 @@
+package aQute.lib.spring;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.xml.transform.*;
+import javax.xml.transform.stream.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+/**
+ * This component is called when we find a resource in the META-INF/*.xml
+ * pattern. We parse the resource and and the imports to the builder.
+ * 
+ * Parsing is done with XSLT (first time I see the use of having XML for the
+ * Spring configuration files!).
+ * 
+ * @author aqute
+ * 
+ */
+public class SpringComponent implements AnalyzerPlugin {
+	static Transformer transformer;
+	static Pattern SPRING_SOURCE = Pattern.compile("META-INF/spring/.*\\.xml");
+	static Pattern QN = Pattern.compile("[_A-Za-z$][_A-Za-z0-9$]*(\\.[_A-Za-z$][_A-Za-z0-9$]*)*");
+
+	public static Set<CharSequence> analyze(InputStream in) throws Exception {
+		if (transformer == null) {
+			TransformerFactory tf = TransformerFactory.newInstance();
+			Source source = new StreamSource(SpringComponent.class
+					.getResourceAsStream("extract.xsl"));
+			transformer = tf.newTransformer(source);
+		}
+
+		Set<CharSequence> refers = new HashSet<CharSequence>();
+
+		ByteArrayOutputStream bout = new ByteArrayOutputStream();
+		Result r = new StreamResult(bout);
+		Source s = new StreamSource(in);
+		transformer.transform(s, r);
+
+		ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+		bout.close();
+
+		BufferedReader br = new BufferedReader(new InputStreamReader(bin, "UTF8"));
+
+		String line = br.readLine();
+		while (line != null) {
+			line = line.trim();
+			if (line.length() > 0) {
+				String parts[] = line.split("\\s*,\\s*");
+				for (int i = 0; i < parts.length; i++) {
+					int n = parts[i].lastIndexOf('.');
+					if (n > 0) {
+						refers.add(parts[i].subSequence(0, n));
+					}
+				}
+			}
+			line = br.readLine();
+		}
+		br.close();
+		return refers;
+	}
+
+	@SuppressWarnings("unchecked")
+    public boolean analyzeJar(Analyzer analyzer) throws Exception {
+	    Jar jar = analyzer.getJar();
+		Map dir = (Map) jar.getDirectories().get("META-INF/spring");
+		if ( dir == null || dir.isEmpty())
+			return false;
+		
+		for (Iterator i = dir.entrySet().iterator(); i.hasNext();) {
+			Map.Entry entry = (Map.Entry) i.next();
+			String path = (String) entry.getKey();
+			Resource resource = (Resource) entry.getValue();
+			if (SPRING_SOURCE.matcher(path).matches()) {
+				try {
+				InputStream in = resource.openInputStream();
+				Set set = analyze(in);
+				in.close();
+				for (Iterator r = set.iterator(); r.hasNext();) {
+					String pack = (String) r.next();
+					if ( !QN.matcher(pack).matches())
+					    analyzer.warning("Package does not seem a package in spring resource ("+path+"): " + pack );
+					if (!analyzer.getReferred().containsKey(pack))
+						analyzer.getReferred().put(pack, new LinkedHashMap());
+				}
+				} catch( Exception e ) {
+					analyzer.error("Unexpected exception in processing spring resources("+path+"): " + e );
+				}
+			}
+		}
+		return false;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/SpringXMLType.java b/bundleplugin/src/main/java/aQute/lib/spring/SpringXMLType.java
new file mode 100644
index 0000000..35b59a9
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/SpringXMLType.java
@@ -0,0 +1,33 @@
+package aQute.lib.spring;
+
+import java.util.*;
+
+import aQute.lib.osgi.*;
+
+/**
+ * This component is called when we find a resource in the META-INF/*.xml
+ * pattern. We parse the resource and and the imports to the builder.
+ * 
+ * Parsing is done with XSLT (first time I see the use of having XML for the
+ * Spring configuration files!).
+ * 
+ * @author aqute
+ * 
+ */
+public class SpringXMLType extends XMLTypeProcessor {
+
+    protected List<XMLType> getTypes(Analyzer analyzer) throws Exception {
+        List<XMLType> types = new ArrayList<XMLType>();
+        
+        String header = analyzer.getProperty("Bundle-Blueprint", "META-INF/blueprint");
+        process(types,"extract.xsl", header, ".*\\.xml");
+        header = analyzer.getProperty("Spring-Context", "META-INF/spring");
+        process(types,"extract.xsl", header, ".*\\.xml"); 
+        
+        return types;
+    }
+
+ 
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/XMLType.java b/bundleplugin/src/main/java/aQute/lib/spring/XMLType.java
new file mode 100644
index 0000000..9fadb35
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/XMLType.java
@@ -0,0 +1,108 @@
+package aQute.lib.spring;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.xml.transform.*;
+import javax.xml.transform.stream.*;
+
+import aQute.lib.osgi.*;
+
+public class XMLType {
+    
+    Transformer    transformer;
+    Pattern        paths;
+    String          root;
+    
+    
+    static Pattern QN = Pattern
+                              .compile("[_A-Za-z$][_A-Za-z0-9$]*(\\.[_A-Za-z$][_A-Za-z0-9$]*)*");
+
+    public XMLType(URL source, String root, String paths ) throws Exception {
+        transformer = getTransformer(source);
+        this.paths = Pattern.compile(paths);
+        this.root = root;
+    }
+    
+    public Set<String> analyze(InputStream in) throws Exception {
+        Set<String> refers = new HashSet<String>();
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        Result r = new StreamResult(bout);
+        Source s = new StreamSource(in);
+        transformer.transform(s, r);
+
+        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
+        bout.close();
+
+        BufferedReader br = new BufferedReader(new InputStreamReader(bin, "UTF8"));
+
+        String line = br.readLine();
+        while (line != null) {
+            line = line.trim();
+            if (line.length() > 0) {
+                String parts[] = line.split("\\s*,\\s*");
+                for (int i = 0; i < parts.length; i++) {
+                    int n = parts[i].lastIndexOf('.');
+                    if (n > 0) {
+                        refers.add(parts[i].subSequence(0, n).toString());
+                    }
+                }
+            }
+            line = br.readLine();
+        }
+        br.close();
+        return refers;
+    }
+
+    public boolean analyzeJar(Analyzer analyzer) throws Exception {
+        Jar jar = analyzer.getJar();
+        Map<String,Resource> dir = jar.getDirectories().get(root);
+        if (dir == null || dir.isEmpty()) {
+            Resource resource  = jar.getResource(root);
+            if ( resource != null )
+                process(analyzer, root, resource);
+            return false;
+        }
+
+        for (Iterator<Map.Entry<String,Resource>> i = dir.entrySet().iterator(); i.hasNext();) {
+            Map.Entry<String,Resource> entry = i.next();
+            String path = entry.getKey();
+            Resource resource = entry.getValue();
+            if (paths.matcher(path).matches()) {
+                process(analyzer, path, resource);
+            }
+        }
+        return false;
+    }
+
+    private void process(Analyzer analyzer, String path, Resource resource) {
+        try {
+            InputStream in = resource.openInputStream();
+            Set<String> set = analyze(in);
+            in.close();
+            for (Iterator<String> r = set.iterator(); r.hasNext();) {
+                String pack = r.next();
+                if (!QN.matcher(pack).matches())
+                    analyzer
+                            .warning("Package does not seem a package in spring resource ("
+                                    + path + "): " + pack);
+                if (!analyzer.getReferred().containsKey(pack))
+                    analyzer.getReferred().put(pack,
+                            new LinkedHashMap<String,String>());
+            }
+        } catch (Exception e) {
+            analyzer
+                    .error("Unexpected exception in processing spring resources("
+                            + path + "): " + e);
+        }
+    }
+
+    protected Transformer getTransformer(java.net.URL url) throws Exception {
+        TransformerFactory tf = TransformerFactory.newInstance();
+        Source source = new StreamSource(url.openStream());
+        return tf.newTransformer(source);
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/XMLTypeProcessor.java b/bundleplugin/src/main/java/aQute/lib/spring/XMLTypeProcessor.java
new file mode 100644
index 0000000..dde8b7e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/XMLTypeProcessor.java
@@ -0,0 +1,33 @@
+package aQute.lib.spring;
+
+import java.util.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+public class XMLTypeProcessor implements AnalyzerPlugin {
+    
+    public boolean analyzeJar(Analyzer analyzer) throws Exception {
+        List<XMLType> types = getTypes(analyzer);
+        for ( XMLType type : types ) {
+            type.analyzeJar(analyzer);
+        }
+        return false;
+    }
+    
+    protected List<XMLType> getTypes(Analyzer analyzer) throws Exception {
+        return new ArrayList<XMLType>();
+    }
+
+
+    protected void process(List<XMLType> types, String resource, String paths,
+            String pattern) throws Exception {
+        
+        Map<String,Map<String,String>> map = Processor.parseHeader(paths,null);
+        for ( String path : map.keySet() ) {
+            types.add( new XMLType( getClass().getResource(resource), path, pattern ));
+        }
+    }
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/tag/Tag.java b/bundleplugin/src/main/java/aQute/lib/tag/Tag.java
new file mode 100644
index 0000000..8762cce
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/tag/Tag.java
@@ -0,0 +1,465 @@
+package aQute.lib.tag;
+
+import java.io.*;
+import java.text.*;
+import java.util.*;
+
+/**
+ * The Tag class represents a minimal XML tree. It consist of a named element
+ * with a hashtable of named attributes. Methods are provided to walk the tree
+ * and get its constituents. The content of a Tag is a list that contains String
+ * objects or other Tag objects.
+ */
+public class Tag {
+	Tag							parent;													// Parent
+	String						name;														// Name
+	final Map<String, String>	attributes	= new LinkedHashMap<String, String>();
+	final List<Object>			content		= new ArrayList<Object>();						// Content
+	static SimpleDateFormat		format		= new SimpleDateFormat("yyyyMMddHHmmss.SSS");
+	boolean						cdata;
+
+	/**
+	 * Construct a new Tag with a name.
+	 */
+	public Tag(String name, Object... contents) {
+		this.name = name;
+		for (Object c : contents)
+			content.add(c);
+	}
+
+	public Tag(Tag parent, String name, Object... contents) {
+		this(name,contents);
+		parent.addContent(this);
+	}
+
+	/**
+	 * Construct a new Tag with a name.
+	 */
+	public Tag(String name, Map<String, String> attributes, Object... contents) {
+		this(name,contents);
+		this.attributes.putAll(attributes);
+
+	}
+	public Tag(String name, Map<String, String> attributes) {
+		this(name, attributes, new Object[0]);
+	}
+
+	/**
+	 * Construct a new Tag with a name and a set of attributes. The attributes
+	 * are given as ( name, value ) ...
+	 */
+	public Tag(String name, String[] attributes, Object... contents) {
+		this(name,contents);
+		for (int i = 0; i < attributes.length; i += 2)
+			addAttribute(attributes[i], attributes[i + 1]);
+	}
+	
+	public Tag(String name, String[] attributes) {
+		this(name, attributes, new Object[0]);
+	}
+
+	/**
+	 * Add a new attribute.
+	 */
+	public Tag addAttribute(String key, String value) {
+		if (value != null)
+			attributes.put(key, value);
+		return this;
+	}
+
+	/**
+	 * Add a new attribute.
+	 */
+	public Tag addAttribute(String key, Object value) {
+		if (value == null)
+			return this;
+		attributes.put(key, value.toString());
+		return this;
+	}
+
+	/**
+	 * Add a new attribute.
+	 */
+	public Tag addAttribute(String key, int value) {
+		attributes.put(key, Integer.toString(value));
+		return this;
+	}
+
+	/**
+	 * Add a new date attribute. The date is formatted as the SimpleDateFormat
+	 * describes at the top of this class.
+	 */
+	public Tag addAttribute(String key, Date value) {
+		if (value != null)
+			attributes.put(key, format.format(value));
+		return this;
+	}
+
+	/**
+	 * Add a new content string.
+	 */
+	public Tag addContent(String string) {
+		if (string != null)
+			content.add(string);
+		return this;
+	}
+
+	/**
+	 * Add a new content tag.
+	 */
+	public Tag addContent(Tag tag) {
+		content.add(tag);
+		tag.parent = this;
+		return this;
+	}
+
+	/**
+	 * Return the name of the tag.
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Return the attribute value.
+	 */
+	public String getAttribute(String key) {
+		return (String) attributes.get(key);
+	}
+
+	/**
+	 * Return the attribute value or a default if not defined.
+	 */
+	public String getAttribute(String key, String deflt) {
+		String answer = getAttribute(key);
+		return answer == null ? deflt : answer;
+	}
+
+	/**
+	 * Answer the attributes as a Dictionary object.
+	 */
+	public Map<String, String> getAttributes() {
+		return attributes;
+	}
+
+	/**
+	 * Return the contents.
+	 */
+	public List<Object> getContents() {
+		return content;
+	}
+
+	/**
+	 * Return a string representation of this Tag and all its children
+	 * recursively.
+	 */
+	public String toString() {
+		StringWriter sw = new StringWriter();
+		print(0, new PrintWriter(sw));
+		return sw.toString();
+	}
+
+	/**
+	 * Return only the tags of the first level of descendants that match the
+	 * name.
+	 */
+	public List<Object> getContents(String tag) {
+		List<Object> out = new ArrayList<Object>();
+		for (Object o : out) {
+			if (o instanceof Tag && ((Tag) o).getName().equals(tag))
+				out.add(o);
+		}
+		return out;
+	}
+
+	/**
+	 * Return the whole contents as a String (no tag info and attributes).
+	 */
+	public String getContentsAsString() {
+		StringBuffer sb = new StringBuffer();
+		getContentsAsString(sb);
+		return sb.toString();
+	}
+
+	/**
+	 * convenient method to get the contents in a StringBuffer.
+	 */
+	public void getContentsAsString(StringBuffer sb) {
+		for (Object o : content) {
+			if (o instanceof Tag)
+				((Tag) o).getContentsAsString(sb);
+			else
+				sb.append(o.toString());
+		}
+	}
+
+	/**
+	 * Print the tag formatted to a PrintWriter.
+	 */
+	public Tag print(int indent, PrintWriter pw) {
+		pw.print("\n");
+		spaces(pw, indent);
+		pw.print('<');
+		pw.print(name);
+
+		for (String key : attributes.keySet()) {
+			String value = escape(attributes.get(key));
+			pw.print(' ');
+			pw.print(key);
+			pw.print("=");
+			String quote = "'";
+			if (value.indexOf(quote) >= 0)
+				quote = "\"";
+			pw.print(quote);
+			pw.print(value);
+			pw.print(quote);
+		}
+
+		if (content.size() == 0)
+			pw.print('/');
+		else {
+			pw.print('>');
+			for (Object c : content) {
+				if (c instanceof String) {
+					formatted(pw, indent + 2, 60, escape((String) c));
+				} else if (c instanceof Tag) {
+					Tag tag = (Tag) c;
+					tag.print(indent + 2, pw);
+				}
+			}
+			pw.print("\n");
+			spaces(pw, indent);
+			pw.print("</");
+			pw.print(name);
+		}
+		pw.print('>');
+		return this;
+	}
+
+	/**
+	 * Convenience method to print a string nicely and does character conversion
+	 * to entities.
+	 */
+	void formatted(PrintWriter pw, int left, int width, String s) {
+		int pos = width + 1;
+		s = s.trim();
+
+		for (int i = 0; i < s.length(); i++) {
+			char c = s.charAt(i);
+			if (i == 0 || (Character.isWhitespace(c) && pos > width - 3)) {
+				pw.print("\n");
+				spaces(pw, left);
+				pos = 0;
+			}
+			switch (c) {
+			case '<':
+				pw.print("&lt;");
+				pos += 4;
+				break;
+			case '>':
+				pw.print("&gt;");
+				pos += 4;
+				break;
+			case '&':
+				pw.print("&amp;");
+				pos += 5;
+				break;
+			default:
+				pw.print(c);
+				pos++;
+				break;
+			}
+
+		}
+	}
+
+	/**
+	 * Escape a string, do entity conversion.
+	 */
+	String escape(String s) {
+		StringBuffer sb = new StringBuffer();
+		for (int i = 0; i < s.length(); i++) {
+			char c = s.charAt(i);
+			switch (c) {
+			case '<':
+				sb.append("&lt;");
+				break;
+			case '>':
+				sb.append("&gt;");
+				break;
+			case '&':
+				sb.append("&amp;");
+				break;
+			default:
+				sb.append(c);
+				break;
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Make spaces.
+	 */
+	void spaces(PrintWriter pw, int n) {
+		while (n-- > 0)
+			pw.print(' ');
+	}
+
+	/**
+	 * root/preferences/native/os
+	 */
+	public Collection<Tag> select(String path) {
+		return select(path, (Tag) null);
+	}
+
+	public Collection<Tag> select(String path, Tag mapping) {
+		List<Tag> v = new ArrayList<Tag>();
+		select(path, v, mapping);
+		return v;
+	}
+
+	void select(String path, List<Tag> results, Tag mapping) {
+		if (path.startsWith("//")) {
+			int i = path.indexOf('/', 2);
+			String name = path.substring(2, i < 0 ? path.length() : i);
+
+			for (Object o : content) {
+				if (o instanceof Tag) {
+					Tag child = (Tag) o;
+					if (match(name, child, mapping))
+						results.add(child);
+					child.select(path, results, mapping);
+				}
+
+			}
+			return;
+		}
+
+		if (path.length() == 0) {
+			results.add(this);
+			return;
+		}
+
+		int i = path.indexOf("/");
+		String elementName = path;
+		String remainder = "";
+		if (i > 0) {
+			elementName = path.substring(0, i);
+			remainder = path.substring(i + 1);
+		}
+
+		for (Object o : content) {
+			if (o instanceof Tag) {
+				Tag child = (Tag) o;
+				if (child.getName().equals(elementName) || elementName.equals("*"))
+					child.select(remainder, results, mapping);
+			}
+		}
+	}
+
+	public boolean match(String search, Tag child, Tag mapping) {
+		String target = child.getName();
+		String sn = null;
+		String tn = null;
+
+		if (search.equals("*"))
+			return true;
+
+		int s = search.indexOf(':');
+		if (s > 0) {
+			sn = search.substring(0, s);
+			search = search.substring(s + 1);
+		}
+		int t = target.indexOf(':');
+		if (t > 0) {
+			tn = target.substring(0, t);
+			target = target.substring(t + 1);
+		}
+
+		if (!search.equals(target)) // different tag names
+			return false;
+
+		if (mapping == null) {
+			return tn == sn || (sn != null && sn.equals(tn));
+		} else {
+			String suri = sn == null ? mapping.getAttribute("xmlns") : mapping
+					.getAttribute("xmlns:" + sn);
+			String turi = tn == null ? child.findRecursiveAttribute("xmlns") : child
+					.findRecursiveAttribute("xmlns:" + tn);
+			return turi == suri || (turi != null && suri != null && turi.equals(suri));
+		}
+	}
+
+	public String getString(String path) {
+		String attribute = null;
+		int index = path.indexOf("@");
+		if (index >= 0) {
+			// attribute
+			attribute = path.substring(index + 1);
+
+			if (index > 0) {
+				// prefix path
+				path = path.substring(index - 1); // skip -1
+			} else
+				path = "";
+		}
+		Collection<Tag> tags = select(path);
+		StringBuffer sb = new StringBuffer();
+		for (Tag tag : tags) {
+			if (attribute == null)
+				tag.getContentsAsString(sb);
+			else
+				sb.append(tag.getAttribute(attribute));
+		}
+		return sb.toString();
+	}
+
+	public String getStringContent() {
+		StringBuffer sb = new StringBuffer();
+		for (Object c : content) {
+			if (!(c instanceof Tag))
+				sb.append(c);
+		}
+		return sb.toString();
+	}
+
+	public String getNameSpace() {
+		return getNameSpace(name);
+	}
+
+	public String getNameSpace(String name) {
+		int index = name.indexOf(':');
+		if (index > 0) {
+			String ns = name.substring(0, index);
+			return findRecursiveAttribute("xmlns:" + ns);
+		} else
+			return findRecursiveAttribute("xmlns");
+	}
+
+	public String findRecursiveAttribute(String name) {
+		String value = getAttribute(name);
+		if (value != null)
+			return value;
+		if (parent != null)
+			return parent.findRecursiveAttribute(name);
+		return null;
+	}
+
+	public String getLocalName() {
+		int index = name.indexOf(':');
+		if (index <= 0)
+			return name;
+
+		return name.substring(index + 1);
+	}
+
+	public void rename(String string) {
+		name = string;
+	}
+
+	public void setCDATA() {
+		cdata = true;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/tag/packageinfo b/bundleplugin/src/main/java/aQute/lib/tag/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/tag/packageinfo
@@ -0,0 +1 @@
+version 1.0
