diff --git a/bundleplugin/pom.xml b/bundleplugin/pom.xml
index 0dfc5e1..7c4bb24 100644
--- a/bundleplugin/pom.xml
+++ b/bundleplugin/pom.xml
@@ -55,15 +55,28 @@
      <target>1.5</target>
     </configuration>
    </plugin>
+    <!-- TEMP: only needed while we include aQute.bndlib 1.47 (not yet on central) -->
+   <plugin>
+    <groupId>org.apache.rat</groupId>
+    <artifactId>apache-rat-plugin</artifactId>
+    <configuration>
+     <excludes>
+      <exclude>**/packageinfo</exclude>
+      <exclude>**/aQute/**</exclude>
+     </excludes>
+    </configuration>
+   </plugin>
   </plugins>
  </build>
 
  <dependencies>
+<!--
   <dependency>
     <groupId>biz.aQute</groupId>
     <artifactId>bndlib</artifactId>
     <version>1.43.0</version>
   </dependency>
+-->
   <dependency>
     <groupId>org.apache.felix</groupId>
     <artifactId>org.apache.felix.bundlerepository</artifactId>
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/ConsumerType.java b/bundleplugin/src/main/java/aQute/bnd/annotation/ConsumerType.java
new file mode 100644
index 0000000..cbbc17b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/ConsumerType.java
@@ -0,0 +1,14 @@
+package aQute.bnd.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * Adding this annotation to a type in an API package indicates the the owner of
+ * that package will not change this interface in a minor update. Any backward
+ * compatible change to this interface requires a major update of the version of
+ * this package.
+ * 
+ */
+@Retention(RetentionPolicy.CLASS) @Target(ElementType.TYPE) public @interface ConsumerType {
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/Export.java b/bundleplugin/src/main/java/aQute/bnd/annotation/Export.java
new file mode 100644
index 0000000..27ea389
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/Export.java
@@ -0,0 +1,30 @@
+package aQute.bnd.annotation;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.PACKAGE)
+public @interface Export {
+    String MANDATORY = "mandatory";
+    String OPTIONAL  = "optional";
+    String USES      = "uses";
+    String EXCLUDE   = "exclude";
+    String INCLUDE   = "include";
+
+    String[] mandatory() default "";
+
+    String[] optional() default "";
+
+    Class<?>[] exclude() default Object.class;
+
+    Class<?>[] include() default Object.class;
+    
+    /**
+     * Use {@link @Version} annotation instead
+     * @return
+     */
+    @Deprecated()
+    String version() default "";
+    
+    
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/ProviderType.java b/bundleplugin/src/main/java/aQute/bnd/annotation/ProviderType.java
new file mode 100644
index 0000000..15ee17e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/ProviderType.java
@@ -0,0 +1,19 @@
+package aQute.bnd.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * This type is provided for convenience because it is the default. A change 
+ * in a provider type (that is all except Consumer types) can be changed with
+ * only a minor update to the package API version number.
+ * 
+ * This interface is similar to the Eclipse @noextend and @noimplement annotations.
+ * 
+ * 
+ * 
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+public @interface ProviderType {
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/UsePolicy.java b/bundleplugin/src/main/java/aQute/bnd/annotation/UsePolicy.java
new file mode 100644
index 0000000..36f0eaf
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/UsePolicy.java
@@ -0,0 +1,20 @@
+package aQute.bnd.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * This annotation can be applied to interface where an implementation should be
+ * treated as a use policy, not an implementation policy. Many package have
+ * interfaces that are very stable and can be maintained backward compatible for
+ * implementers during minor changes. For example, in Event Admin, the
+ * EventAdmin implementers should follow the minor version, e.g. [1.1,1.2), however,
+ * an implementer of EventHandler should not require such a small range. Therefore
+ * an interface like EventHandler should use this anotation.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+@Deprecated
+public @interface UsePolicy {
+    String RNAME = "LaQute/bnd/annotation/UsePolicy;";
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/Version.java b/bundleplugin/src/main/java/aQute/bnd/annotation/Version.java
new file mode 100644
index 0000000..fae42b1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/Version.java
@@ -0,0 +1,9 @@
+package aQute.bnd.annotation;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.PACKAGE})
+public @interface Version {
+	String value();
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Activate.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Activate.java
new file mode 100644
index 0000000..52284a0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Activate.java
@@ -0,0 +1,10 @@
+package aQute.bnd.annotation.component;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Activate {
+    String RNAME = "LaQute/bnd/annotation/component/Activate;";
+    
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Attribute.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Attribute.java
new file mode 100644
index 0000000..f089b75
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Attribute.java
@@ -0,0 +1,10 @@
+package aQute.bnd.annotation.component;
+
+public @interface Attribute {
+	class C {}
+	
+	String name() default "";
+	String description() default "";
+	String[] options();
+	
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Component.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Component.java
new file mode 100644
index 0000000..1fb39d6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Component.java
@@ -0,0 +1,38 @@
+package aQute.bnd.annotation.component;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS) @Target(ElementType.TYPE) public @interface Component {
+	String	RNAME					= "LaQute/bnd/annotation/component/Component;";
+	String	PROVIDE					= "provide";
+	String	NAME					= "name";
+	String	FACTORY					= "factory";
+	String	SERVICEFACTORY			= "servicefactory";
+	String	IMMEDIATE				= "immediate";
+	String	CONFIGURATION_POLICY	= "configurationPolicy";
+	String	ENABLED					= "enabled";
+	String	PROPERTIES				= "properties";
+	String	VERSION					= "version";
+	String	DESIGNATE				= "designate";
+	String	DESIGNATE_FACTORY		= "designateFactory";
+
+	String name() default "";
+
+	Class<?>[] provide() default Object.class;
+
+	String factory() default "";
+
+	boolean servicefactory() default false;
+
+	boolean enabled() default true;
+
+	boolean immediate() default false;
+
+	ConfigurationPolicy configurationPolicy() default ConfigurationPolicy.optional;
+
+	String[] properties() default {};
+
+	Class<?> designate() default Object.class;
+
+	Class<?> designateFactory() default Object.class;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/ConfigurationPolicy.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/ConfigurationPolicy.java
new file mode 100644
index 0000000..7651557
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/ConfigurationPolicy.java
@@ -0,0 +1,5 @@
+package aQute.bnd.annotation.component;
+
+public enum ConfigurationPolicy {
+    optional, require, ignore;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Deactivate.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Deactivate.java
new file mode 100644
index 0000000..5858ea0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Deactivate.java
@@ -0,0 +1,10 @@
+package aQute.bnd.annotation.component;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Deactivate {
+    String RNAME = "LaQute/bnd/annotation/component/Deactivate;";
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Modified.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Modified.java
new file mode 100644
index 0000000..655a535
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Modified.java
@@ -0,0 +1,10 @@
+package aQute.bnd.annotation.component;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Modified {
+    String RNAME = "LaQute/bnd/annotation/component/Modified;";
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Reference.java b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Reference.java
new file mode 100644
index 0000000..58894dd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/Reference.java
@@ -0,0 +1,33 @@
+package aQute.bnd.annotation.component;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Reference {
+    String RNAME    = "LaQute/bnd/annotation/component/Reference;";
+    String NAME     = "name";
+    String SERVICE  = "service";
+    String OPTIONAL = "optional";
+    String MULTIPLE = "multiple";
+    String DYNAMIC  = "dynamic";
+    String TARGET   = "target";
+    String TYPE     = "type";
+    String UNBIND   = "unbind";
+
+    String name() default "";
+
+    Class<?> service() default Object.class;
+
+    boolean optional() default false;
+
+    boolean multiple() default false;
+
+    boolean dynamic() default false;
+
+    String target() default "";
+    
+    String unbind() default "";
+
+    char type() default 0;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/component/packageinfo b/bundleplugin/src/main/java/aQute/bnd/annotation/component/packageinfo
new file mode 100644
index 0000000..ec0efd4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/component/packageinfo
@@ -0,0 +1 @@
+version 1.43.1
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Configurable.java b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Configurable.java
new file mode 100644
index 0000000..6dcf614
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Configurable.java
@@ -0,0 +1,262 @@
+package aQute.bnd.annotation.metatype;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+public class Configurable<T> {
+
+	
+	
+	
+	public static <T> T createConfigurable(Class<T> c, Map<?, ?> properties) {
+		Object o = Proxy.newProxyInstance(c.getClassLoader(), new Class<?>[] { c },
+				new ConfigurableHandler(properties, c.getClassLoader()));
+		return c.cast(o);
+	}
+
+	public static <T> T createConfigurable(Class<T> c, Dictionary<?, ?> properties) {
+		Map<Object,Object> alt = new HashMap<Object,Object>();
+		for( Enumeration<?> e = properties.keys(); e.hasMoreElements(); ) {
+			Object key = e.nextElement();
+			alt.put(key, properties.get(key));
+		}
+		return createConfigurable(c, alt);
+	}
+
+	static class ConfigurableHandler implements InvocationHandler {
+		final Map<?, ?>	properties;
+		final ClassLoader			loader;
+
+		ConfigurableHandler(Map<?, ?> properties, ClassLoader loader) {
+			this.properties = properties;
+			this.loader = loader;
+		}
+
+		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+			Meta.AD ad = method.getAnnotation(Meta.AD.class);
+			String id = Configurable.mangleMethodName(method.getName());
+
+			if (ad != null && !ad.id().equals(Meta.NULL))
+				id = ad.id();
+
+			Object o = properties.get(id);
+
+			if (o == null) {
+				if (ad != null) {
+					if (ad.required())
+						throw new IllegalStateException("Attribute is required but not set "
+								+ method.getName());
+
+					o = ad.deflt();
+					if (o.equals(Meta.NULL))
+						o = null;
+				}
+			}
+			if (o == null) {
+				if (method.getReturnType().isPrimitive()
+						|| Number.class.isAssignableFrom(method.getReturnType())) {
+
+					o = "0";
+				} else
+					return null;
+			}
+
+			return convert(method.getGenericReturnType(), o);
+		}
+
+		@SuppressWarnings( { "unchecked" }) public Object convert(Type type, Object o)
+				throws Exception {
+			if (type instanceof ParameterizedType) {
+				ParameterizedType pType = (ParameterizedType) type;
+				return convert(pType, o);
+			}
+
+			if (type instanceof GenericArrayType) {
+				GenericArrayType gType = (GenericArrayType) type;
+				return convertArray(gType.getGenericComponentType(), o);
+			}
+
+			Class<?> resultType = (Class<?>) type;
+
+			if (resultType.isArray()) {
+				return convertArray(resultType.getComponentType(), o);
+			}
+
+			Class<?> actualType = o.getClass();
+			if (actualType.isAssignableFrom(resultType))
+				return o;
+
+			if (resultType == boolean.class || resultType == Boolean.class) {
+				if ( actualType == boolean.class || actualType == Boolean.class)
+					return o;
+				
+				if (Number.class.isAssignableFrom(actualType)) {
+					double b = ((Number) o).doubleValue();
+					if (b == 0)
+						return false;
+					else
+						return true;
+				}
+				return true;
+				
+			} else if (resultType == byte.class || resultType == Byte.class) {
+				if (Number.class.isAssignableFrom(actualType))
+					return ((Number) o).byteValue();
+				resultType = Byte.class;
+			} else if (resultType == char.class) {
+				resultType = Character.class;
+			} else if (resultType == short.class) {
+				if (Number.class.isAssignableFrom(actualType))
+					return ((Number) o).shortValue();
+				resultType = Short.class;
+			} else if (resultType == int.class) {
+				if (Number.class.isAssignableFrom(actualType))
+					return ((Number) o).intValue();
+				resultType = Integer.class;
+			} else if (resultType == long.class) {
+				if (Number.class.isAssignableFrom(actualType))
+					return ((Number) o).longValue();
+				resultType = Long.class;
+			} else if (resultType == float.class) {
+				if (Number.class.isAssignableFrom(actualType))
+					return ((Number) o).floatValue();
+				resultType = Float.class;
+			} else if (resultType == double.class) {
+				if (Number.class.isAssignableFrom(actualType))
+					return ((Number) o).doubleValue();
+				resultType = Double.class;
+			}
+
+			if (resultType.isPrimitive())
+				throw new IllegalArgumentException("Unknown primitive: " + resultType);
+
+			if (Number.class.isAssignableFrom(resultType) && actualType == Boolean.class) {
+				Boolean b = (Boolean) o;
+				o = b ? "1" : "0";
+			} else if (actualType == String.class) {
+				String input = (String) o;
+				if (Enum.class.isAssignableFrom(resultType)) {
+					return Enum.valueOf((Class<Enum>) resultType, input);
+				}
+				if (resultType == Class.class && loader != null) {
+					return loader.loadClass(input);
+				}
+				if (resultType == Pattern.class) {
+					return Pattern.compile(input);
+				}
+			}
+
+			try {
+				Constructor<?> c = resultType.getConstructor(String.class);
+				return c.newInstance(o.toString());
+			} catch (Throwable t) {
+				// handled on next line
+			}
+			throw new IllegalArgumentException("No conversion to " + resultType + " from "
+					+ actualType + " value " + o);
+		}
+
+		private Object convert(ParameterizedType pType, Object o) throws InstantiationException,
+				IllegalAccessException, Exception {
+			Class<?> resultType = (Class<?>) pType.getRawType();
+			if (Collection.class.isAssignableFrom(resultType)) {
+				Collection<?> input = toCollection(o);
+				if (resultType.isInterface()) {
+					if (resultType == Collection.class || resultType == List.class)
+						resultType = ArrayList.class;
+					else if (resultType == Set.class || resultType == SortedSet.class)
+						resultType = TreeSet.class;
+					else if (resultType == Queue.class /*|| resultType == Deque.class*/)
+						resultType = LinkedList.class;
+					else if (resultType == Queue.class /*|| resultType == Deque.class*/)
+						resultType = LinkedList.class;
+					else
+						throw new IllegalArgumentException(
+								"Unknown interface for a collection, no concrete class found: "
+										+ resultType);
+				}
+				
+				@SuppressWarnings("unchecked") Collection<Object> result = (Collection<Object>) resultType
+						.newInstance();
+				Type componentType = pType.getActualTypeArguments()[0];
+
+				for (Object i : input) {
+					result.add(convert(componentType, i));
+				}
+				return result;
+			} else if (pType.getRawType() == Class.class) {
+				return loader.loadClass(o.toString());
+			}
+			throw new IllegalArgumentException("cannot convert to " + pType
+					+ " because it uses generics and is not a Collection");
+		}
+
+		Object convertArray(Type componentType, Object o) throws Exception {
+			Collection<?> input = toCollection(o);
+			Class<?> componentClass = getRawClass(componentType);
+			Object array = Array.newInstance(componentClass, input.size());
+
+			int i = 0;
+			for (Object next : input) {
+				Array.set(array, i++, convert(componentType, next));
+			}
+			return array;
+		}
+
+		private Class<?> getRawClass(Type type) {
+			if (type instanceof Class)
+				return (Class<?>) type;
+
+			if (type instanceof ParameterizedType)
+				return (Class<?>) ((ParameterizedType) type).getRawType();
+
+			throw new IllegalArgumentException(
+					"For the raw type, type must be ParamaterizedType or Class but is " + type);
+		}
+
+		private Collection<?> toCollection(Object o) {
+			if (o instanceof Collection)
+				return (Collection<?>) o;
+
+			if (o.getClass().isArray()) {
+				if ( o.getClass().getComponentType().isPrimitive()) {
+					int length = Array.getLength(o);
+					List<Object> result = new ArrayList<Object>(length);
+					for ( int i=0; i<length; i++) {
+						result.add( Array.get(o, i));
+					}
+					return result;
+				} else
+					return Arrays.asList((Object[]) o);
+			}
+
+			if ( o instanceof String) {
+				String s = (String)o;
+				if (s.indexOf('|')>0)
+					return Arrays.asList(s.split("\\|"));					
+			}
+			return Arrays.asList(o);
+		}
+
+	}
+	
+	
+	public static String mangleMethodName(String id) {
+		StringBuilder sb = new StringBuilder(id);
+		for ( int i =0; i<sb.length(); i++) {
+			char c  = sb.charAt(i);
+			boolean twice = i < sb.length()-1 && sb.charAt(i+1) ==c;
+			if ( c == '$' || c == '_') {
+				if ( twice )
+					sb.deleteCharAt(i+1);
+				else 
+					if ( c == '$')
+						sb.deleteCharAt(i--); // Remove dollars
+					else
+						sb.setCharAt(i, '.'); // Make _ into .
+			}				
+		}
+		return sb.toString();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Meta.java b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Meta.java
new file mode 100644
index 0000000..a2686e5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Meta.java
@@ -0,0 +1,180 @@
+package aQute.bnd.annotation.metatype;
+
+import java.lang.annotation.*;
+
+/**
+ * The Metadata interface provides access to the properties that underly a
+ * Configurable interface. Any Configurable interface can implement this
+ * interface. The interface provides the annotations that can be used to create
+ * metatype objects.
+ * 
+ * @ConsumerInterface
+ */
+
+public interface Meta {
+	enum Type {
+		Boolean,
+		Byte,
+		Character,
+		Short,
+		Integer,
+		Long,
+		Float,
+		Double,
+		String,
+		Password
+	}
+
+	/**
+	 * Constant NULL for default usage
+	 */
+	final String	NULL	= "§NULL§";
+
+	/**
+	 * The OCD Annotation maps to the OCD element in the Metatype specification.
+	 * The only difference is that it is possible to create a Designate element
+	 * as well.
+	 * 
+	 */
+	@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface OCD {
+		/**
+		 * The name for this component. The default name is a the short class
+		 * name that us un-camel cased to make it more readable.
+		 * 
+		 * @return The name of this component
+		 */
+		String name() default NULL;
+
+		/**
+		 * The id of the component. Default the name of the class in FQN
+		 * notation but with nested classes using the $ as separator (not .).
+		 * 
+		 * The Felix webconsole always uses this id as the PID and not the pid
+		 * in the Designate element. Reported as an error.
+		 * 
+		 * @return the id
+		 */
+		String id() default NULL;
+
+		/**
+		 * The localization prefix. The default localization prefix is the name
+		 * of the class with a $ separator for nested classes.
+		 * 
+		 * @return the localization prefix.
+		 */
+		String localization() default NULL;
+
+		/**
+		 * A description for this ocd. The default is empty.
+		 * 
+		 * @return the description
+		 */
+		String description() default NULL;
+
+		/**
+		 * Defines if this is for a factory or not.
+		 */
+		boolean factory() default false;
+	}
+
+	/**
+	 * The AD element in the Metatype specification.
+	 * 
+	 */
+	@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @interface AD {
+		/**
+		 * A description of the attribute. Default is empty.
+		 * 
+		 * @return The description of the attribute.
+		 */
+		String description() default NULL;
+
+		/**
+		 * The name of the attribute. By default the un-camel cased version of
+		 * the method name.
+		 * 
+		 * @return the name
+		 */
+		String name() default NULL;
+
+		/**
+		 * The id of the attribute. By default the name of the method. The id is
+		 * the key used to access the properties. This is the reason the AD is a
+		 * runtime annotation so the runtime can find the proper key.
+		 * 
+		 * @return the id
+		 */
+		String id() default NULL;
+
+		/**
+		 * The type of the field. This must be one of the basic types in the
+		 * metatype specification. By default, the type is derived from the
+		 * return type of the method. This includes most collections and arrays.
+		 * Unrecognized types are defaulted to String.
+		 * 
+		 * @return the type to be used.
+		 */
+		Type type() default Type.String;
+
+		/**
+		 * The cardinality of the attribute. If not explicitly set it will be
+		 * derived from the attributes return type. Collections return
+		 * Integer.MIN_VALUE and arrays use Integer.MAX_VALUE.
+		 * 
+		 * If a single string needs to be converted to a Collection or array
+		 * then the | will be used as a separator to split the line.
+		 * 
+		 * @return the cardinality of the attribute
+		 */
+		int cardinality() default 0;
+
+		/**
+		 * The minimum value. This string must be converted to the attribute
+		 * type before comparison takes place.
+		 * 
+		 * @return the min value
+		 */
+		String min() default NULL;
+
+		/**
+		 * The maximum value. This string must be converted to the attribute
+		 * type before comparison takes place.
+		 * 
+		 * @return the max value
+		 */
+		String max() default NULL;
+
+		/**
+		 * The default value. This value must be converted to the return type of
+		 * the attribute. For multi valued returns use the | as separator.
+		 * 
+		 * @return the default value
+		 */
+		String deflt() default NULL;
+
+		/**
+		 * Indicates that this attribute is required. By default attributes are
+		 * required.
+		 * 
+		 * @return
+		 */
+		boolean required() default true;
+
+		/**
+		 * Provide labels for options. These labels must match the values. If no
+		 * labels are set, the un-cameled version of the values are used (if
+		 * they are set of course).
+		 * 
+		 * @return the option labels
+		 */
+		String[] optionLabels() default NULL;
+
+		/**
+		 * The values of options. If not set and the return type is an enum
+		 * class then the values will be derived from this return type.
+		 * 
+		 * @return the option labels
+		 */
+		String[] optionValues() default NULL;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/packageinfo b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/packageinfo
new file mode 100644
index 0000000..ec0efd4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/packageinfo
@@ -0,0 +1 @@
+version 1.43.1
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/packageinfo b/bundleplugin/src/main/java/aQute/bnd/annotation/packageinfo
new file mode 100644
index 0000000..ec0efd4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/packageinfo
@@ -0,0 +1 @@
+version 1.43.1
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/CircularDependencyException.java b/bundleplugin/src/main/java/aQute/bnd/build/CircularDependencyException.java
new file mode 100644
index 0000000..f08255b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/CircularDependencyException.java
@@ -0,0 +1,10 @@
+package aQute.bnd.build;
+
+public class CircularDependencyException extends Exception {
+    public CircularDependencyException(String string) {
+        super(string);
+    }
+
+    private static final long serialVersionUID = 1L;
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Container.java b/bundleplugin/src/main/java/aQute/bnd/build/Container.java
new file mode 100644
index 0000000..72715b0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Container.java
@@ -0,0 +1,203 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.bnd.service.RepositoryPlugin.Strategy;
+import aQute.lib.osgi.*;
+
+public class Container {
+	public enum TYPE {
+		REPO, PROJECT, EXTERNAL, LIBRARY, ERROR
+	}
+
+	final File					file;
+	final TYPE					type;
+	final String				bsn;
+	final String				version;
+	final String				error;
+	final Project				project;
+	volatile Map<String, String>	attributes;
+	private long				manifestTime;
+	private Manifest			manifest;
+
+	Container(Project project, String bsn, String version, TYPE type, File source, String error,
+			Map<String, String> attributes) {
+		this.bsn = bsn;
+		this.version = version;
+		this.type = type;
+		this.file = source != null ? source : new File("/" + bsn + ":" + version + ":" + type);
+		this.project = project;
+		this.error = error;
+		if (attributes == null || attributes.isEmpty())
+			this.attributes = Collections.emptyMap();
+		else
+			this.attributes = attributes;
+	}
+
+	public Container(Project project, File file) {
+		this(project, file.getName(), "project", TYPE.PROJECT, file, null, null);
+	}
+
+	public Container(File file) {
+		this(null, file.getName(), "project", TYPE.EXTERNAL, file, null, null);
+	}
+
+	public File getFile() {
+		return file;
+	}
+
+	/**
+	 * Iterate over the containers and get the files they represent
+	 * 
+	 * @param files
+	 * @return
+	 * @throws Exception
+	 */
+	public boolean contributeFiles(List<File> files, Processor reporter) throws Exception {
+		switch (type) {
+		case EXTERNAL:
+		case REPO:
+			files.add(file);
+			return true;
+
+		case PROJECT:
+			File[] fs = project.build();
+			reporter.getInfo(project);
+			if (fs == null)
+				return false;
+
+			for (File f : fs)
+				files.add(f);
+			return true;
+
+		case LIBRARY:
+			List<Container> containers = getMembers();
+			for (Container container : containers) {
+				if (!container.contributeFiles(files, reporter))
+					return false;
+			}
+			return true;
+
+		case ERROR:
+			reporter.error(error);
+			return false;
+		}
+		return false;
+	}
+
+	public String getBundleSymbolicName() {
+		return bsn;
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	public TYPE getType() {
+		return type;
+	}
+
+	public String getError() {
+		return error;
+	}
+
+	public boolean equals(Object other) {
+		if (other instanceof Container)
+			return file.equals(((Container) other).file);
+		else
+			return false;
+	}
+
+	public int hashCode() {
+		return file.hashCode();
+	}
+
+	public Project getProject() {
+		return project;
+	}
+
+	/**
+	 * Must show the file name or the error formatted as a file name
+	 * 
+	 * @return
+	 */
+	public String toString() {
+		if (getError() != null)
+			return "/error/" + getError();
+		else
+			return getFile().getAbsolutePath();
+	}
+
+	public Map<String, String> getAttributes() {
+		return attributes;
+	}
+	
+	public void putAttribute(String name, String value) {
+		if (attributes == Collections.<String,String>emptyMap())
+			attributes = new HashMap<String, String>(1);
+		attributes.put(name, value);
+	}
+
+	/**
+	 * Return the this if this is anything else but a library. If it is a
+	 * library, return the members. This could work recursively, e.g., libraries
+	 * can point to libraries.
+	 * 
+	 * @return
+	 * @throws Exception
+	 */
+	public List<Container> getMembers() throws Exception {
+		List<Container> result = project.newList();
+
+		// Are ww a library? If no, we are the result
+		if (getType() == TYPE.LIBRARY) {
+			// We are a library, parse the file. This is
+			// basically a specification clause per line.
+			// I.e. you can do bsn; version, bsn2; version. But also
+			// spread it out over lines.
+			InputStream in = new FileInputStream(file);
+			BufferedReader rd = new BufferedReader(new InputStreamReader(in,
+					Constants.DEFAULT_CHARSET));
+			try {
+				String line;
+				while ((line = rd.readLine()) != null) {
+					line = line.trim();
+					if (!line.startsWith("#") && line.length() > 0) {
+						List<Container> list = project.getBundles(Strategy.HIGHEST, line, null);
+						result.addAll(list);
+					}
+				}
+			} finally {
+				in.close();
+			}
+		} else
+			result.add(this);
+
+		return result;
+	}
+
+	/**
+	 * Answer the manifest for this container (if possible). Manifest is cached
+	 * until the file is renewed.
+	 */
+
+	public Manifest getManifest() throws Exception {
+		if (getError() != null || getFile() == null)
+			return null;
+
+		if (manifestTime < getFile().lastModified()) {
+			InputStream in = new FileInputStream(getFile());
+			try {
+				JarInputStream jin = new JarInputStream(in);
+				manifest = jin.getManifest();
+				jin.close();
+				manifestTime = getFile().lastModified();
+			} finally {
+				in.close();
+			}
+		}
+		return manifest;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Project.java b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
new file mode 100644
index 0000000..d05ba0b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
@@ -0,0 +1,1832 @@
+package aQute.bnd.build;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+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.StringTokenizer;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.jar.Manifest;
+
+import aQute.bnd.help.Syntax;
+import aQute.bnd.maven.support.Pom;
+import aQute.bnd.maven.support.ProjectPom;
+import aQute.bnd.service.CommandPlugin;
+import aQute.bnd.service.DependencyContributor;
+import aQute.bnd.service.Deploy;
+import aQute.bnd.service.RepositoryPlugin;
+import aQute.bnd.service.RepositoryPlugin.Strategy;
+import aQute.bnd.service.Scripter;
+import aQute.bnd.service.action.Action;
+import aQute.bnd.service.action.NamedAction;
+import aQute.lib.io.IO;
+import aQute.lib.osgi.Builder;
+import aQute.lib.osgi.Constants;
+import aQute.lib.osgi.Instruction;
+import aQute.lib.osgi.Jar;
+import aQute.lib.osgi.Processor;
+import aQute.lib.osgi.Resource;
+import aQute.lib.osgi.eclipse.EclipseClasspath;
+import aQute.libg.generics.Create;
+import aQute.libg.header.OSGiHeader;
+import aQute.libg.sed.Sed;
+
+/**
+ * This class is NOT threadsafe
+ * 
+ * @author aqute
+ * 
+ */
+
+public class Project extends Processor {
+
+	final static String			DEFAULT_ACTIONS			= "build; label='Build', test; label='Test', run; label='Run', clean; label='Clean', release; label='Release', refreshAll; label=Refresh, deploy;label=Deploy";
+	public final static String	BNDFILE					= "bnd.bnd";
+	public final static String	BNDCNF					= "cnf";
+	final Workspace				workspace;
+	boolean						preparedPaths;
+	final Collection<Project>	dependson				= new LinkedHashSet<Project>();
+	final Collection<Container>	buildpath				= new LinkedHashSet<Container>();
+	final Collection<Container>	testpath				= new LinkedHashSet<Container>();
+	final Collection<Container>	runpath					= new LinkedHashSet<Container>();
+	final Collection<Container>	runbundles				= new LinkedHashSet<Container>();
+	File						runstorage;
+	final Collection<File>		sourcepath				= new LinkedHashSet<File>();
+	final Collection<File>		allsourcepath			= new LinkedHashSet<File>();
+	final Collection<Container>	bootclasspath			= new LinkedHashSet<Container>();
+	final Lock					lock					= new ReentrantLock(true);
+	volatile String				lockingReason;
+	volatile Thread				lockingThread;
+	File						output;
+	File						target;
+	boolean						inPrepare;
+	int							revision;
+	File						files[];
+	private long				buildtime;
+	static List<Project>		trail					= new ArrayList<Project>();
+	boolean						delayRunDependencies	= false;
+
+	public Project(Workspace workspace, File projectDir, File buildFile) throws Exception {
+		super(workspace);
+		this.workspace = workspace;
+		setFileMustExist(false);
+		setProperties(buildFile);
+		assert workspace != null;
+		// For backward compatibility reasons, we also read
+		readBuildProperties();
+	}
+
+	public Project(Workspace workspace, File buildDir) throws Exception {
+		this(workspace, buildDir, new File(buildDir, BNDFILE));
+	}
+
+	private void readBuildProperties() throws Exception {
+		try {
+			File f = getFile("build.properties");
+			if (f.isFile()) {
+				Properties p = loadProperties(f);
+				for (Enumeration<?> e = p.propertyNames(); e.hasMoreElements();) {
+					String key = (String) e.nextElement();
+					String newkey = key;
+					if (key.indexOf('$') >= 0) {
+						newkey = getReplacer().process(key);
+					}
+					setProperty(newkey, p.getProperty(key));
+				}
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	public static Project getUnparented(File propertiesFile) throws Exception {
+		propertiesFile = propertiesFile.getAbsoluteFile();
+		Workspace workspace = new Workspace(propertiesFile.getParentFile());
+		Project project = new Project(workspace, propertiesFile.getParentFile());
+		project.setProperties(propertiesFile);
+		project.setFileMustExist(true);
+		return project;
+	}
+
+	public synchronized boolean isValid() {
+		return getBase().isDirectory() && getPropertiesFile().isFile();
+	}
+
+	/**
+	 * Return a new builder that is nicely setup for this project. Please close
+	 * this builder after use.
+	 * 
+	 * @param parent
+	 *            The project builder to use as parent, use this project if null
+	 * @return
+	 * @throws Exception
+	 */
+	public synchronized ProjectBuilder getBuilder(ProjectBuilder parent) throws Exception {
+
+		ProjectBuilder builder;
+
+		if (parent == null)
+			builder = new ProjectBuilder(this);
+		else
+			builder = new ProjectBuilder(parent);
+
+		builder.setBase(getBase());
+
+		return builder;
+	}
+
+	public synchronized int getChanged() {
+		return revision;
+	}
+
+	/*
+	 * Indicate a change in the external world that affects our build. This will
+	 * clear any cached results.
+	 */
+	public synchronized void setChanged() {
+		// if (refresh()) {
+		preparedPaths = false;
+		files = null;
+		revision++;
+		// }
+	}
+
+	public Workspace getWorkspace() {
+		return workspace;
+	}
+
+	public String toString() {
+		return getBase().getName();
+	}
+
+	/**
+	 * Set up all the paths
+	 */
+
+	public synchronized void prepare() throws Exception {
+		if (!isValid()) {
+			warning("Invalid project attempts to prepare: %s", this);
+			return;
+		}
+
+		if (inPrepare)
+			throw new CircularDependencyException(trail.toString() + "," + this);
+
+		trail.add(this);
+		try {
+			if (!preparedPaths) {
+				inPrepare = true;
+				try {
+					dependson.clear();
+					buildpath.clear();
+					sourcepath.clear();
+					allsourcepath.clear();
+					bootclasspath.clear();
+					testpath.clear();
+					runpath.clear();
+					runbundles.clear();
+
+					// We use a builder to construct all the properties for
+					// use.
+					setProperty("basedir", getBase().getAbsolutePath());
+
+					// If a bnd.bnd file exists, we read it.
+					// Otherwise, we just do the build properties.
+					if (!getPropertiesFile().isFile() && new File(getBase(), ".classpath").isFile()) {
+						// Get our Eclipse info, we might depend on other
+						// projects
+						// though ideally this should become empty and void
+						doEclipseClasspath();
+					}
+
+					// Calculate our source directory
+
+					File src = getSrc();
+					if (src.isDirectory()) {
+						sourcepath.add(src);
+						allsourcepath.add(src);
+					} else
+						sourcepath.add(getBase());
+
+					// Set default bin directory
+					output = getFile(getProperty("bin", "bin")).getAbsoluteFile();
+					if (!output.exists()) {
+						output.mkdirs();
+						getWorkspace().changedFile(output);
+					}
+					if (!output.isDirectory())
+						error("Can not find output directory: " + output);
+					else if (!buildpath.contains(output))
+						buildpath.add(new Container(this, output));
+
+					// Where we store all our generated stuff.
+					target = getFile(getProperty("target", "generated"));
+					if (!target.exists()) {
+						target.mkdirs();
+						getWorkspace().changedFile(target);
+					}
+					
+					// Where the launched OSGi framework stores stuff
+					String runStorageStr = getProperty(Constants.RUNSTORAGE);
+					runstorage = runStorageStr != null ? getFile(runStorageStr) : null;
+
+					// We might have some other projects we want build
+					// before we do anything, but these projects are not in
+					// our path. The -dependson allows you to build them before.
+
+					List<Project> dependencies = new ArrayList<Project>();
+					// dependencies.add( getWorkspace().getProject("cnf"));
+
+					String dp = getProperty(Constants.DEPENDSON);
+					Set<String> requiredProjectNames = parseHeader(dp).keySet();
+					List<DependencyContributor> dcs = getPlugins(DependencyContributor.class);
+					for (DependencyContributor dc : dcs)
+						dc.addDependencies(this, requiredProjectNames);
+
+					for (String p : requiredProjectNames) {
+						Project required = getWorkspace().getProject(p);
+						if (required == null)
+							error("No such project " + required + " on " + Constants.DEPENDSON);
+						else {
+							dependencies.add(required);
+						}
+
+					}
+
+					// We have two paths that consists of repo files, projects,
+					// or some other stuff. The doPath routine adds them to the
+					// path and extracts the projects so we can build them
+					// before.
+
+					doPath(buildpath, dependencies, parseBuildpath(), bootclasspath);
+					doPath(testpath, dependencies, parseTestpath(), bootclasspath);
+					if (!delayRunDependencies) {
+						doPath(runpath, dependencies, parseRunpath(), null);
+						doPath(runbundles, dependencies, parseRunbundles(), null);
+					}
+
+					// We now know all dependent projects. But we also depend
+					// on whatever those projects depend on. This creates an
+					// ordered list without any duplicates. This of course
+					// assumes
+					// that there is no circularity. However, this is checked
+					// by the inPrepare flag, will throw an exception if we
+					// are circular.
+
+					Set<Project> done = new HashSet<Project>();
+					done.add(this);
+					allsourcepath.addAll(sourcepath);
+
+					for (Project project : dependencies)
+						project.traverse(dependson, done);
+
+					for (Project project : dependson) {
+						allsourcepath.addAll(project.getSourcePath());
+					}
+					if (isOk())
+						preparedPaths = true;
+				} finally {
+					inPrepare = false;
+				}
+			}
+		} finally {
+			trail.remove(this);
+		}
+	}
+
+	public File getSrc() {
+		return new File(getBase(), getProperty("src", "src"));
+	}
+
+	private void traverse(Collection<Project> dependencies, Set<Project> visited) throws Exception {
+		if (visited.contains(this))
+			return;
+
+		visited.add(this);
+
+		for (Project project : getDependson())
+			project.traverse(dependencies, visited);
+
+		dependencies.add(this);
+	}
+
+	/**
+	 * Iterate over the entries and place the projects on the projects list and
+	 * all the files of the entries on the resultpath.
+	 * 
+	 * @param resultpath
+	 *            The list that gets all the files
+	 * @param projects
+	 *            The list that gets any projects that are entries
+	 * @param entries
+	 *            The input list of classpath entries
+	 */
+	private void doPath(Collection<Container> resultpath, Collection<Project> projects,
+			Collection<Container> entries, Collection<Container> bootclasspath) {
+		for (Container cpe : entries) {
+			if (cpe.getError() != null)
+				error(cpe.getError());
+			else {
+				if (cpe.getType() == Container.TYPE.PROJECT) {
+					projects.add(cpe.getProject());
+				}
+				if (bootclasspath != null && cpe.getBundleSymbolicName().startsWith("ee.")
+						|| cpe.getAttributes().containsKey("boot"))
+					bootclasspath.add(cpe);
+				else
+					resultpath.add(cpe);
+			}
+		}
+	}
+
+	/**
+	 * Parse the list of bundles that are a prerequisite to this project.
+	 * 
+	 * Bundles are listed in repo specific names. So we just let our repo
+	 * plugins iterate over the list of bundles and we get the highest version
+	 * from them.
+	 * 
+	 * @return
+	 */
+
+	private List<Container> parseBuildpath() throws Exception {
+		List<Container> bundles = getBundles(Strategy.LOWEST, getProperty(Constants.BUILDPATH), Constants.BUILDPATH);
+		appendPackages(Strategy.LOWEST, getProperty(Constants.BUILDPACKAGES), bundles, ResolverMode.build);
+		return bundles;
+	}
+
+	private List<Container> parseRunpath() throws Exception {
+		return getBundles(Strategy.HIGHEST, getProperty(Constants.RUNPATH), Constants.RUNPATH);
+	}
+
+	private List<Container> parseRunbundles() throws Exception {
+		return getBundles(Strategy.HIGHEST, getProperty(Constants.RUNBUNDLES), Constants.RUNBUNDLES);
+	}
+	
+	private List<Container> parseTestpath() throws Exception {
+		return getBundles(Strategy.HIGHEST, getProperty(Constants.TESTPATH), Constants.TESTPATH);
+	}
+	
+	/**
+	 * Analyze the header and return a list of files that should be on the
+	 * build, test or some other path. The list is assumed to be a list of bsns
+	 * with a version specification. The special case of version=project
+	 * indicates there is a project in the same workspace. The path to the
+	 * output directory is calculated. The default directory ${bin} can be
+	 * overridden with the output attribute.
+	 * 
+	 * @param strategy
+	 *            STRATEGY_LOWEST or STRATEGY_HIGHEST
+	 * @param spec
+	 *            The header
+	 * @return
+	 */
+	public List<Container> getBundles(Strategy strategyx, String spec, String source) throws Exception {
+		List<Container> result = new ArrayList<Container>();
+		Map<String, Map<String, String>> bundles = parseHeader(spec);
+
+		try {
+			for (Iterator<Map.Entry<String, Map<String, String>>> i = bundles.entrySet().iterator(); i
+					.hasNext();) {
+				Map.Entry<String, Map<String, String>> entry = i.next();
+				String bsn = entry.getKey();
+				Map<String, String> attrs = entry.getValue();
+
+				Container found = null;
+
+				// Check if we have to use the maven pom ...
+				if (bsn.equals("pom")) {
+					doMavenPom(strategyx, result, attrs.get("scope"));
+					continue;
+				}
+
+				String versionRange = attrs.get("version");
+
+				if (versionRange != null) {
+					if (versionRange.equals("latest") || versionRange.equals("snapshot")) {
+						found = getBundle(bsn, versionRange, strategyx, attrs);
+					}
+				}
+				if (found == null) {
+					if (versionRange != null
+							&& (versionRange.equals("project") || versionRange.equals("latest"))) {
+						Project project = getWorkspace().getProject(bsn);
+						if (project != null && project.exists()) {
+							File f = project.getOutput();
+							found = new Container(project, bsn, "project", Container.TYPE.PROJECT,
+									f, null, attrs);
+						} else {
+							error("Reference to project that does not exist in workspace\n"
+									+ "  Project       %s\n" + "  Specification %s", bsn, spec);
+							continue;
+						}
+					} else if (versionRange != null && versionRange.equals("file")) {
+						File f = getFile(bsn);
+						String error = null;
+						if (!f.exists())
+							error = "File does not exist: " + f.getAbsolutePath();
+						if (f.getName().endsWith(".lib")) {
+							found = new Container(this, bsn, "file", Container.TYPE.LIBRARY, f,
+									error, attrs);
+						} else {
+							found = new Container(this, bsn, "file", Container.TYPE.EXTERNAL, f,
+									error, attrs);
+						}
+					} else {
+						found = getBundle(bsn, versionRange, strategyx, attrs);
+					}
+				}
+
+				if (found != null) {
+					List<Container> libs = found.getMembers();
+					for (Container cc : libs) {
+						if (result.contains(cc))
+							warning("Multiple bundles with the same final URL: " + cc);
+
+						result.add(cc);
+					}
+				} else {
+					// Oops, not a bundle in sight :-(
+					Container x = new Container(this, bsn, versionRange, Container.TYPE.ERROR,
+							null, bsn + ";version=" + versionRange + " not found", attrs);
+					result.add(x);
+					warning("Can not find URL for bsn " + bsn);
+				}
+			}
+		} catch (CircularDependencyException e) {
+			String message = e.getMessage();
+			if (source != null)
+				message = String.format("%s (from property: %s)", message, source);
+			error("Circular dependency detected from project %s: %s", e, getName(), message);
+		} catch (Exception e) {
+			error("Unexpected error while trying to get the bundles from " + spec, e);
+			e.printStackTrace();
+		}
+		return result;
+	}
+	
+	/**
+	 * Calculates the containers required to fulfil the {@code -buildpackages}
+	 * instruction, and appends them to the existing list of containers.
+	 * 
+	 * @param strategyx
+	 *            The package-version disambiguation strategy.
+	 * @param spec
+	 *            The value of the @{code -buildpackages} instruction.
+	 * @throws Exception
+	 */
+	public void appendPackages(Strategy strategyx, String spec, List<Container> resolvedBundles, ResolverMode mode) throws Exception {
+		Map<File, Container> pkgResolvedBundles = new HashMap<File, Container>();
+		
+		List<Entry<String, Map<String, String>>> queue = new LinkedList<Map.Entry<String,Map<String,String>>>();
+		queue.addAll(parseHeader(spec).entrySet());
+		
+		while (!queue.isEmpty()) {
+			Entry<String, Map<String, String>> entry = queue.remove(0);
+			
+			String pkgName = entry.getKey();
+			Map<String, String> attrs = entry.getValue();
+			
+			Container found = null;
+			
+			String versionRange = attrs.get(Constants.VERSION_ATTRIBUTE);
+			if ("latest".equals(versionRange) || "snapshot".equals(versionRange))
+				found = getPackage(pkgName, versionRange, strategyx, attrs, mode);
+
+			if (found == null)
+				found = getPackage(pkgName, versionRange, strategyx, attrs, mode);
+
+			if (found != null) {
+				if (resolvedBundles.contains(found)) {
+					// Don't add his bundle because it was already included using -buildpath
+				} else {
+					List<Container> libs = found.getMembers();
+					for (Container cc : libs) {
+						Container existing = pkgResolvedBundles.get(cc.file);
+						if (existing != null)
+							addToPackageList(existing, attrs.get("packages"));
+						else {
+							addToPackageList(cc, attrs.get("packages"));
+							pkgResolvedBundles.put(cc.file, cc);
+						}
+						
+						String importUses = cc.getAttributes().get("import-uses");
+						if (importUses != null)
+							queue.addAll(0, parseHeader(importUses).entrySet());
+					}
+				}
+			} else {
+				// Unable to resolve
+				Container x = new Container(this, "X", versionRange, Container.TYPE.ERROR, null, "package " + pkgName + ";version=" + versionRange + " not found", attrs);
+				resolvedBundles.add(x);
+				warning("Can not find URL for package " + pkgName);
+			}
+		}
+		
+		for (Container container : pkgResolvedBundles.values()) {
+			resolvedBundles.add(container);
+		}
+	}
+	
+	static void mergeNames(String names, Set<String> set) {
+		StringTokenizer tokenizer = new StringTokenizer(names, ",");
+		while (tokenizer.hasMoreTokens())
+			set.add(tokenizer.nextToken().trim());
+	}
+	
+	static String flatten(Set<String> names) {
+		StringBuilder builder = new StringBuilder();
+		boolean first = true;
+		for (String name : names) {
+			if (!first) builder.append(',');
+			builder.append(name);
+			first = false;
+		}
+		return builder.toString();
+	}
+
+	static void addToPackageList(Container container, String newPackageNames) {
+		Set<String> merged = new HashSet<String>();
+		
+		String packageListStr = container.attributes.get("packages");
+		if (packageListStr != null)
+			mergeNames(packageListStr, merged);
+		if (newPackageNames != null)
+			mergeNames(newPackageNames, merged);
+		
+		container.putAttribute("packages", flatten(merged));
+	}
+
+	/**
+	 * Find a container to fulfil a package requirement
+	 * 
+	 * @param packageName
+	 *            The package required
+	 * @param range
+	 *            The package version range required
+	 * @param strategyx
+	 *            The package-version disambiguation strategy
+	 * @param attrs
+	 *            Other attributes specified by the search.
+	 * @return
+	 * @throws Exception
+	 */
+	public Container getPackage(String packageName, String range, Strategy strategyx, Map<String, String> attrs, ResolverMode mode) throws Exception {
+		if ("snapshot".equals(range))
+			return new Container(this, "", range, Container.TYPE.ERROR, null, "snapshot not supported for package lookups", null);
+		
+		if (attrs == null)
+			attrs = new HashMap<String, String>(2);
+		attrs.put("package", packageName);
+		attrs.put("mode", mode.name());
+		
+		Strategy useStrategy = findStrategy(attrs, strategyx, range);
+		
+		List<RepositoryPlugin> plugins = getPlugins(RepositoryPlugin.class);
+		for (RepositoryPlugin plugin : plugins) {
+			try {
+				File result = plugin.get(null, range, useStrategy, attrs);
+				if (result != null) {
+					if (result.getName().endsWith("lib"))
+						return new Container(this, result.getName(), range, Container.TYPE.LIBRARY, result, null, attrs);
+					else
+						return new Container(this, result.getName(), range, Container.TYPE.REPO, result, null, attrs);
+				}
+			} catch (Exception e) {
+				// Ignore... lots of repos will fail here
+			}
+		}
+		
+		return new Container(this, "X", range, Container.TYPE.ERROR, null, "package " + packageName + ";version=" + range + " Not found in " + plugins, null);
+	}
+
+	private Strategy findStrategy(Map<String, String> attrs, Strategy defaultStrategy, String versionRange) {
+		Strategy useStrategy = defaultStrategy;
+		String overrideStrategy = attrs.get("strategy");
+		if (overrideStrategy != null) {
+			if ("highest".equalsIgnoreCase(overrideStrategy))
+				useStrategy = Strategy.HIGHEST;
+			else if ("lowest".equalsIgnoreCase(overrideStrategy))
+				useStrategy = Strategy.LOWEST;
+			else if ("exact".equalsIgnoreCase(overrideStrategy))
+				useStrategy = Strategy.EXACT;
+		}
+		if ("latest".equals(versionRange))
+			useStrategy = Strategy.HIGHEST;
+		return useStrategy;
+	}
+
+	/**
+	 * The user selected pom in a path. This will place the pom as well as its
+	 * dependencies on the list
+	 * 
+	 * @param strategyx
+	 *            the strategy to use.
+	 * @param result
+	 *            The list of result containers
+	 * @param attrs
+	 *            The attributes
+	 * @throws Exception
+	 *             anything goes wrong
+	 */
+	public void doMavenPom(Strategy strategyx, List<Container> result, String action)
+			throws Exception {
+		File pomFile = getFile("pom.xml");
+		if (!pomFile.isFile())
+			error("Specified to use pom.xml but the project directory does not contain a pom.xml file");
+		else {
+			ProjectPom pom = getWorkspace().getMaven().createProjectModel(pomFile);
+			if (action == null)
+				action = "compile";
+			Pom.Scope act = Pom.Scope.valueOf(action);
+			Set<Pom> dependencies = pom.getDependencies(act);
+			for (Pom sub : dependencies) {
+				File artifact = sub.getArtifact();
+				Container container = new Container(artifact);
+				result.add(container);
+			}
+		}
+	}
+
+	public Collection<Project> getDependson() throws Exception {
+		prepare();
+		return dependson;
+	}
+
+	public Collection<Container> getBuildpath() throws Exception {
+		prepare();
+		return buildpath;
+	}
+
+	public Collection<Container> getTestpath() throws Exception {
+		prepare();
+		return testpath;
+	}
+
+	/**
+	 * Handle dependencies for paths that are calculated on demand.
+	 * 
+	 * @param testpath2
+	 * @param parseTestpath
+	 */
+	private void justInTime(Collection<Container> path, List<Container> entries) {
+		if (delayRunDependencies && path.isEmpty())
+			doPath(path, dependson, entries, null);
+	}
+
+	public Collection<Container> getRunpath() throws Exception {
+		prepare();
+		justInTime(runpath, parseRunpath());
+		return runpath;
+	}
+
+	public Collection<Container> getRunbundles() throws Exception {
+		prepare();
+		justInTime(runbundles, parseRunbundles());
+		return runbundles;
+	}
+	
+	public File getRunStorage() throws Exception {
+		prepare();
+		return runstorage;
+	}
+	
+	public boolean getRunBuilds() {
+		boolean result;
+		String runBuildsStr = getProperty(Constants.RUNBUILDS);
+		if (runBuildsStr == null)
+			result = !getPropertiesFile().getName().toLowerCase().endsWith(Constants.DEFAULT_BNDRUN_EXTENSION);
+		else
+			result = Boolean.parseBoolean(runBuildsStr);
+		return result;
+	}
+
+	public Collection<File> getSourcePath() throws Exception {
+		prepare();
+		return sourcepath;
+	}
+
+	public Collection<File> getAllsourcepath() throws Exception {
+		prepare();
+		return allsourcepath;
+	}
+
+	public Collection<Container> getBootclasspath() throws Exception {
+		prepare();
+		return bootclasspath;
+	}
+
+	public File getOutput() throws Exception {
+		prepare();
+		return output;
+	}
+
+	private void doEclipseClasspath() throws Exception {
+		EclipseClasspath eclipse = new EclipseClasspath(this, getWorkspace().getBase(), getBase());
+		eclipse.setRecurse(false);
+
+		// We get the file directories but in this case we need
+		// to tell ant that the project names
+		for (File dependent : eclipse.getDependents()) {
+			Project required = workspace.getProject(dependent.getName());
+			dependson.add(required);
+		}
+		for (File f : eclipse.getClasspath()) {
+			buildpath.add(new Container(f));
+		}
+		for (File f : eclipse.getBootclasspath()) {
+			bootclasspath.add(new Container(f));
+		}
+		sourcepath.addAll(eclipse.getSourcepath());
+		allsourcepath.addAll(eclipse.getAllSources());
+		output = eclipse.getOutput();
+	}
+
+	public String _p_dependson(String args[]) throws Exception {
+		return list(args, toFiles(getDependson()));
+	}
+
+	private Collection<?> toFiles(Collection<Project> projects) {
+		List<File> files = new ArrayList<File>();
+		for (Project p : projects) {
+			files.add(p.getBase());
+		}
+		return files;
+	}
+
+	public String _p_buildpath(String args[]) throws Exception {
+		return list(args, getBuildpath());
+	}
+
+	public String _p_testpath(String args[]) throws Exception {
+		return list(args, getRunpath());
+	}
+
+	public String _p_sourcepath(String args[]) throws Exception {
+		return list(args, getSourcePath());
+	}
+
+	public String _p_allsourcepath(String args[]) throws Exception {
+		return list(args, getAllsourcepath());
+	}
+
+	public String _p_bootclasspath(String args[]) throws Exception {
+		return list(args, getBootclasspath());
+	}
+
+	public String _p_output(String args[]) throws Exception {
+		if (args.length != 1)
+			throw new IllegalArgumentException("${output} should not have arguments");
+		return getOutput().getAbsolutePath();
+	}
+
+	private String list(String[] args, Collection<?> list) {
+		if (args.length > 3)
+			throw new IllegalArgumentException("${" + args[0]
+					+ "[;<separator>]} can only take a separator as argument, has "
+					+ Arrays.toString(args));
+
+		String separator = ",";
+
+		if (args.length == 2) {
+			separator = args[1];
+		}
+
+		return join(list, separator);
+	}
+
+	protected Object[] getMacroDomains() {
+		return new Object[] { workspace };
+	}
+
+	public File release(Jar jar) throws Exception {
+		String name = getProperty(Constants.RELEASEREPO);
+		return release(name, jar);
+	}
+
+	/**
+	 * Release
+	 * 
+	 * @param name
+	 *            The repository name
+	 * @param jar
+	 * @return
+	 * @throws Exception
+	 */
+	public File release(String name, Jar jar) throws Exception {
+		List<RepositoryPlugin> plugins = getPlugins(RepositoryPlugin.class);
+		RepositoryPlugin rp = null;
+		for (RepositoryPlugin plugin : plugins) {
+			if (!plugin.canWrite()) {
+				continue;
+			}
+			if (name == null) {
+				rp = plugin;
+				break;
+			} else if (name.equals(plugin.getName())) {
+				rp = plugin;
+				break;
+			}
+		}
+
+		if (rp != null) {
+			try {
+				return rp.put(jar);
+			} catch (Exception e) {
+				error("Deploying " + jar.getName() + " on " + rp.getName(), e);
+			} finally {
+				jar.close();
+			}
+		}
+		return null;
+
+	}
+
+	public void release(boolean test) throws Exception {
+		String name = getProperty(Constants.RELEASEREPO);
+		release(name, test);
+	}
+
+	/**
+	 * Release
+	 * 
+	 * @param name
+	 *            The respository name
+	 * @param test
+	 *            Run testcases
+	 * @throws Exception
+	 */
+	public void release(String name, boolean test) throws Exception {
+		File[] jars = build(test);
+		// If build fails jars will be null
+		if (jars == null) {
+			return;
+		}
+		for (File jar : jars) {
+			Jar j = new Jar(jar);
+			release(name, j);
+			j.close();
+		}
+
+	}
+
+	/**
+	 * Get a bundle from one of the plugin repositories.
+	 * 
+	 * @param bsn
+	 *            The bundle symbolic name
+	 * @param range
+	 *            The version range
+	 * @param lowest
+	 *            set to LOWEST or HIGHEST
+	 * @return the file object that points to the bundle or null if not found
+	 * @throws Exception
+	 *             when something goes wrong
+	 */
+	public Container getBundle(String bsn, String range, Strategy strategyx,
+			Map<String, String> attrs) throws Exception {
+
+		if ("snapshot".equals(range)) {
+			return getBundleFromProject(bsn, attrs);
+		}
+
+		if ("latest".equals(range)) {
+			Container c = getBundleFromProject(bsn, attrs);
+			if (c != null)
+				return c;
+		}
+
+		List<RepositoryPlugin> plugins = getPlugins(RepositoryPlugin.class);
+		;
+
+		Strategy useStrategy = strategyx;
+		if (attrs != null) {
+			String overrideStrategy = attrs.get("strategy");
+
+			if (overrideStrategy != null) {
+				if ("highest".equalsIgnoreCase(overrideStrategy))
+					useStrategy = Strategy.HIGHEST;
+				else if ("lowest".equalsIgnoreCase(overrideStrategy))
+					useStrategy = Strategy.LOWEST;
+				else if ("exact".equalsIgnoreCase(overrideStrategy))
+					useStrategy = Strategy.EXACT;
+			}
+		}
+
+		// If someone really wants the latest, lets give it to them.
+		// regardless of they asked for a lowest strategy
+		if (range != null && range.equals("latest"))
+			useStrategy = Strategy.HIGHEST;
+
+		// if ( bsn.indexOf('+')>0) {
+		// return getMavenContainer(bsn,range,useStrategy,attrs);
+		// }
+
+		// Maybe we want an exact match this time.
+		// In that case we limit the range to be exactly
+		// the version specified. We ignore it when a range
+		// is used instead of a version
+
+		for (RepositoryPlugin plugin : plugins) {
+			File result = plugin.get(bsn, range, useStrategy, attrs);
+			if (result != null) {
+				if (result.getName().endsWith("lib"))
+					return new Container(this, bsn, range, Container.TYPE.LIBRARY, result, null,
+							attrs);
+				else
+					return new Container(this, bsn, range, Container.TYPE.REPO, result, null, attrs);
+			}
+		}
+
+		return new Container(this, bsn, range, Container.TYPE.ERROR, null, bsn + ";version="
+				+ range + " Not found in " + plugins, null);
+	}
+
+	/**
+	 * Look for the bundle in the workspace. The premise is that the bsn must
+	 * start with the project name.
+	 * 
+	 * @param bsn
+	 *            The bsn
+	 * @param attrs
+	 *            Any attributes
+	 * @return
+	 * @throws Exception
+	 */
+	private Container getBundleFromProject(String bsn, Map<String, String> attrs) throws Exception {
+		String pname = bsn;
+		while (true) {
+			Project p = getWorkspace().getProject(pname);
+			if (p != null && p.isValid()) {
+				Container c = p.getDeliverable(bsn, attrs);
+				return c;
+			}
+
+			int n = pname.lastIndexOf('.');
+			if (n <= 0)
+				return null;
+			pname = pname.substring(0, n);
+		}
+	}
+
+	/**
+	 * Deploy the file (which must be a bundle) into the repository.
+	 * 
+	 * @param name
+	 *            The repository name
+	 * @param file
+	 *            bundle
+	 */
+	public void deploy(String name, File file) throws Exception {
+		List<RepositoryPlugin> plugins = getPlugins(RepositoryPlugin.class);
+		;
+		RepositoryPlugin rp = null;
+		for (RepositoryPlugin plugin : plugins) {
+			if (!plugin.canWrite()) {
+				continue;
+			}
+			if (name == null) {
+				rp = plugin;
+				break;
+			} else if (name.equals(plugin.getName())) {
+				rp = plugin;
+				break;
+			}
+		}
+
+		if (rp != null) {
+			Jar jar = new Jar(file);
+			try {
+				rp.put(jar);
+				return;
+			} catch (Exception e) {
+				error("Deploying " + file + " on " + rp.getName(), e);
+			} finally {
+				jar.close();
+			}
+			return;
+		}
+		trace("No repo found " + file);
+		throw new IllegalArgumentException("No repository found for " + file);
+	}
+
+	/**
+	 * Deploy the file (which must be a bundle) into the repository.
+	 * 
+	 * @param file
+	 *            bundle
+	 */
+	public void deploy(File file) throws Exception {
+		String name = getProperty(Constants.DEPLOYREPO);
+		deploy(name, file);
+	}
+
+	/**
+	 * Deploy the current project to a repository
+	 * 
+	 * @throws Exception
+	 */
+	public void deploy() throws Exception {
+		Map<String, Map<String, String>> deploy = parseHeader(getProperty(DEPLOY));
+		if (deploy.isEmpty()) {
+			warning("Deploying but %s is not set to any repo", DEPLOY);
+			return;
+		}
+		File[] outputs = getBuildFiles();
+		for (File output : outputs) {
+			Jar jar = new Jar(output);
+			try {
+				for (Deploy d : getPlugins(Deploy.class)) {
+					trace("Deploying %s to: %s", jar, d);
+					try {
+						if (d.deploy(this, jar))
+							trace("deployed %s successfully to %s", output, d);
+					} catch (Exception e) {
+						error("Error while deploying %s, %s", this, e);
+						e.printStackTrace();
+					}
+				}
+			} finally {
+				jar.close();
+			}
+		}
+	}
+
+	/**
+	 * Macro access to the repository
+	 * 
+	 * ${repo;<bsn>[;<version>[;<low|high>]]}
+	 */
+
+	public String _repo(String args[]) throws Exception {
+		if (args.length < 2)
+			throw new IllegalArgumentException(
+					"Too few arguments for repo, syntax=: ${repo ';'<bsn> [ ; <version> [; ('HIGHEST'|'LOWEST')]}");
+
+		String bsns = args[1];
+		String version = null;
+		Strategy strategy = Strategy.HIGHEST;
+
+		if (args.length > 2) {
+			version = args[2];
+			if (args.length == 4) {
+				if (args[3].equalsIgnoreCase("HIGHEST"))
+					strategy = Strategy.HIGHEST;
+				else if (args[3].equalsIgnoreCase("LOWEST"))
+					strategy = Strategy.LOWEST;
+				else if (args[3].equalsIgnoreCase("EXACT"))
+					strategy = Strategy.EXACT;
+				else
+					error("${repo;<bsn>;<version>;<'highest'|'lowest'|'exact'>} macro requires a strategy of 'highest' or 'lowest', and is "
+							+ args[3]);
+			}
+		}
+
+		Collection<String> parts = split(bsns);
+		List<String> paths = new ArrayList<String>();
+
+		for (String bsn : parts) {
+			Container container = getBundle(bsn, version, strategy, null);
+			add(paths, container);
+		}
+		return join(paths);
+	}
+
+	private void add(List<String> paths, Container container) throws Exception {
+		if (container.getType() == Container.TYPE.LIBRARY) {
+			List<Container> members = container.getMembers();
+			for (Container sub : members) {
+				add(paths, sub);
+			}
+		} else {
+			if (container.getError() == null)
+				paths.add(container.getFile().getAbsolutePath());
+			else {
+				paths.add("<<${repo} = " + container.getBundleSymbolicName() + "-"
+						+ container.getVersion() + " : " + container.getError() + ">>");
+
+				if (isPedantic()) {
+					warning("Could not expand repo path request: %s ", container);
+				}
+			}
+
+		}
+	}
+
+	public File getTarget() throws Exception {
+		prepare();
+		return target;
+	}
+
+	/**
+	 * This is the external method that will pre-build any dependencies if it is
+	 * out of date.
+	 * 
+	 * @param underTest
+	 * @return
+	 * @throws Exception
+	 */
+	public File[] build(boolean underTest) throws Exception {
+		if (getProperty(NOBUNDLES) != null)
+			return null;
+
+		if (getProperty("-nope") != null) {
+			warning("Please replace -nope with %s", NOBUNDLES);
+			return null;
+		}
+
+
+		if (isStale()) {
+			trace("Building " + this);
+			files = buildLocal(underTest);
+		}
+
+		return files;
+	}
+	
+	/**
+	 * Return the files
+	 */
+	
+	public File[] getFiles() {
+		return files;
+	}
+	/**
+	 * Check if this project needs building
+	 */
+	public boolean isStale() throws Exception {
+		if ( files == null)
+			return true;
+		
+		long localTime = getBuildTime();
+		if ( lastModified()>localTime)
+			return true;
+		
+		for (Project dependency : getDependson()) {
+			if (dependency.isStale())
+				return true;
+	
+			if ( dependency.getBuildTime() > localTime)
+				return true;
+			
+			if ( dependency.lastModified() > localTime)
+				return true;
+			
+		}
+		return false;
+	}
+
+	/**
+	 * This method must only be called when it is sure that the project has been
+	 * build before in the same session.
+	 * 
+	 * It is a bit yucky, but ant creates different class spaces which makes it
+	 * hard to detect we already build it.
+	 * 
+	 * @return
+	 */
+
+	public File[] getBuildFiles() throws Exception {
+		return getBuildFiles(true);
+	}
+
+	public File[] getBuildFiles(boolean buildIfAbsent) throws Exception {
+		File f = new File(getTarget(), BUILDFILES);
+		if (f.isFile()) {
+			FileReader fin = new FileReader(f);
+			BufferedReader rdr = new BufferedReader(fin);
+			try {
+				List<File> files = newList();
+				for (String s = rdr.readLine(); s != null; s = rdr.readLine()) {
+					s = s.trim();
+					File ff = new File(s);
+					if (!ff.isFile()) {
+						error("buildfile lists file but the file does not exist %s", ff);
+					} else
+						files.add(ff);
+				}
+				return files.toArray(new File[files.size()]);
+			} finally {
+				fin.close();
+			}
+		}
+		if (buildIfAbsent)
+			return buildLocal(false);
+		else
+			return null;
+	}
+
+	/**
+	 * Build without doing any dependency checking. Make sure any dependent
+	 * projects are built first.
+	 * 
+	 * @param underTest
+	 * @return
+	 * @throws Exception
+	 */
+	public File[] buildLocal(boolean underTest) throws Exception {
+		if (getProperty(NOBUNDLES) != null)
+			return null;
+
+		long buildtime = System.currentTimeMillis();
+		File bfs = new File(getTarget(), BUILDFILES);
+		bfs.delete();
+
+		files = null;
+		ProjectBuilder builder = getBuilder(null);
+		if (underTest)
+			builder.setProperty(Constants.UNDERTEST, "true");
+		Jar jars[] = builder.builds();
+		File[] files = new File[jars.length];
+
+		for (int i = 0; i < jars.length; i++) {
+			Jar jar = jars[i];
+			files[i] = saveBuild(jar);
+		}
+		getInfo(builder);
+		builder.close();
+		if (isOk()) {
+			this.files = files;
+
+			// Write out the filenames in the buildfiles file
+			// so we can get them later evenin another process
+			FileWriter fw = new FileWriter(bfs);
+			try {
+				for (File f : files) {
+					fw.append(f.getAbsolutePath());
+					fw.append("\n");
+				}
+			} finally {
+				fw.close();
+			}
+			getWorkspace().changedFile(bfs);
+			this.buildtime = buildtime;
+			return files;
+		} else
+			return null;
+	}
+
+	public File saveBuild(Jar jar) throws Exception {
+		try {
+			String bsn = jar.getName();
+			File f = getOutputFile(bsn);
+			String msg = "";
+			if (!f.exists() || f.lastModified() < jar.lastModified()) {
+				reportNewer(f.lastModified(), jar);
+				f.delete();
+				if (!f.getParentFile().isDirectory())
+					f.getParentFile().mkdirs();
+				jar.write(f);
+
+				getWorkspace().changedFile(f);
+			} else {
+				msg = "(not modified since " + new Date(f.lastModified()) + ")";
+			}
+			trace(jar.getName() + " (" + f.getName() + ") " + jar.getResources().size() + " " + msg);
+			return f;
+		} finally {
+			jar.close();
+		}
+	}
+
+	private File getOutputFile(String bsn) throws Exception {
+		return new File(getTarget(), bsn + ".jar");
+	}
+
+	private void reportNewer(long lastModified, Jar jar) {
+		if (isTrue(getProperty(Constants.REPORTNEWER))) {
+			StringBuilder sb = new StringBuilder();
+			String del = "Newer than " + new Date(lastModified);
+			for (Map.Entry<String, Resource> entry : jar.getResources().entrySet()) {
+				if (entry.getValue().lastModified() > lastModified) {
+					sb.append(del);
+					del = ", \n     ";
+					sb.append(entry.getKey());
+				}
+			}
+			if (sb.length() > 0)
+				warning(sb.toString());
+		}
+	}
+
+	/**
+	 * Refresh if we are based on stale data. This also implies our workspace.
+	 */
+	public boolean refresh() {
+		boolean changed = false;
+		if (isCnf()) {
+			changed = workspace.refresh();
+		}
+		return super.refresh() || changed;
+	}
+
+	public boolean isCnf() {
+		return getBase().getName().equals(Workspace.CNFDIR);
+	}
+
+	public void propertiesChanged() {
+		super.propertiesChanged();
+		preparedPaths = false;
+		files = null;
+
+	}
+
+	public String getName() {
+		return getBase().getName();
+	}
+
+	public Map<String, Action> getActions() {
+		Map<String, Action> all = newMap();
+		Map<String, Action> actions = newMap();
+		fillActions(all);
+		getWorkspace().fillActions(all);
+
+		for (Map.Entry<String, Action> action : all.entrySet()) {
+			String key = getReplacer().process(action.getKey());
+			if (key != null && key.trim().length() != 0)
+				actions.put(key, action.getValue());
+		}
+		return actions;
+	}
+
+	public void fillActions(Map<String, Action> all) {
+		List<NamedAction> plugins = getPlugins(NamedAction.class);
+		for (NamedAction a : plugins)
+			all.put(a.getName(), a);
+
+		Map<String, Map<String, String>> actions = parseHeader(getProperty("-actions",
+				DEFAULT_ACTIONS));
+		for (Map.Entry<String, Map<String, String>> entry : actions.entrySet()) {
+			String key = Processor.removeDuplicateMarker(entry.getKey());
+			Action action;
+
+			if (entry.getValue().get("script") != null) {
+				// TODO check for the type
+				action = new ScriptAction(entry.getValue().get("type"), entry.getValue().get(
+						"script"));
+			} else {
+				action = new ReflectAction(key);
+			}
+			String label = entry.getValue().get("label");
+			all.put(label.toLowerCase(), action);
+		}
+	}
+
+	public void release() throws Exception {
+		release(false);
+	}
+
+	/**
+	 * Release.
+	 * 
+	 * @param name
+	 *            The repository name
+	 * @throws Exception
+	 */
+	public void release(String name) throws Exception {
+		release(name, false);
+	}
+
+	public void clean() throws Exception {
+		File target = getTarget();
+		if (target.isDirectory() && target.getParentFile() != null) {
+			IO.delete(target);
+		}
+		if (getOutput().isDirectory())
+			IO.delete(getOutput());
+		getOutput().mkdirs();
+	}
+
+	public File[] build() throws Exception {
+		return build(false);
+	}
+
+	public void run() throws Exception {
+		ProjectLauncher pl = getProjectLauncher();
+		pl.setTrace(isTrace());
+		pl.launch();
+	}
+
+	public void test() throws Exception {
+		clear();
+		ProjectTester tester = getProjectTester();
+		tester.setContinuous(isTrue( getProperty(Constants.TESTCONTINUOUS)));
+		tester.prepare();
+
+		if (!isOk()) {
+			return;
+		}
+		int errors = tester.test();
+		if (errors == 0) {
+			System.out.println("No Errors");
+		} else {
+			if (errors > 0) {
+				System.out.println(errors + " Error(s)");
+
+			} else
+				System.out.println("Error " + errors);
+		}
+	}
+
+	/**
+	 * This methods attempts to turn any jar into a valid jar. If this is a
+	 * bundle with manifest, a manifest is added based on defaults. If it is a
+	 * bundle, but not r4, we try to add the r4 headers.
+	 * 
+	 * @param descriptor
+	 * @param in
+	 * @return
+	 * @throws Exception
+	 */
+	public Jar getValidJar(File f) throws Exception {
+		Jar jar = new Jar(f);
+		return getValidJar(jar, f.getAbsolutePath());
+	}
+
+	public Jar getValidJar(URL url) throws Exception {
+		InputStream in = url.openStream();
+		try {
+			Jar jar = new Jar(url.getFile().replace('/', '.'), in, System.currentTimeMillis());
+			return getValidJar(jar, url.toString());
+		} finally {
+			in.close();
+		}
+	}
+
+	public Jar getValidJar(Jar jar, String id) throws Exception {
+		Manifest manifest = jar.getManifest();
+		if (manifest == null) {
+			trace("Wrapping with all defaults");
+			Builder b = new Builder(this);
+			b.addClasspath(jar);
+			b.setProperty("Bnd-Message", "Wrapped from " + id + "because lacked manifest");
+			b.setProperty(Constants.EXPORT_PACKAGE, "*");
+			b.setProperty(Constants.IMPORT_PACKAGE, "*;resolution:=optional");
+			jar = b.build();
+		} else if (manifest.getMainAttributes().getValue(Constants.BUNDLE_MANIFESTVERSION) == null) {
+			trace("Not a release 4 bundle, wrapping with manifest as source");
+			Builder b = new Builder(this);
+			b.addClasspath(jar);
+			b.setProperty(Constants.PRIVATE_PACKAGE, "*");
+			b.mergeManifest(manifest);
+			String imprts = manifest.getMainAttributes().getValue(Constants.IMPORT_PACKAGE);
+			if (imprts == null)
+				imprts = "";
+			else
+				imprts += ",";
+			imprts += "*;resolution=optional";
+
+			b.setProperty(Constants.IMPORT_PACKAGE, imprts);
+			b.setProperty("Bnd-Message", "Wrapped from " + id + "because had incomplete manifest");
+			jar = b.build();
+		}
+		return jar;
+	}
+
+	public String _project(String args[]) {
+		return getBase().getAbsolutePath();
+	}
+
+	public void bump(String mask) throws IOException {
+		Sed sed = new Sed(getReplacer(), getPropertiesFile());
+		sed.replace("(Bundle-Version\\s*(:|=)\\s*)(([0-9]+(\\.[0-9]+(\\.[0-9]+)?)?))",
+				"$1${version;" + mask + ";$3}");
+		sed.doIt();
+		refresh();
+	}
+
+	public void bump() throws IOException {
+		bump(getProperty(BUMPPOLICY, "=+0"));
+	}
+
+	public void action(String command) throws Throwable {
+		Map<String, Action> actions = getActions();
+
+		Action a = actions.get(command);
+		if (a == null)
+			a = new ReflectAction(command);
+
+		before(this, command);
+		try {
+			a.execute(this, command);
+		} catch (Throwable t) {
+			after(this, command, t);
+			throw t;
+		}
+	}
+
+	/**
+	 * Run all before command plugins
+	 * 
+	 */
+	void before(Project p, String a) {
+		List<CommandPlugin> testPlugins = getPlugins(CommandPlugin.class);
+		for (CommandPlugin testPlugin : testPlugins) {
+			testPlugin.before(this, a);
+		}
+	}
+
+	/**
+	 * Run all after command plugins
+	 */
+	void after(Project p, String a, Throwable t) {
+		List<CommandPlugin> testPlugins = getPlugins(CommandPlugin.class);
+		for (int i = testPlugins.size() - 1; i >= 0; i--) {
+			testPlugins.get(i).after(this, a, t);
+		}
+	}
+
+	public String _findfile(String args[]) {
+		File f = getFile(args[1]);
+		List<String> files = new ArrayList<String>();
+		tree(files, f, "", Instruction.getPattern(args[2]));
+		return join(files);
+	}
+
+	void tree(List<String> list, File current, String path, Instruction instr) {
+		if (path.length() > 0)
+			path = path + "/";
+
+		String subs[] = current.list();
+		if (subs != null) {
+			for (String sub : subs) {
+				File f = new File(current, sub);
+				if (f.isFile()) {
+					if (instr.matches(sub) && !instr.isNegated())
+						list.add(path + sub);
+				} else
+					tree(list, f, path + sub, instr);
+			}
+		}
+	}
+
+	public void refreshAll() {
+		workspace.refresh();
+		refresh();
+	}
+
+	@SuppressWarnings("unchecked") public void script(String type, String script) throws Exception {
+		// TODO check tyiping
+		List<Scripter> scripters = getPlugins(Scripter.class);
+		if (scripters.isEmpty()) {
+			error("Can not execute script because there are no scripters registered: %s", script);
+			return;
+		}
+		@SuppressWarnings("rawtypes")
+		Map x = (Map) getProperties();
+		scripters.get(0).eval((Map<String, Object>) x, new StringReader(script));
+	}
+
+	public String _repos(String args[]) throws Exception {
+		List<RepositoryPlugin> repos = getPlugins(RepositoryPlugin.class);
+		List<String> names = new ArrayList<String>();
+		for (RepositoryPlugin rp : repos)
+			names.add(rp.getName());
+		return join(names, ", ");
+	}
+
+	public String _help(String args[]) throws Exception {
+		if (args.length == 1)
+			return "Specify the option or header you want information for";
+
+		Syntax syntax = Syntax.HELP.get(args[1]);
+		if (syntax == null)
+			return "No help for " + args[1];
+
+		String what = null;
+		if (args.length > 2)
+			what = args[2];
+
+		if (what == null || what.equals("lead"))
+			return syntax.getLead();
+		if (what == null || what.equals("example"))
+			return syntax.getExample();
+		if (what == null || what.equals("pattern"))
+			return syntax.getPattern();
+		if (what == null || what.equals("values"))
+			return syntax.getValues();
+
+		return "Invalid type specified for help: lead, example, pattern, values";
+	}
+
+	/**
+	 * Returns containers for the deliverables of this project. The deliverables
+	 * is the project builder for this project if no -sub is specified.
+	 * Otherwise it contains all the sub bnd files.
+	 * 
+	 * @return A collection of containers
+	 * 
+	 * @throws Exception
+	 */
+	public Collection<Container> getDeliverables() throws Exception {
+		List<Container> result = new ArrayList<Container>();
+		Collection<? extends Builder> builders = getSubBuilders();
+
+		for (Builder builder : builders) {
+			Container c = new Container(this, builder.getBsn(), builder.getVersion(),
+					Container.TYPE.PROJECT, getOutputFile(builder.getBsn()), null, null);
+			result.add(c);
+		}
+		return result;
+
+	}
+
+	/**
+	 * Return the builder associated with the give bnd file or null. The bnd.bnd
+	 * file can contain -sub option. This option allows specifying files in the
+	 * same directory that should drive the generation of multiple deliverables.
+	 * This method figures out if the bndFile is actually one of the bnd files
+	 * of a deliverable.
+	 * 
+	 * @param bndFile
+	 *            A file pointing to a bnd file.
+	 * @return null or the builder for a sub file.
+	 * @throws Exception
+	 */
+	public Builder getSubBuilder(File bndFile) throws Exception {
+		bndFile = bndFile.getCanonicalFile();
+
+		// Verify that we are inside the project.
+		File base = getBase().getCanonicalFile();
+		if (!bndFile.getAbsolutePath().startsWith(base.getAbsolutePath()))
+			return null;
+
+		Collection<? extends Builder> builders = getSubBuilders();
+		for (Builder sub : builders) {
+			File propertiesFile = sub.getPropertiesFile();
+			if (propertiesFile != null) {
+				if (propertiesFile.getCanonicalFile().equals(bndFile)) {
+					// Found it!
+					return sub;
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Answer the container associated with a given bsn.
+	 * 
+	 * @param bndFile
+	 *            A file pointing to a bnd file.
+	 * @return null or the builder for a sub file.
+	 * @throws Exception
+	 */
+	public Container getDeliverable(String bsn, Map<String, String> attrs) throws Exception {
+		Collection<? extends Builder> builders = getSubBuilders();
+		for (Builder sub : builders) {
+			if (sub.getBsn().equals(bsn))
+				return new Container(this, getOutputFile(bsn));
+		}
+		return null;
+	}
+
+	/**
+	 * Get a list of the sub builders. A bnd.bnd file can contain the -sub
+	 * option. This will generate multiple deliverables. This method returns the
+	 * builders for each sub file. If no -sub option is present, the list will
+	 * contain a builder for the bnd.bnd file.
+	 * 
+	 * @return A list of builders.
+	 * @throws Exception
+	 */
+	public Collection<? extends Builder> getSubBuilders() throws Exception {
+		return getBuilder(null).getSubBuilders();
+	}
+
+	/**
+	 * Calculate the classpath. We include our own runtime.jar which includes
+	 * the test framework and we include the first of the test frameworks
+	 * specified.
+	 * 
+	 * @throws Exception
+	 */
+	Collection<File> toFile(Collection<Container> containers) throws Exception {
+		ArrayList<File> files = new ArrayList<File>();
+		for (Container container : containers) {
+			container.contributeFiles(files, this);
+		}
+		return files;
+	}
+
+	public Collection<String> getRunVM() {
+		Map<String, Map<String, String>> hdr = parseHeader(getProperty(RUNVM));
+		return hdr.keySet();
+	}
+
+	public Map<String, String> getRunProperties() {
+		return OSGiHeader.parseProperties(getProperty(RUNPROPERTIES));
+	}
+
+	/**
+	 * Get a launcher.
+	 * 
+	 * @return
+	 * @throws Exception
+	 */
+	public ProjectLauncher getProjectLauncher() throws Exception {
+		return getHandler(ProjectLauncher.class, getRunpath(), LAUNCHER_PLUGIN,
+				"biz.aQute.launcher");
+	}
+
+	public ProjectTester getProjectTester() throws Exception {
+		return getHandler(ProjectTester.class, getTestpath(), TESTER_PLUGIN, "biz.aQute.junit");
+	}
+
+	private <T> T getHandler(Class<T> target, Collection<Container> containers, String header,
+			String defaultHandler) throws Exception {
+		Class<? extends T> handlerClass = target;
+
+		// Make sure we find at least one handler, but hope to find an earlier
+		// one
+		List<Container> withDefault = Create.list();
+		withDefault.addAll(containers);
+		withDefault.addAll(getBundles(Strategy.HIGHEST, defaultHandler, null));
+
+		for (Container c : withDefault) {
+			Manifest manifest = c.getManifest();
+
+			if (manifest != null) {
+				String launcher = manifest.getMainAttributes().getValue(header);
+				if (launcher != null) {
+					Class<?> clz = getClass(launcher, c.getFile());
+					if (clz != null) {
+						if (!target.isAssignableFrom(clz)) {
+							error("Found a %s class in %s but it is not compatible with: %s", clz,
+									c, target);
+						} else {
+							handlerClass = clz.asSubclass(target);
+							Constructor<? extends T> constructor = handlerClass
+									.getConstructor(Project.class);
+							return constructor.newInstance(this);
+						}
+					}
+				}
+			}
+		}
+		throw new IllegalArgumentException("Default handler for " + header + " not found in "
+				+ defaultHandler);
+	}
+
+	public synchronized boolean lock(String reason) throws InterruptedException {
+		if (!lock.tryLock(5, TimeUnit.SECONDS)) {
+			error("Could not acquire lock for %s, was locked by %s for %s", reason, lockingThread,
+					lockingReason);
+			System.out.printf("Could not acquire lock for %s, was locked by %s for %s\n", reason,
+					lockingThread, lockingReason);
+			System.out.flush();
+			return false;
+		}
+		this.lockingReason = reason;
+		this.lockingThread = Thread.currentThread();
+		return true;
+	}
+
+	public void unlock() {
+		lockingReason = null;
+		lock.unlock();
+	}
+
+	public long getBuildTime() throws Exception {
+		if (buildtime == 0) {
+
+			files = getBuildFiles();
+			if (files != null && files.length >= 1)
+				buildtime = files[0].lastModified();
+		}
+		return buildtime;
+	}
+
+	/**
+	 * Make this project delay the calculation of the run dependencies.
+	 * 
+	 * The run dependencies calculation can be done in prepare or until the
+	 * dependencies are actually needed.
+	 */
+	public void setDelayRunDependencies(boolean x) {
+		delayRunDependencies = x;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ProjectBuilder.java b/bundleplugin/src/main/java/aQute/bnd/build/ProjectBuilder.java
new file mode 100644
index 0000000..d9cccda
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ProjectBuilder.java
@@ -0,0 +1,73 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+
+public class ProjectBuilder extends Builder {
+    Project project;
+    boolean initialized;
+
+    public ProjectBuilder(Project project) {
+        super(project);
+        this.project = project;
+    }
+
+    public ProjectBuilder(ProjectBuilder builder) {
+        super(builder);
+        this.project = builder.project;
+    }
+
+    @Override
+    public long lastModified() {
+        return Math.max(project.lastModified(), super.lastModified());
+    }
+
+    /**
+     * We put our project and our workspace on the macro path.
+     */
+    protected Object[] getMacroDomains() {
+        return new Object[] { project, project.getWorkspace() };
+    }
+
+    public Builder getSubBuilder() throws Exception {
+        return project.getBuilder(this);
+    }
+
+    public Project getProject() {
+        return project;
+    }
+
+    public void init() {
+        try {
+            if (!initialized) {
+                initialized = true;
+                for (Container file : project.getBuildpath()) {
+                    addClasspath(file.getFile());
+                }
+
+                for (Container file : project.getBootclasspath()) {
+                    addClasspath(file.getFile());
+                }
+
+                for (File file : project.getAllsourcepath()) {
+                    addSourcepath(file);
+                }
+
+            }
+        } catch (Exception e) {
+            error("init project builder fails", e);
+        }
+    }
+
+    public List<Jar> getClasspath() {
+        init();
+        return super.getClasspath();
+    }
+
+    @Override
+    protected void changedFile(File f) {
+        project.getWorkspace().changedFile(f);
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ProjectLauncher.java b/bundleplugin/src/main/java/aQute/bnd/build/ProjectLauncher.java
new file mode 100644
index 0000000..2b78943
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ProjectLauncher.java
@@ -0,0 +1,327 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.jar.*;
+
+import aQute.bnd.service.RepositoryPlugin.Strategy;
+import aQute.lib.osgi.*;
+import aQute.libg.command.*;
+import aQute.libg.generics.*;
+
+/**
+ * A Project Launcher is a base class to be extended by launchers. Launchers are
+ * JARs that launch a framework and install a number of bundles and then run the
+ * framework. A launcher jar must specify a Launcher-Class manifest header. This
+ * class is instantiated and cast to a LauncherPlugin. This plug in is then
+ * asked to provide a ProjectLauncher. This project launcher is then used by the
+ * project to run the code. Launchers must extend this class.
+ * 
+ */
+public abstract class ProjectLauncher {
+	private final Project						project;
+	private long								timeout				= 0;
+	private final Collection<String>			classpath			= new ArrayList<String>();
+	private List<String>						runbundles			= Create.list();
+	private final List<String>					runvm				= new ArrayList<String>();
+	private Map<String, String>					runproperties;
+	private Command								java;
+	private Map<String, Map<String, String>>	runsystempackages;
+	private final List<String>					activators			= Create.list();
+	private File								storageDir;
+
+	private boolean								trace;
+	private boolean								keep;
+	private int									framework;
+
+	public final static int						SERVICES			= 10111;
+	public final static int						NONE				= 20123;
+
+	// MUST BE ALIGNED WITH LAUNCHER
+	public final static int						OK					= 0;
+	public final static int						WARNING				= -1;
+	public final static int						ERROR				= -2;
+	public final static int						TIMEDOUT			= -3;
+	public final static int						UPDATE_NEEDED		= -4;
+	public final static int						CANCELED			= -5;
+	public final static int						DUPLICATE_BUNDLE	= -6;
+	public final static int						RESOLVE_ERROR		= -7;
+	public final static int						ACTIVATOR_ERROR		= -8;
+	public final static int						CUSTOM_LAUNCHER		= -128;
+
+	public final static String					EMBEDDED_ACTIVATOR	= "Embedded-Activator";
+
+	public ProjectLauncher(Project project) throws Exception {
+		this.project = project;
+
+		updateFromProject();
+	}
+
+	/**
+	 * Collect all the aspect from the project and set the local fields from
+	 * them. Should be called
+	 * 
+	 * @throws Exception
+	 */
+	protected void updateFromProject() throws Exception {
+		// pkr: could not use this because this is killing the runtests.
+		// project.refresh();
+		runbundles.clear();
+		Collection<Container> run = project.getRunbundles();
+		
+		for (Container container : run) {
+			File file = container.getFile();
+			if (file != null && (file.isFile() || file.isDirectory()))
+				runbundles.add(file.getAbsolutePath());
+		}
+
+		if (project.getRunBuilds()) {
+			File[] builds = project.build();
+			if (builds != null)
+				for (File file : builds)
+					runbundles.add(file.getAbsolutePath());
+		}
+
+		Collection<Container> runpath = project.getRunpath();
+		runsystempackages = project.parseHeader(project.getProperty(Constants.RUNSYSTEMPACKAGES));
+		framework = getRunframework(project.getProperty(Constants.RUNFRAMEWORK));
+		trace = Processor.isTrue(project.getProperty(Constants.RUNTRACE));
+
+		timeout = Processor.getDuration(project.getProperty(Constants.RUNTIMEOUT), 0);
+		trace = Processor.isTrue(project.getProperty(Constants.RUNTRACE));
+
+		// For backward compatibility with bndtools launcher
+		List<Container> fws = project.getBundles(Strategy.HIGHEST, project.getProperty("-runfw"), "-runfw");
+		runpath.addAll(fws);
+
+		for (Container c : runpath) {
+			addClasspath(c);
+		}
+
+		runvm.addAll(project.getRunVM());
+		runproperties = project.getRunProperties();
+
+		storageDir = project.getRunStorage();
+		if (storageDir == null) {
+			storageDir = new File(project.getTarget(), "fw");
+		}
+	}
+
+	private int getRunframework(String property) {
+		if (Constants.RUNFRAMEWORK_NONE.equalsIgnoreCase(property))
+			return NONE;
+		else if (Constants.RUNFRAMEWORK_SERVICES.equalsIgnoreCase(property))
+			return SERVICES;
+
+		return SERVICES;
+	}
+
+	public void addClasspath(Container container) throws Exception {
+		if (container.getError() != null) {
+			project.error("Cannot launch because %s has reported %s", container.getProject(),
+					container.getError());
+		} else {
+			Collection<Container> members = container.getMembers();
+			for (Container m : members) {
+				String path = m.getFile().getAbsolutePath();
+				if (!classpath.contains(path)) {
+					classpath.add(path);
+
+					Manifest manifest = m.getManifest();
+					if (manifest != null) {
+						Map<String, Map<String, String>> exports = project.parseHeader(manifest
+								.getMainAttributes().getValue(Constants.EXPORT_PACKAGE));
+						for (Map.Entry<String, Map<String, String>> e : exports.entrySet()) {
+							if (!runsystempackages.containsKey(e.getKey()))
+								runsystempackages.put(e.getKey(), e.getValue());
+						}
+
+						// Allow activators on the runpath. They are called
+						// after
+						// the framework is completely initialized wit the
+						// system
+						// context.
+						String activator = manifest.getMainAttributes()
+								.getValue(EMBEDDED_ACTIVATOR);
+						if (activator != null)
+							activators.add(activator);
+					}
+				}
+			}
+		}
+	}
+
+	public void addRunBundle(String f) {
+		runbundles.add(f);
+	}
+
+	public Collection<String> getRunBundles() {
+		return runbundles;
+	}
+
+	public void addRunVM(String arg) {
+		runvm.add(arg);
+	}
+
+	public Collection<String> getRunpath() {
+		return classpath;
+	}
+
+	public Collection<String> getClasspath() {
+		return classpath;
+	}
+
+	public Collection<String> getRunVM() {
+		return runvm;
+	}
+
+	public Collection<String> getArguments() {
+		return Collections.emptySet();
+	}
+
+	public Map<String, String> getRunProperties() {
+		return runproperties;
+	}
+	
+	public File getStorageDir() {
+		return storageDir;
+	}
+
+	public abstract String getMainTypeName();
+
+	public abstract void update() throws Exception;
+
+	public int launch() throws Exception {
+		prepare();
+		java = new Command();
+		java.add(project.getProperty("java", "java"));
+		java.add("-cp");
+		java.add(Processor.join(getClasspath(), File.pathSeparator));
+		java.addAll(getRunVM());
+		java.add(getMainTypeName());
+		java.addAll(getArguments());
+		if (timeout != 0)
+			java.setTimeout(timeout + 1000, TimeUnit.MILLISECONDS);
+
+		int result = java.execute(System.in, System.out, System.err);
+		if (result == Integer.MIN_VALUE)
+			return TIMEDOUT;
+
+		reportResult(result);
+		return result;
+	}
+
+	protected void reportResult(int result) {
+		switch (result) {
+		case OK:
+			project.trace("Command terminated normal %s", java);
+			break;
+		case TIMEDOUT:
+			project.error("Launch timedout: %s", java);
+			break;
+
+		case ERROR:
+			project.error("Launch errored: %s", java);
+			break;
+
+		case WARNING:
+			project.warning("Launch had a warning %s", java);
+			break;
+		default:
+			project.warning("Unknown code %d from launcher: %s", result, java);
+			break;
+		}
+	}
+
+	public void setTimeout(long timeout, TimeUnit unit) {
+		this.timeout = unit.convert(timeout, TimeUnit.MILLISECONDS);
+	}
+
+	public long getTimeout() {
+		return this.timeout;
+	}
+
+	public void cancel() {
+		java.cancel();
+	}
+
+	public Map<String, Map<String, String>> getSystemPackages() {
+		return runsystempackages;
+	}
+
+	public void setKeep(boolean keep) {
+		this.keep = keep;
+	}
+
+	public boolean isKeep() {
+		return keep;
+	}
+
+	public void setTrace(boolean level) {
+		this.trace = level;
+	}
+
+	public boolean getTrace() {
+		return this.trace;
+	}
+
+	/**
+	 * Should be called when all the changes to the launchers are set. Will
+	 * calculate whatever is necessary for the launcher.
+	 * 
+	 * @throws Exception
+	 */
+	public abstract void prepare() throws Exception;
+
+	public Project getProject() {
+		return project;
+	}
+
+	public boolean addActivator(String e) {
+		return activators.add(e);
+	}
+
+	public Collection<String> getActivators() {
+		return Collections.unmodifiableCollection(activators);
+	}
+
+	/**
+	 * Either NONE or SERVICES to indicate how the remote end launches. NONE
+	 * means it should not use the classpath to run a framework. This likely
+	 * requires some dummy framework support. SERVICES means it should load the
+	 * framework from the claspath.
+	 * 
+	 * @return
+	 */
+	public int getRunFramework() {
+		return framework;
+	}
+
+	public void setRunFramework(int n) {
+		assert n == NONE || n == SERVICES;
+		this.framework = n;
+	}
+
+	/**
+	 * Add the specification for a set of bundles the runpath if it does not
+	 * already is included. This can be used by subclasses to ensure the proper
+	 * jars are on the classpath.
+	 * 
+	 * @param defaultSpec
+	 *            The default spec for default jars
+	 */
+	public void addDefault(String defaultSpec) throws Exception {
+		Collection<Container> deflts = project.getBundles(Strategy.HIGHEST, defaultSpec, null);
+		for (Container c : deflts)
+			addClasspath(c);
+	}
+
+	/**
+	 * Create a self executable.
+	 */
+
+	public Jar executable() throws Exception {
+		throw new UnsupportedOperationException();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ProjectTester.java b/bundleplugin/src/main/java/aQute/bnd/build/ProjectTester.java
new file mode 100644
index 0000000..5060d2f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ProjectTester.java
@@ -0,0 +1,75 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.util.*;
+
+public abstract class ProjectTester {
+	final Project				project;
+	final Collection<Container>	testbundles;
+	final ProjectLauncher		launcher;
+	final List<String>			tests		= new ArrayList<String>();
+	File						reportDir;
+	boolean						continuous	= true;
+	
+	public ProjectTester(Project project) throws Exception {
+		this.project = project;
+		launcher = project.getProjectLauncher();
+		testbundles = project.getTestpath();
+		for (Container c : testbundles) {
+			launcher.addClasspath(c);
+		}
+		reportDir = new File(project.getTarget(), project.getProperty("test-reports",
+				"test-reports"));
+	}
+
+	public ProjectLauncher getProjectLauncher() {
+		return launcher;
+	}
+
+	public void addTest(String test) {
+		tests.add(test);
+	}
+
+	public Collection<String> getTests() {
+		return tests;
+	}
+
+	public Collection<File> getReports() {
+		List<File> reports = new ArrayList<File>();
+		for (File report : reportDir.listFiles()) {
+			if (report.isFile() )
+				reports.add(report);
+		}
+		return reports;
+	}
+
+	public File getReportDir() {
+		return reportDir;
+	}
+
+	public void setReportDir(File reportDir) {
+		this.reportDir = reportDir;
+	}
+
+	public Project getProject() {
+		return project;
+	}
+
+	public boolean getContinuous() {
+		return continuous;
+	}
+
+	public void setContinuous(boolean b) {
+		this.continuous = b;
+	}
+
+	public boolean prepare() throws Exception {
+		reportDir.mkdirs();
+		for ( File file : reportDir.listFiles() ) {
+			file.delete();
+		}
+		return true;
+	}
+
+	public abstract int test() throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ReflectAction.java b/bundleplugin/src/main/java/aQute/bnd/build/ReflectAction.java
new file mode 100644
index 0000000..55c2861
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ReflectAction.java
@@ -0,0 +1,22 @@
+package aQute.bnd.build;
+
+import java.lang.reflect.*;
+
+import aQute.bnd.service.action.*;
+
+public class ReflectAction implements Action {
+    String  what;
+    
+    public ReflectAction(String what) {
+        this.what = what;
+    }
+    
+    public void execute(Project project, String action) throws Exception {
+        Method m = project.getClass().getMethod(what);
+        m.invoke(project);
+    }
+
+    public String toString() {
+        return "ra:" + what;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ResolverMode.java b/bundleplugin/src/main/java/aQute/bnd/build/ResolverMode.java
new file mode 100644
index 0000000..1a98e76
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ResolverMode.java
@@ -0,0 +1,5 @@
+package aQute.bnd.build;
+
+public enum ResolverMode {
+	build, runtime
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ScriptAction.java b/bundleplugin/src/main/java/aQute/bnd/build/ScriptAction.java
new file mode 100644
index 0000000..8ca55fd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ScriptAction.java
@@ -0,0 +1,18 @@
+package aQute.bnd.build;
+
+import aQute.bnd.service.action.*;
+
+public class ScriptAction implements Action {
+    final String script;
+    final String type;
+    
+    public ScriptAction(String type, String script) {
+        this.script = script;
+        this.type = type;
+    }
+
+    public void execute(Project project, String action) throws Exception {
+        project.script(type, script);
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Workspace.java b/bundleplugin/src/main/java/aQute/bnd/build/Workspace.java
new file mode 100644
index 0000000..ed8a94e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Workspace.java
@@ -0,0 +1,294 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.lang.ref.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
+import java.util.jar.*;
+
+import javax.naming.*;
+
+import aQute.bnd.maven.support.*;
+import aQute.bnd.service.*;
+import aQute.bnd.service.action.*;
+import aQute.lib.deployer.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+
+public class Workspace extends Processor {
+	public static final String					BUILDFILE	= "build.bnd";
+	public static final String					CNFDIR		= "cnf";
+	public static final String					BNDDIR		= "bnd";
+	public static final String					CACHEDIR	= "cache";
+
+	static Map<File, WeakReference<Workspace>>	cache		= newHashMap();
+	final Map<String, Project>					models		= newHashMap();
+	final Map<String, Action>					commands	= newMap();
+	final CachedFileRepo						cachedRepo;
+	final File									buildDir;
+	final Maven									maven		= new Maven(Processor.getExecutor());
+	private boolean	postpone;
+
+	/**
+	 * This static method finds the workspace and creates a project (or returns
+	 * an existing project)
+	 * 
+	 * @param projectDir
+	 * @return
+	 */
+	public static Project getProject(File projectDir) throws Exception {
+		projectDir = projectDir.getAbsoluteFile();
+		assert projectDir.isDirectory();
+
+		Workspace ws = getWorkspace(projectDir.getParentFile());
+		return ws.getProject(projectDir.getName());
+	}
+
+	public static Workspace getWorkspace(File parent) throws Exception {
+		File workspaceDir = parent.getAbsoluteFile();
+
+		// the cnf directory can actually be a
+		// file that redirects
+		while (workspaceDir.isDirectory()) {
+			File test = new File(workspaceDir, CNFDIR);
+
+			if (!test.exists())
+				test = new File(workspaceDir, BNDDIR);
+
+			if (test.isDirectory())
+				break;
+
+			if (test.isFile()) {
+				String redirect = IO.collect(test).trim();
+				test = getFile(test.getParentFile(), redirect).getAbsoluteFile();
+				workspaceDir = test;
+			}
+			if (!test.exists())
+				throw new IllegalArgumentException("No Workspace found from: " + parent);
+		}
+
+		synchronized (cache) {
+			WeakReference<Workspace> wsr = cache.get(workspaceDir);
+			Workspace ws;
+			if (wsr == null || (ws = wsr.get()) == null) {
+				ws = new Workspace(workspaceDir);
+				cache.put(workspaceDir, new WeakReference<Workspace>(ws));
+			}
+			return ws;
+		}
+	}
+
+	public Workspace(File dir) throws Exception {
+		dir = dir.getAbsoluteFile();
+		dir.mkdirs();
+		assert dir.isDirectory();
+
+		File buildDir = new File(dir, BNDDIR).getAbsoluteFile();
+		if (!buildDir.isDirectory())
+			buildDir = new File(dir, CNFDIR).getAbsoluteFile();
+
+		this.buildDir = buildDir;
+
+		File buildFile = new File(buildDir, BUILDFILE).getAbsoluteFile();
+		if (!buildFile.isFile())
+			warning("No Build File in " + dir);
+
+		setProperties(buildFile, dir);
+		propertiesChanged();
+		
+		cachedRepo = new CachedFileRepo();
+	}
+
+	public Project getProject(String bsn) throws Exception {
+		synchronized (models) {
+			Project project = models.get(bsn);
+			if (project != null)
+				return project;
+
+			File projectDir = getFile(bsn);
+			project = new Project(this, projectDir);
+			if (!project.isValid())
+				return null;
+
+			models.put(bsn, project);
+			return project;
+		}
+	}
+
+	public boolean isPresent(String name) {
+		return models.containsKey(name);
+	}
+
+	public Collection<Project> getCurrentProjects() {
+		return models.values();
+	}
+
+	public boolean refresh() {
+		if (super.refresh()) {
+			for (Project project : getCurrentProjects()) {
+				project.propertiesChanged();
+			}
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	public void propertiesChanged() {
+		super.propertiesChanged();
+		File extDir = new File(this.buildDir, "ext");
+		File[] extensions = extDir.listFiles();
+		if (extensions != null) {
+			for (File extension : extensions) {
+				if (extension.getName().endsWith(".bnd")) {
+					try {
+						doIncludeFile(extension, true, getProperties());
+					} catch (Exception e) {
+						error("PropertiesChanged: " + e.getMessage());
+					}
+				}
+			}
+		}
+	}
+
+	public String _workspace(String args[]) {
+		return getBase().getAbsolutePath();
+	}
+
+	public void addCommand(String menu, Action action) {
+		commands.put(menu, action);
+	}
+
+	public void removeCommand(String menu) {
+		commands.remove(menu);
+	}
+
+	public void fillActions(Map<String, Action> all) {
+		all.putAll(commands);
+	}
+
+	public Collection<Project> getAllProjects() throws Exception {
+		List<Project> projects = new ArrayList<Project>();
+		for (File file : getBase().listFiles()) {
+			if (new File(file, Project.BNDFILE).isFile())
+				projects.add(getProject(file));
+		}
+		return projects;
+	}
+
+	/**
+	 * Inform any listeners that we changed a file (created/deleted/changed).
+	 * 
+	 * @param f
+	 *            The changed file
+	 */
+	public void changedFile(File f) {
+		List<BndListener> listeners = getPlugins(BndListener.class);
+		for (BndListener l : listeners)
+			try {
+				l.changed(f);
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+	}
+
+	public void bracket(boolean begin) {
+		List<BndListener> listeners = getPlugins(BndListener.class);
+		for (BndListener l : listeners)
+			try {
+				if ( begin )
+					l.begin();
+				else
+					l.end();
+			} catch (Exception e) {
+				// who cares?
+			}
+	}
+
+
+	private void copy(InputStream in, OutputStream out) throws Exception {
+		byte data[] = new byte[10000];
+		int size = in.read(data);
+		while (size > 0) {
+			out.write(data, 0, size);
+			size = in.read(data);
+		}
+	}
+
+	class CachedFileRepo extends FileRepo {
+		final Lock	lock	= new ReentrantLock();
+		boolean		inited;
+
+		CachedFileRepo() {
+			super("cache", getFile(buildDir, CACHEDIR), false);
+		}
+
+		protected void init() throws Exception {
+			if (lock.tryLock(50, TimeUnit.SECONDS) == false)
+				throw new TimeLimitExceededException(
+						"Cached File Repo is locked and can't acquire it");
+			try {
+				if (!inited) {
+					inited = true;
+					root.mkdirs();
+					if (!root.isDirectory())
+						throw new IllegalArgumentException("Cannot create cache dir " + root);
+
+					InputStream in = getClass().getResourceAsStream(EMBEDDED_REPO);
+					if (in != null)
+						unzip(in, root);
+					else
+						System.out.println("!!!! WTF Couldn't find embedded-repo.jar in bundle ");
+				}
+			} finally {
+				lock.unlock();
+			}
+		}
+
+		void unzip(InputStream in, File dir) throws Exception {
+			try {
+				JarInputStream jin = new JarInputStream(in);
+				JarEntry jentry = jin.getNextJarEntry();
+				while (jentry != null) {
+					if (!jentry.isDirectory()) {
+						File dest = Processor.getFile(dir, jentry.getName());
+						if (!dest.isFile() || dest.lastModified() < jentry.getTime()
+								|| jentry.getTime() == 0) {
+							dest.getParentFile().mkdirs();
+							FileOutputStream out = new FileOutputStream(dest);
+							try {
+								copy(jin, out);
+							} finally {
+								out.close();
+							}
+						}
+					}
+					jentry = jin.getNextJarEntry();
+				}
+			} finally {
+				in.close();
+			}
+		}
+	}
+
+	public List<RepositoryPlugin> getRepositories() {
+		return getPlugins(RepositoryPlugin.class);
+	}
+
+	public static Workspace getWorkspace(String path) throws Exception {
+		File file = IO.getFile(new File(""), path);
+		return getWorkspace(file);
+	}
+
+	public Maven getMaven() {
+		return maven;
+	}
+
+	@Override
+	protected void setTypeSpecificPlugins( Set<Object> list) {
+		super.setTypeSpecificPlugins(list);
+		list.add(maven);
+		list.add(cachedRepo);
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/packageinfo b/bundleplugin/src/main/java/aQute/bnd/build/packageinfo
new file mode 100644
index 0000000..ec0efd4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/packageinfo
@@ -0,0 +1 @@
+version 1.43.1
diff --git a/bundleplugin/src/main/java/aQute/bnd/compatibility/Access.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/Access.java
new file mode 100644
index 0000000..ac8bb37
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/compatibility/Access.java
@@ -0,0 +1,25 @@
+package aQute.bnd.compatibility;
+
+import java.lang.reflect.*;
+
+/**
+ * Access modifier
+ */
+public enum Access {
+	PUBLIC, PROTECTED, PACKAGE, PRIVATE, UNKNOWN;
+
+	public static Access modifier(int mod) {
+		if (Modifier.isPublic(mod))
+			return PUBLIC;
+		if (Modifier.isProtected(mod))
+			return PROTECTED;
+		if (Modifier.isPrivate(mod))
+			return PRIVATE;
+
+		return PACKAGE;
+	}
+
+	public String toString() {
+		return super.toString().toLowerCase();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/compatibility/GenericParameter.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/GenericParameter.java
new file mode 100644
index 0000000..1eac28c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/compatibility/GenericParameter.java
@@ -0,0 +1,25 @@
+package aQute.bnd.compatibility;
+
+public class GenericParameter {
+	String name;
+	GenericType bounds[];
+	
+	public GenericParameter(String name, GenericType[] bounds) {
+		this.name = name;
+		this.bounds = bounds;
+		if (bounds == null || bounds.length == 0)
+			bounds = new GenericType[] { new GenericType( Object.class) };
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		sb.append(name);
+		if ( bounds != null && bounds.length > 0) {
+			for ( GenericType gtype : bounds ) {
+				sb.append( ":");
+				sb.append(gtype);
+			}
+		}
+		return sb.toString();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/compatibility/GenericType.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/GenericType.java
new file mode 100644
index 0000000..847a358
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/compatibility/GenericType.java
@@ -0,0 +1,37 @@
+package aQute.bnd.compatibility;
+
+
+public class GenericType {
+	public GenericType(Class<Object> class1) {
+		// TODO Auto-generated constructor stub
+	}
+
+	final static GenericType	EMPTY[]	= new GenericType[0];
+	Scope						reference;
+	GenericType[]				a;
+	GenericType[]				b;
+	int							array;
+	
+	Scope	scope;
+	
+		static public class GenericWildcard extends GenericType{
+
+		public GenericWildcard(Class<Object> class1) {
+			super(class1);
+			// TODO Auto-generated constructor stub
+		}
+		
+	}
+	
+	static public class GenericArray extends GenericType {
+
+		public GenericArray(Class<Object> class1) {
+			super(class1);
+			// TODO Auto-generated constructor stub
+		}
+		
+	}
+	
+	
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/compatibility/Kind.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/Kind.java
new file mode 100644
index 0000000..1e84030
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/compatibility/Kind.java
@@ -0,0 +1,13 @@
+package aQute.bnd.compatibility;
+
+/**
+ * The kind of thing we scope
+ * 
+ */
+public enum Kind {
+	ROOT, CLASS, FIELD, CONSTRUCTOR, METHOD, UNKNOWN;
+
+	public String toString() {
+		return super.toString().toLowerCase();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/compatibility/ParseSignatureBuilder.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/ParseSignatureBuilder.java
new file mode 100644
index 0000000..dc578ea
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/compatibility/ParseSignatureBuilder.java
@@ -0,0 +1,109 @@
+package aQute.bnd.compatibility;
+
+import java.io.*;
+
+import aQute.lib.osgi.*;
+
+public class ParseSignatureBuilder {
+	final Scope			root;
+	
+	public ParseSignatureBuilder(Scope root) {
+		this.root = root;
+	}
+	
+	public void add( Jar jar ) throws Exception {
+		for ( Resource r : jar.getResources().values()) {
+			InputStream in = r.openInputStream();
+			try {
+				parse(in);
+			} finally {
+				in.close();
+			}
+		}
+	}
+	
+	public Scope getRoot() { return root; }
+	
+	
+	public void parse(InputStream in) throws IOException {
+		Clazz clazz = new Clazz("", null);
+		
+		clazz.parseClassFile(in, new ClassDataCollector() {
+			Scope	s;
+			Scope	enclosing;
+			Scope	declaring;
+
+			public void classBegin(int access, String name) {
+				s = root.getScope(Scope.classIdentity(name));
+				s.access = Access.modifier(access);
+				s.kind = Kind.CLASS;
+			}
+
+			public void extendsClass(String name) {
+//				s.setBase(new GenericType(name));
+			}
+
+			public void implementsInterfaces(String names[]) {
+				s.setParameterTypes(convert(names));
+			}
+
+			GenericType[] convert(String names[]) {
+				GenericType tss[] = new GenericType[names.length];
+				for (int i = 0; i < names.length; i++) {
+//					tss[i] = new GenericType(names[i]);
+				}
+				return tss;
+			}
+
+			public void method(Clazz.MethodDef defined) {
+				String descriptor;
+				Kind kind;
+				if (defined.isConstructor()) {
+					descriptor = ":" + defined.descriptor;
+					kind = Kind.CONSTRUCTOR;
+				} else {
+					descriptor = defined.name + ":" + defined.descriptor;
+					kind = Kind.METHOD;
+				}
+				Scope m = s.getScope(descriptor);
+				m.access = Access.modifier(defined.access);
+				m.kind = kind;
+				m.declaring = s;
+				s.add(m);
+			}
+
+			public void field(Clazz.FieldDef defined) {
+				String descriptor = defined.name + ":" + defined.descriptor;
+				Kind kind = Kind.FIELD;
+				Scope m = s.getScope(descriptor);
+				m.access = Access.modifier(defined.access);
+				m.kind = kind;
+				m.declaring = s;
+				s.add(m);
+			}
+
+			public void classEnd() {
+				if (enclosing != null)
+					s.setEnclosing( enclosing );
+				if (declaring != null)
+					s.setDeclaring( declaring );				
+			}
+
+			public void enclosingMethod(String cName, String mName, String mDescriptor) {
+				enclosing = root.getScope(Scope.classIdentity(cName));
+				if (mName != null) {
+					enclosing = enclosing.getScope(Scope.methodIdentity(mName, mDescriptor));
+				}
+			}
+
+			public void innerClass(String innerClass, String outerClass, String innerName,
+					int innerClassAccessFlags) {
+				if (outerClass != null && innerClass != null && innerClass.equals(s.name))
+					declaring = root.getScope(Scope.classIdentity(outerClass));
+			}
+		});
+		
+		
+	}
+}
+
diff --git a/bundleplugin/src/main/java/aQute/bnd/compatibility/RuntimeSignatureBuilder.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/RuntimeSignatureBuilder.java
new file mode 100644
index 0000000..7761701
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/compatibility/RuntimeSignatureBuilder.java
@@ -0,0 +1,220 @@
+package aQute.bnd.compatibility;
+
+import java.lang.reflect.*;
+
+public class RuntimeSignatureBuilder {
+	final Scope	root;
+
+	public RuntimeSignatureBuilder(Scope root) {
+		this.root = root;
+	}
+
+	static public String identity(Class<?> c) {
+		return Scope.classIdentity(c.getName());
+	}
+
+	static public String identity(Method m) {
+		return Scope.methodIdentity(m.getName(), getDescriptor(m.getReturnType(), m
+				.getParameterTypes()));
+	}
+
+	static public String identity(Constructor m) {
+		return Scope.constructorIdentity(getDescriptor(void.class, m.getParameterTypes()));
+	}
+
+	static public String identity(Field m) {
+		return Scope.fieldIdentity(m.getName(), getDescriptor(m.getType(), null));
+	}
+
+	static public String getDescriptor(Class<?> base, Class<?>[] parameters) {
+		StringBuilder sb = new StringBuilder();
+		if (parameters != null) {
+			sb.append("(");
+			for (Class<?> parameter : parameters) {
+				sb.append(getDescriptor(parameter));
+			}
+			sb.append(")");
+		}
+		sb.append(getDescriptor(base));
+		return sb.toString();
+	}
+
+	public Scope add(Class<?> c) {
+		Scope local = add(root, getEnclosingScope(c), c.getModifiers(), c.getTypeParameters(),
+				Kind.CLASS, identity(c), c.getGenericSuperclass(), c.getGenericInterfaces(), null);
+
+		for (Field f : c.getDeclaredFields()) {
+			add(local, // declaring scope
+					local, // enclosing
+					f.getModifiers(), // access modifiers
+					null, // fields have no type vars
+					Kind.FIELD, // field
+					identity(f), // the name of the field
+					f.getGenericType(), // the type of the field
+					null, // fields have no parameters
+					null // fields have no exceptions
+			);
+		}
+
+		for (Constructor constr : c.getConstructors()) {
+			add(local, // class scope
+					local, // enclosing
+					constr.getModifiers(), // access modifiers
+					constr.getTypeParameters(), // Type vars
+					Kind.CONSTRUCTOR, // constructor
+					identity(constr), // <init>(type*)
+					void.class, // Always void
+					constr.getGenericParameterTypes(), // parameters types
+					constr.getGenericExceptionTypes() // exception types
+			);
+		}
+
+		for (Method m : c.getDeclaredMethods()) {
+			if (m.getDeclaringClass() != Object.class) {
+				add(local, // class scope
+						local, // enclosing
+						m.getModifiers(), // access modifiers
+						m.getTypeParameters(), Kind.METHOD, // method
+						identity(m), // <name>(type*)return
+						m.getGenericReturnType(), // return type
+						m.getGenericParameterTypes(), // parameter types
+						m.getGenericExceptionTypes() // exception types
+				);
+			}
+		}
+
+		return local;
+	}
+
+	private Scope getEnclosingScope(Class<?> c) {
+		Method m = c.getEnclosingMethod();
+		if (m != null) {
+			Scope s = getGlobalScope(m.getDeclaringClass());
+			return s.getScope(identity(m));
+		}
+// TODO
+//		Constructor cnstr = c.getEnclosingConstructor();
+//		if (m != null) {
+//			Scope s = getGlobalScope(cnstr.getDeclaringClass());
+//			return s.getScope(identity(cnstr));
+//
+//		}
+		Class<?> enclosingClass = c.getEnclosingClass();
+		if (enclosingClass != null) {
+			return getGlobalScope(enclosingClass);
+		}
+
+		return null;
+	}
+
+	private Scope getGlobalScope(Class<?> c) {
+		if (c == null)
+			return null;
+		String id = identity(c);
+		return root.getScope(id);
+	}
+
+	private Scope add(Scope declaring, Scope enclosing, int modifiers,
+			TypeVariable<?>[] typeVariables, Kind kind, String id, Type mainType,
+			Type[] parameterTypes, Type exceptionTypes[]) {
+
+		Scope scope = declaring.getScope(id);
+		assert scope.access == Access.UNKNOWN;
+		scope.setAccess(Access.modifier(modifiers));
+		scope.setKind(kind);
+		scope.setGenericParameter(convert(typeVariables));
+		scope.setBase(convert(scope,mainType));
+		scope.setParameterTypes(convert(parameterTypes));
+		scope.setExceptionTypes(convert(exceptionTypes));
+		scope.setDeclaring(declaring);
+		scope.setEnclosing(enclosing);
+		return scope;
+	}
+
+	private GenericType convert(Scope source, Type t) {
+		if (t instanceof ParameterizedType) {
+			// C<P..>
+			ParameterizedType pt = (ParameterizedType) t;
+			/*Scope reference =*/ root.getScope(identity((Class<?>)pt.getRawType()));			
+			Type args[] = pt.getActualTypeArguments();
+			GenericType[] arguments = new GenericType[args.length];
+			int n = 0;
+			for (Type arg : args)
+				arguments[n++] = convert(source,arg);
+//			return new GenericType(reference,null,arguments);
+			
+		} else if (t instanceof TypeVariable) {
+//			TypeVariable tv = (TypeVariable) t;
+//			return new GenericType(source,tv.getName(), null);
+		} else if (t instanceof WildcardType) {
+//			WildcardType wc = (WildcardType) t;
+//			wc.
+		} else if (t instanceof GenericArrayType) {
+
+		}
+		if (t instanceof Class<?>) {
+//			raw = ((Class<?>) t).getName() + ";";
+		} else
+			throw new IllegalArgumentException(t.toString());
+
+		return null;
+	}
+
+	private GenericParameter[] convert(TypeVariable vars[]) {
+		if (vars == null)
+			return null;
+
+		GenericParameter out[] = new GenericParameter[vars.length];
+		for (int i = 0; i < vars.length; i++) {
+			GenericType gss[] = convert(vars[i].getBounds());
+			out[i] = new GenericParameter(vars[i].getName(), gss);
+		}
+		return out;
+	}
+
+	private GenericType[] convert(Type[] parameterTypes) {
+		if (parameterTypes == null || parameterTypes.length == 0)
+			return GenericType.EMPTY;
+
+		GenericType tss[] = new GenericType[parameterTypes.length];
+		for (int i = 0; i < parameterTypes.length; i++) {
+			//tss[i] = new GenericType(parameterTypes[i]);
+		}
+		return tss;
+	}
+
+	private static String getDescriptor(Class<?> c) {
+		StringBuilder sb = new StringBuilder();
+		if (c.isPrimitive()) {
+			if (c == boolean.class)
+				sb.append("Z");
+			else if (c == byte.class)
+				sb.append("Z");
+			else if (c == char.class)
+				sb.append("C");
+			else if (c == short.class)
+				sb.append("S");
+			else if (c == int.class)
+				sb.append("I");
+			else if (c == long.class)
+				sb.append("J");
+			else if (c == float.class)
+				sb.append("F");
+			else if (c == double.class)
+				sb.append("D");
+			else if (c == void.class)
+				sb.append("V");
+			else
+				throw new IllegalArgumentException("unknown primitive type: " + c);
+		} else if (c.isArray()) {
+			sb.append("[");
+			sb.append(getDescriptor(c));
+		} else {
+			sb.append("L");
+			sb.append(c.getName().replace('.', '/'));
+			sb.append(";");
+		}
+		return sb.toString();
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/compatibility/Scope.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/Scope.java
new file mode 100644
index 0000000..218a31c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/compatibility/Scope.java
@@ -0,0 +1,166 @@
+package aQute.bnd.compatibility;
+
+import java.io.*;
+import java.util.*;
+
+public class Scope {
+	final Map<String, Scope>	children	= new LinkedHashMap<String, Scope>();
+
+	// class: slashed name
+	// field: name ":" typed
+	// constructor: ":(" typed* ")" typed
+	// method: name ":(" typed* ")" typed
+	final String				name;
+
+	Access						access;
+	Kind						kind;
+	Scope						enclosing;
+	Scope						declaring;
+	GenericParameter						typeVars[];
+	Map<String, String[]>		name2bounds;
+
+	// class: super
+	// field: type
+	// constructor: void
+	// method: return
+	GenericType				base;
+
+	// class: interfaces
+	// constructor: args
+	// method: args
+	GenericType[]				parameters;
+
+	// constructor: exceptions
+	// method: exceptions
+	GenericType[]				exceptions;
+
+	// class: super interfaces*
+	// field: type
+	// constructor: void arguments*
+	// method: return arguments*
+
+	public Scope(Access access, Kind kind, String name) {
+		this.access = access;
+		this.kind = kind;
+		this.name = name;
+	}
+
+	Scope getScope(String name) {
+		Scope s = children.get(name);
+		if (s != null)
+			return s;
+
+		s = new Scope(Access.UNKNOWN, Kind.UNKNOWN, name);
+		children.put(name, s);
+		s.declaring = this;
+		return s;
+	}
+
+	public void setParameterTypes(GenericType[] convert) {
+		this.parameters = convert;
+	}
+
+	public void setExceptionTypes(GenericType[] convert) {
+		this.exceptions = convert;
+	}
+
+	public void setBase(GenericType typeSignature) {
+		base = typeSignature;
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		
+		if ( typeVars != null && typeVars.length !=0) {
+			sb.append("<");
+			for ( GenericParameter v : typeVars) {
+				sb.append(v);
+			}
+			sb.append(">");
+		}
+		sb.append(access.toString());
+		sb.append(" ");
+		sb.append(kind.toString());
+		sb.append( " ");
+		sb.append( name );
+		return sb.toString();
+	}
+
+	public void report(Appendable a, int indent) throws IOException {
+		for (int i = 0; i < indent; i++)
+			a.append("  ");
+		a.append(toString());
+		a.append("\n");
+		for (Scope s : children.values())
+			s.report(a, indent + 1);
+	}
+
+	public void add(Scope m) {
+		children.put(m.name, m);
+
+	}
+
+	public void setDeclaring(Scope declaring) {
+		this.declaring = declaring;
+	}
+
+	public void setAccess(Access access) {
+		this.access = access;
+	}
+
+	public void setEnclosing(Scope enclosing) {
+		this.enclosing = enclosing;
+		if (this.enclosing != null) {
+			this.enclosing.add(this);
+		}
+	}
+
+	public boolean isTop() {
+		return enclosing == null;
+	}
+
+	public void setKind(Kind kind) {
+		this.kind = kind;
+	}
+
+	static public String classIdentity(String name) {
+		return name.replace('.', '/');
+	}
+
+	static public String methodIdentity(String name, String descriptor) {
+		return name + ":" + descriptor;
+	}
+
+	static public String constructorIdentity(String descriptor) {
+		return ":" + descriptor;
+	}
+
+	static public String fieldIdentity(String name, String descriptor) {
+		return name + ":" + descriptor;
+	}
+
+	public void cleanRoot() {
+		Iterator<Map.Entry<String, Scope>> i = children.entrySet().iterator();
+		while (i.hasNext()) {
+			Map.Entry<String, Scope> entry = i.next();
+			if (!entry.getValue().isTop())
+				i.remove();
+		}
+	}
+
+	public void prune(EnumSet<Access> level) {
+		Iterator<Map.Entry<String, Scope>> i = children.entrySet().iterator();
+		while (i.hasNext()) {
+			Map.Entry<String, Scope> entry = i.next();
+			if (!level.contains(entry.getValue().access))
+				i.remove();
+			else
+				entry.getValue().prune(level);
+		}
+	}
+
+	public void setGenericParameter(GenericParameter[] typeVars) {
+		this.typeVars = typeVars;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/compatibility/SignatureGenerator.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/SignatureGenerator.java
new file mode 100644
index 0000000..25177df
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/compatibility/SignatureGenerator.java
@@ -0,0 +1,125 @@
+package aQute.bnd.compatibility;
+
+
+public class SignatureGenerator {
+//	enum ACCESS {
+////		PUBLIC("+"), PROTECTED("|"), PACKAGE_PRIVATE(""), PRIVATE("-");
+////		final String	repr;
+////
+////		ACCESS(String s) {
+////			repr = s;
+////		}
+////		
+////		public String toString() {
+////			return repr;
+////		}
+//	}
+//
+//	public static void main(String args[]) throws Exception {
+//		final PrintStream out = System.out;
+//
+//		Clazz c = new Clazz("x", new FileResource(new File(
+//				"src/aQute/bnd/compatibility/SignatureGenerator.class")));
+//		c.parseClassFileWithCollector(new ClassDataCollector() {
+//			public void classBegin(int access, String name) {
+//				out.print(name);
+//				out.println(access(access));
+//			}
+//
+//			private ACCESS access(int access) {
+//				if (Modifier.isPublic(access))
+//					return ACCESS.PUBLIC;
+//
+//				throw new IllegalArgumentException();
+//			}
+//
+//			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/bnd/compatibility/Signatures.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/Signatures.java
new file mode 100644
index 0000000..ec4a545
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/compatibility/Signatures.java
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) OSGi Alliance (2009, 2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package aQute.bnd.compatibility;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+/**
+ * This class is compiled against 1.5 or later to provide access to the generic
+ * signatures. It can convert a Class, Field, Method or constructor to a generic
+ * signature and it can normalize a signature. Both are methods. Normalized
+ * signatures can be string compared and match even if the type variable names
+ * differ.
+ * 
+ * @version $Id$
+ */
+public class Signatures {
+	
+	
+	/**
+	 * Check if the environment has generics, i.e. later than 
+	 * Java 5 VM.
+	 * 
+	 * @return true if generics are supported
+	 * @throws Exception
+	 */
+	public boolean hasGenerics() throws Exception {
+		try {
+			call( Signatures.class, "getGenericSuperClass");
+			return true;
+		} catch( NoSuchMethodException mnfe ) {
+			return false;
+		}
+	}
+	
+	
+	
+	/**
+	 * Helper class to track an index in a string.
+	 */
+	class Rover {
+		final String	s;
+		int				i;
+
+		public Rover(String s) {
+			this.s = s;
+			i = 0;
+		}
+
+		char peek() {
+			return s.charAt(i);
+		}
+
+		char take() {
+			return s.charAt(i++);
+		}
+
+		char take(char c) {
+			char x = s.charAt(i++);
+			if (c != x)
+				throw new IllegalStateException("get() expected " + c
+						+ " but got + " + x);
+			return x;
+		}
+
+		public String upTo(String except) {
+			int start = i;
+			while (except.indexOf(peek()) < 0)
+				take();
+			return s.substring(start, i);
+		}
+
+		public boolean isEOF() {
+			return i >= s.length();
+		}
+
+	}
+
+	/**
+	 * Calculate the generic signature of a Class,Method,Field, or Constructor.
+	 * @param f
+	 * @return
+	 * @throws Exception 
+	 */
+	public String getSignature(Object c) throws Exception {
+		if( c instanceof Class<?>)
+			return getSignature((Class<?>)c);
+		if( c instanceof Constructor<?>)
+			return getSignature((Constructor<?>)c);
+		if( c instanceof Method)
+			return getSignature((Method)c);
+		if( c instanceof Field)
+			return getSignature((Field)c);
+		
+		throw new IllegalArgumentException(c.toString());
+	}
+
+	/**
+	 * Calculate the generic signature of a Class. A Class consists of:
+	 * 
+	 * <pre>
+	 * 	  class        ::= declaration? reference reference*
+	 * </pre>
+	 * 
+	 * 
+	 * @param f
+	 * @return
+	 * @throws Exception 
+	 */
+	public String getSignature(Class< ? > c) throws Exception {
+		StringBuffer sb = new StringBuffer();
+		declaration(sb, c);
+		reference(sb, call(c, "getGenericSuperclass"));
+		for (Object type : (Object[]) call(c,"getGenericInterfaces")) {
+			reference(sb, type);
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * Calculate the generic signature of a Method. A Method consists of:
+	 * 
+	 * <pre>
+	 *    method ::= declaration? '(' reference* ')' reference
+	 * </pre>
+	 * 
+	 * @param c
+	 * @return
+	 * @throws Exception 
+	 */
+	public String getSignature(Method m) throws Exception {
+		StringBuffer sb = new StringBuffer();
+		declaration(sb, m);
+		sb.append('(');
+		for (Object type : (Object[]) call(m,"getGenericParameterTypes")) {
+			reference(sb, type);
+		}
+		sb.append(')');
+		reference(sb, call(m,"getGenericReturnType"));
+		return sb.toString();
+	}
+
+	/**
+	 * Calculate the generic signature of a Constructor. A Constructor consists
+	 * of:
+	 * 
+	 * <pre>
+	 *    constructor ::= declaration? '(' reference* ')V'
+	 * </pre>
+	 * 
+	 * @param c
+	 * @return
+	 * @throws Exception 
+	 */
+	public String getSignature(Constructor< ? > c) throws Exception {
+		StringBuffer sb = new StringBuffer();
+		declaration(sb, c);
+		sb.append('(');
+		for (Object type : (Object[]) call(c,"getGenericParameterTypes")) {
+			reference(sb, type);
+		}
+		sb.append(')');
+		reference(sb, void.class);
+		return sb.toString();
+	}
+
+	/**
+	 * Calculate the generic signature of a Field. A Field consists of:
+	 * 
+	 * <pre>
+	 *    constructor ::= reference
+	 * </pre>
+	 * 
+	 * @param c
+	 * @return
+	 * @throws Exception 
+	 */
+	public String getSignature(Field f) throws Exception {
+		StringBuffer sb = new StringBuffer();
+		Object t = call(f,"getGenericType");
+		reference(sb, t);
+		return sb.toString();
+	}
+
+/**
+	 * Classes, Methods, or Constructors can have a declaration that provides
+	 * nested a scope for type variables. A Method/Constructor inherits
+	 * the type variables from its class and a class inherits its type variables
+	 * from its outer class. The declaration consists of the following
+	 * syntax:
+	 * <pre>
+	 *    declarations ::= '<' declaration ( ',' declaration )* '>'
+	 *    declaration  ::= identifier ':' declare
+	 *    declare      ::= types | variable 
+	 *    types        ::= ( 'L' class ';' )? ( ':' 'L' interface ';' )*
+	 *    variable     ::= 'T' id ';'
+	 * </pre>
+	 * 
+	 * @param sb
+	 * @param gd
+ * @throws Exception 
+	 */
+	private void declaration(StringBuffer sb, Object gd) throws Exception {
+		Object[] typeParameters = (Object[]) call(gd,"getTypeParameters");
+		if (typeParameters.length > 0) {
+			sb.append('<');
+			for (Object tv : typeParameters) {
+				sb.append( call(tv,"getName"));
+
+				Object[] bounds = (Object[]) call(tv,"getBounds");
+				if (bounds.length > 0 && isInterface(bounds[0])) {
+					sb.append(':');
+				}
+				for (int i = 0; i < bounds.length; i++) {
+					sb.append(':');
+					reference(sb, bounds[i]);
+				}
+			}
+			sb.append('>');
+		}
+	}
+
+	/**
+	 * Verify that the type is an interface.
+	 * 
+	 * @param type the type to check.
+	 * @return true if this is a class that is an interface or a Parameterized
+	 *         Type that is an interface
+	 * @throws Exception 
+	 */
+	private boolean isInterface(Object type) throws Exception {
+		if (type instanceof Class)
+			return (((Class< ? >) type).isInterface());
+
+		if ( isInstance(type.getClass(), "java.lang.reflect.ParameterizedType"))
+			return isInterface(call(type,"getRawType"));
+
+		return false;
+	}
+
+
+/**
+	 * This is the heart of the signature builder. A reference is used
+	 * in a lot of places. It referes to another type.
+	 * <pre>
+	 *   reference     ::= array | class | primitive | variable
+	 *   array         ::= '[' reference
+	 *   class         ::=  'L' body ( '.' body )* ';'
+	 *   body          ::=  id ( '<' ( wildcard | reference )* '>' )?
+	 *   variable      ::=  'T' id ';'
+	 *   primitive     ::= PRIMITIVE
+	 * </pre>
+	 * 
+	 * @param sb
+	 * @param t
+ * @throws Exception 
+	 */
+	private void reference(StringBuffer sb, Object t) throws Exception {
+
+		if ( isInstance(t.getClass(),"java.lang.reflect.ParameterizedType")) {
+			sb.append('L');
+			parameterizedType(sb, t);
+			sb.append(';');
+			return;
+		}
+		else
+			if ( isInstance(t.getClass(), "java.lang.reflect.GenericArrayType")) {
+				sb.append('[');
+				reference(sb, call(t,"getGenericComponentType"));
+			}
+			else
+				if ( isInstance(t.getClass(), "java.lang.reflect.WildcardType")) {
+					Object[] lowerBounds = (Object[]) call(t, "getLowerBounds");
+					Object[] upperBounds = (Object[]) call(t, "getUpperBounds");
+
+					if (upperBounds.length == 1
+							&& upperBounds[0] == Object.class)
+						upperBounds = new Object[0];
+
+					if (upperBounds.length != 0) {
+						// extend
+						for (Object upper : upperBounds) {
+							sb.append('+');
+							reference(sb, upper);
+						}
+					}
+					else
+						if (lowerBounds.length != 0) {
+							// super, can only be one by the language
+							for (Object lower : lowerBounds) {
+								sb.append('-');
+								reference(sb, lower);
+							}
+						}
+						else
+							sb.append('*');
+				}
+				else
+					if ( isInstance(t.getClass(),"java.lang.reflect.TypeVariable")) {
+						sb.append('T');
+						sb.append( call(t,"getName"));
+						sb.append(';');
+					}
+					else
+						if (t instanceof Class< ? >) {
+							Class< ? > c = (Class< ? >) t;
+							if (c.isPrimitive()) {
+								sb.append(primitive(c));
+							}
+							else {
+								sb.append('L');
+								String name = c.getName().replace('.', '/');
+								sb.append(name);
+								sb.append(';');
+							}
+						}
+	}
+
+	/**
+	 * Creates the signature for a Parameterized Type.
+	 * 
+	 * A Parameterized Type has a raw class and a set of type variables.
+	 * 
+	 * @param sb
+	 * @param pt
+	 * @throws Exception 
+	 */
+	private void parameterizedType(StringBuffer sb, Object pt) throws Exception {
+		Object owner = call(pt,"getOwnerType");
+		String name = ((Class< ? >) call(pt,"getRawType")).getName()
+				.replace('.', '/');
+		if (owner != null) {
+			if ( isInstance(owner.getClass(), "java.lang.reflect.ParameterizedType"))
+				parameterizedType(sb, owner);
+			else
+				sb.append(((Class< ? >) owner).getName().replace('.', '/'));
+			sb.append('.');
+			int n = name.lastIndexOf('$');
+			name = name.substring(n + 1);
+		}
+		sb.append(name);
+
+		sb.append('<');
+		for (Object parameterType : (Object[]) call(pt,"getActualTypeArguments")) {
+			reference(sb, parameterType);
+		}
+		sb.append('>');
+
+	}
+
+	/**
+	 * Handle primitives, these need to be translated to a single char.
+	 * 
+	 * @param type the primitive class
+	 * @return the single char associated with the primitive
+	 */
+	private char primitive(Class< ? > type) {
+		if (type == byte.class)
+			return 'B';
+		else
+			if (type == char.class)
+				return 'C';
+			else
+				if (type == double.class)
+					return 'D';
+				else
+					if (type == float.class)
+						return 'F';
+					else
+						if (type == int.class)
+							return 'I';
+						else
+							if (type == long.class)
+								return 'J';
+							else
+								if (type == short.class)
+									return 'S';
+								else
+									if (type == boolean.class)
+										return 'Z';
+									else
+										if (type == void.class)
+											return 'V';
+										else
+											throw new IllegalArgumentException(
+													"Unknown primitive type "
+															+ type);
+	}
+
+	/**
+	 * Normalize a signature to make sure the name of the variables are always
+	 * the same. We change the names of the type variables to _n, where n is an
+	 * integer. n is incremented for every new name and already used names are
+	 * replaced with the _n name.
+	 * 
+	 * @return a normalized signature
+	 */
+
+	public String normalize(String signature) {
+		StringBuffer sb = new StringBuffer();
+		Map<String, String> map = new HashMap<String, String>();
+		Rover rover = new Rover(signature);
+		declare(sb, map, rover);
+
+		if (rover.peek() == '(') {
+			// method or constructor
+			sb.append(rover.take('('));
+			while (rover.peek() != ')') {
+				reference(sb, map, rover, true);
+			}
+			sb.append(rover.take(')'));
+			reference(sb, map, rover, true); // return type
+		}
+		else {
+			// field or class
+			reference(sb, map, rover, true); // field type or super class
+			while (!rover.isEOF()) {
+				reference(sb, map, rover, true); // interfaces
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * The heart of the routine. Handle a reference to a type. Can be
+	 * an array, a class, a type variable, or a primitive.
+	 * 
+	 * @param sb
+	 * @param map
+	 * @param rover
+	 * @param primitivesAllowed
+	 */
+	private void reference(StringBuffer sb, Map<String, String> map,
+			Rover rover, boolean primitivesAllowed) {
+
+		char type = rover.take();
+		sb.append(type);
+
+		if (type == '[') {
+			reference(sb, map, rover, true);
+		}
+		else
+			if (type == 'L') {
+				String fqnb = rover.upTo("<;.");
+				sb.append(fqnb);
+				body(sb, map, rover);
+				while (rover.peek() == '.') {
+					sb.append(rover.take('.'));
+					sb.append(rover.upTo("<;."));
+					body(sb, map, rover);
+				}
+				sb.append(rover.take(';'));
+			}
+			else
+				if (type == 'T') {
+					String name = rover.upTo(";");
+					name = assign(map, name);
+					sb.append(name);
+					sb.append(rover.take(';'));
+				}
+				else {
+					if (!primitivesAllowed)
+						throw new IllegalStateException(
+								"Primitives are not allowed without an array");
+				}
+	}
+
+	/**
+	 * Because classes can be nested the body handles the part that can 
+	 * be nested, the reference handles the enclosing L ... ;
+	 * 
+	 * @param sb
+	 * @param map
+	 * @param rover
+	 */
+	private void body(StringBuffer sb, Map<String, String> map, Rover rover) {
+		if (rover.peek() == '<') {
+			sb.append(rover.take('<'));
+			while (rover.peek() != '>') {
+				switch (rover.peek()) {
+					case 'L' :
+					case '[' :
+						reference(sb, map, rover, false);
+						break;
+
+					case 'T' :
+						String name;
+						sb.append(rover.take('T')); // 'T'
+						name = rover.upTo(";");
+						sb.append(assign(map, name));
+						sb.append(rover.take(';'));
+						break;
+
+					case '+' : // extends
+					case '-' : // super
+						sb.append(rover.take());
+						reference(sb, map, rover, false);
+						break;
+
+					case '*' : // wildcard
+						sb.append(rover.take());
+						break;
+
+				}
+			}
+			sb.append(rover.take('>'));
+		}
+	}
+
+	/**
+	 * Handle the declaration part.
+	 * 
+	 * @param sb
+	 * @param map
+	 * @param rover
+	 */
+	private void declare(StringBuffer sb, Map<String, String> map, Rover rover) {
+		char c = rover.peek();
+		if (c == '<') {
+			sb.append(rover.take('<'));
+
+			while (rover.peek() != '>') {
+				String name = rover.upTo(":");
+				name = assign(map, name);
+				sb.append(name);
+				typeVar: while (rover.peek() == ':') {
+					sb.append(rover.take(':'));
+					switch (rover.peek()) {
+						case ':' : // empty class cases
+							continue typeVar;
+
+						default :
+							reference(sb, map, rover, false);
+							break;
+					}
+				}
+			}
+			sb.append(rover.take('>'));
+		}
+	}
+
+	/**
+	 * Handles the assignment of type variables to index names so that
+	 * we have a normalized name for each type var.
+	 * 
+	 * @param map the map with variables.
+	 * @param name The name of the variable
+	 * @return the index name, like _1
+	 */
+	private String assign(Map<String, String> map, String name) {
+		if (map.containsKey(name))
+			return map.get(name);
+		else {
+			int n = map.size();
+			map.put(name, "_" + n);
+			return "_" + n;
+		}
+	}
+
+	private boolean isInstance(Class<?> type, String string) {
+		if ( type == null)
+			return false;
+		
+		if ( type.getName().equals(string))
+			return true;
+		
+		if ( isInstance( type.getSuperclass(), string))
+			return true;
+		
+		for ( Class<?> intf : type.getInterfaces()) {
+			if ( isInstance(intf,string))
+				return true;
+		}
+		return false;
+	}
+	
+	private Object call(Object gd, String string) throws Exception {
+		Method m = gd.getClass().getMethod(string);
+		return m.invoke(gd);
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java b/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java
new file mode 100644
index 0000000..af927f4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java
@@ -0,0 +1,344 @@
+package aQute.bnd.component;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+import org.osgi.service.component.annotations.*;
+
+import aQute.lib.collections.*;
+import aQute.lib.osgi.*;
+import aQute.libg.version.*;
+
+public class AnnotationReader extends ClassDataCollector {
+	final static String[]			EMPTY					= new String[0];
+	final static Pattern			PROPERTY_PATTERN		= Pattern
+																	.compile("([^=]+(:(Boolean|Byte|Char|Short|Integer|Long|Float|Double|String))?)\\s*=(.*)");
+
+	public static final Version	V1_1					= new Version("1.1.0");																												// "1.1.0"
+	public static final Version	V1_2					= new Version("1.2.0");																												// "1.1.0"
+	static Pattern					BINDDESCRIPTOR			= Pattern
+																	.compile("\\(((L([^;]+);)(Ljava/util/Map;)?|Lorg/osgi/framework/ServiceReference;)\\)V");
+	static Pattern					BINDMETHOD				= Pattern
+																	.compile("(set|bind|add)?(.*)");
+
+	static Pattern					ACTIVATEDESCRIPTOR		= Pattern
+																	.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;))*\\)V");
+	static Pattern					REFERENCEBINDDESCRIPTOR	= Pattern
+																	.compile("\\(Lorg/osgi/framework/ServiceReference;\\)V");
+
+	ComponentDef					component				= new ComponentDef();
+
+	Clazz							clazz;
+	String							interfaces[];
+	String							methodDescriptor;
+	String							method;
+	String							className;
+	int								methodAccess;
+	Analyzer						analyzer;
+	MultiMap<String, String>		methods					= new MultiMap<String, String>();
+	String							extendsClass;
+
+	AnnotationReader(Analyzer analyzer, Clazz clazz) {
+		this.analyzer = analyzer;
+		this.clazz = clazz;
+	}
+
+	public static ComponentDef getDefinition(Clazz c, Analyzer analyzer) throws Exception {
+		AnnotationReader r = new AnnotationReader(analyzer, c);
+
+		return r.getDef(c, analyzer);
+	}
+
+	/**
+	 * fixup any unbind methods To declare no unbind method, the value "-" must
+	 * be used. If not specified, the name of the unbind method is derived from
+	 * the name of the annotated bind method. If the annotated method name
+	 * begins with set, that is replaced with unset to derive the unbind method
+	 * name. If the annotated method name begins with add, that is replaced with
+	 * remove to derive the unbind method name. Otherwise, un is prefixed to the
+	 * annotated method name to derive the unbind method name.
+	 * 
+	 * @return
+	 * @throws Exception
+	 */
+	private ComponentDef getDef(Clazz c, Analyzer analyzer) throws Exception {
+		c.parseClassFileWithCollector(this);
+		if (component.implementation == null)
+			return null;
+
+		while (extendsClass != null) {
+			if (extendsClass.startsWith("java/"))
+				break;
+
+			Clazz ec = analyzer.findClass(extendsClass);
+			if (ec == null) {
+				analyzer.error("Missing super class for DS annotations: "
+						+ Clazz.pathToFqn(extendsClass) + " from " + c.getFQN());
+			} else {
+				c.parseClassFileWithCollector(this);
+			}
+		}
+
+		if (component.implementation != null) {
+			for (ReferenceDef rdef : component.references.values()) {
+				rdef.unbind = referredMethod(analyzer, rdef, rdef.unbind, "add(.*)", "remove$1", "(.*)",
+						"un$1");
+				rdef.modified = referredMethod(analyzer, rdef, rdef.modified, "(add|set)(.*)", "modified$2",
+						"(.*)", "modified$1");
+			}
+			return component;
+		} else
+			return null;
+	}
+
+	/**
+	 * 
+	 * @param analyzer
+	 * @param rdef
+	 */
+	protected String referredMethod(Analyzer analyzer, ReferenceDef rdef, String value,
+			String... matches) {
+		if (value == null) {
+			String bind = rdef.bind;
+			for (int i = 0; i < matches.length; i += 2) {
+				Matcher m = Pattern.compile(matches[i]).matcher(bind);
+				if (m.matches()) {
+					value = m.replaceFirst(matches[i+1]);
+					break;
+				}
+			}
+		} else if (value.equals("-"))
+			return null;
+
+		if (methods.containsKey(value)) {
+			for (String descriptor : methods.get(value)) {
+				Matcher matcher = BINDDESCRIPTOR.matcher(descriptor);
+				if (matcher.matches()) {
+					String type = matcher.group(2);
+					if (rdef.interfce.equals(Clazz.objectDescriptorToFQN(type))
+							|| type.equals("Ljava/util/Map;")
+							|| type.equals("Lorg/osgi/framework/ServiceReference;")) {
+
+						return value;
+					}
+				}
+			}
+			analyzer.error(
+					"A related method to %s from the reference %s has no proper prototype for class %s. Expected void %s(%s s [,Map m] | ServiceReference r)",
+					rdef.bind, value, component.implementation, value, rdef.interfce);
+		}
+		return null;
+	}
+
+	public void annotation(Annotation annotation) {
+		try {
+			java.lang.annotation.Annotation a = annotation.getAnnotation();
+
+			if (a instanceof Component)
+				doComponent((Component) a, annotation);
+			else if (a instanceof Activate)
+				doActivate();
+			else if (a instanceof Deactivate)
+				doDeactivate();
+			else if (a instanceof Modified)
+				doModified();
+			else if (a instanceof Reference)
+				doReference((Reference) a, annotation);
+
+		} catch (Exception e) {
+			e.printStackTrace();
+			analyzer.error("During generation of a component on class %s, exception %s", clazz, e);
+		}
+	}
+
+	/**
+	 * 
+	 */
+	protected void doDeactivate() {
+		if (!ACTIVATEDESCRIPTOR.matcher(methodDescriptor).matches())
+			analyzer.error(
+					"Deactivate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+					clazz, methodDescriptor);
+		else {
+			component.deactivate = method;
+		}
+	}
+
+	/**
+	 * 
+	 */
+	protected void doModified() {
+		if (!ACTIVATEDESCRIPTOR.matcher(methodDescriptor).matches())
+			analyzer.error(
+					"Modified method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+					clazz, methodDescriptor);
+		else {
+			component.modified = method;
+		}
+	}
+	/**
+	 * @param annotation
+	 * @throws Exception
+	 */
+	protected void doReference(Reference reference, Annotation raw) throws Exception {
+		ReferenceDef def = new ReferenceDef();
+		def.name = reference.name();
+
+		if (def.name == null) {
+			Matcher m = BINDMETHOD.matcher(method);
+			if (m.matches()) {
+				def.name = m.group(2);
+			} else {
+				def.name = method;
+			}
+		}
+
+		def.unbind = reference.unbind();
+		def.bind = method;
+
+		def.interfce = raw.get("service");
+		if (def.interfce != null) {
+			def.interfce = Clazz.objectDescriptorToFQN(def.interfce);
+		} else {
+			// We have to find the type of the current method to
+			// link it to the referenced service.
+			Matcher m = BINDDESCRIPTOR.matcher(methodDescriptor);
+			if (m.matches()) {
+				def.interfce = Clazz.internalToFqn(m.group(3));
+			} else
+				throw new IllegalArgumentException(
+						"Cannot detect the type of a Component Reference from the descriptor: "
+								+ methodDescriptor);
+		}
+
+		// Check if we have a target, this must be a filter
+		def.target = reference.target();
+		if (def.target != null) {
+			Verifier.verifyFilter(def.target, 0);
+		}
+
+		if (component.references.containsKey(def.name))
+			analyzer.error(
+					"In component %s, multiple references with the same name: %s. Previous def: %s, this def: %s",
+					component.implementation, component.references.get(def.name), def.interfce, "");
+		else
+			component.references.put(def.name, def);
+
+		def.cardinality = reference.cardinality();
+		def.policy = reference.policy();
+	}
+
+	/**
+	 * 
+	 */
+	protected void doActivate() {
+		if (!ACTIVATEDESCRIPTOR.matcher(methodDescriptor).matches())
+			analyzer.error(
+					"Activate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+					clazz, methodDescriptor);
+		else {
+			component.activate = method;
+		}
+	}
+
+	/**
+	 * @param annotation
+	 * @throws Exception
+	 */
+	protected void doComponent(Component comp, Annotation annotation) throws Exception {
+
+		// Check if we are doing a super class
+		if (component.implementation != null)
+			return;
+
+		component.version = V1_1;
+		component.implementation = clazz.getFQN();
+		component.name = comp.name();
+		component.factory = comp.factory();
+		component.configurationPolicy = comp.configurationPolicy();
+		if (annotation.get("enabled") != null)
+			component.enabled = comp.enabled();
+		if (annotation.get("factory") != null)
+			component.factory = comp.factory();
+		if (annotation.get("immediate") != null)
+			component.immediate = comp.immediate();
+		if (annotation.get("servicefactory") != null)
+			component.servicefactory = comp.servicefactory();
+
+		String properties[] = comp.properties();
+		if (properties != null)
+			for (String entry : properties)
+				component.properties.add(entry);
+
+		doProperties(comp.property());
+		Object [] x = annotation.get("service");
+		
+		if (x == null) {
+			// Use the found interfaces, but convert from internal to
+			// fqn.
+			if (interfaces != null) {
+				List<String> result = new ArrayList<String>();
+				for (int i = 0; i < interfaces.length; i++) {
+					if (!interfaces[i].equals("scala/ScalaObject"))
+						result.add(Clazz.internalToFqn(interfaces[i]));
+				}
+				component.service = result.toArray(EMPTY);
+			}
+		} else {
+			// We have explicit interfaces set
+			component.service= new String[x.length];
+			for (int i = 0; i < x.length; i++) {
+				component.service[i] = Clazz.objectDescriptorToFQN(x[i].toString());
+			}
+		}
+
+	}
+
+	/**
+	 * Parse the properties
+	 */
+
+	private void doProperties(String[] properties) {
+		if (properties != null) {
+			for (String p : properties) {
+				Matcher m = PROPERTY_PATTERN.matcher(p);
+
+				if (m.matches()) {
+					String key = m.group(1);
+					String value = m.group(4);
+					component.property.add(key, value);
+				} else
+					throw new IllegalArgumentException("Malformed property '" + p
+							+ "' on component: " + className);
+			}
+		}
+	}
+
+	/**
+	 * Are called during class parsing
+	 */
+
+	@Override public void classBegin(int access, String name) {
+		className = name;
+	}
+
+	@Override public void implementsInterfaces(String[] interfaces) {
+		this.interfaces = interfaces;
+	}
+
+	@Override public void method(int access, String name, String descriptor) {
+		if (Modifier.isPrivate(access) || Modifier.isAbstract(access) || Modifier.isStatic(access))
+			return;
+
+		this.method = name;
+		this.methodDescriptor = descriptor;
+		this.methodAccess = access;
+		methods.add(name, descriptor);
+	}
+
+	@Override public void extendsClass(String name) {
+		this.extendsClass = name;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/ComponentDef.java b/bundleplugin/src/main/java/aQute/bnd/component/ComponentDef.java
new file mode 100644
index 0000000..30268a7
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/component/ComponentDef.java
@@ -0,0 +1,132 @@
+package aQute.bnd.component;
+
+import java.util.*;
+
+import org.osgi.service.component.annotations.*;
+
+import aQute.lib.collections.*;
+import aQute.lib.osgi.*;
+import aQute.lib.tag.*;
+import aQute.libg.version.*;
+
+class ComponentDef {
+	final static String				NAMESPACE_STEM	= "http://www.osgi.org/xmlns/scr";
+	Version							version			= new Version("1.1.0");
+	String							name;
+	String							factory;
+	Boolean							immediate;
+	Boolean							servicefactory;
+	ConfigurationPolicy				configurationPolicy;
+	String							implementation;
+	String							service[];
+	String							activate;
+	String							deactivate;
+	String							modified;
+	Boolean							enabled;
+	final List<String>				properties		= new ArrayList<String>();
+	final MultiMap<String, String>	property		= new MultiMap<String, String>();
+	final Map<String, ReferenceDef>	references		= new TreeMap<String, ReferenceDef>();
+
+	void prepare(Analyzer analyzer) {
+
+		for (ReferenceDef ref : references.values()) {
+			ref.prepare(analyzer);
+			if (ref.version.compareTo(version) > 0)
+				version = ref.version;
+		}
+
+		if (implementation == null)
+			analyzer.error("No Implementation defined for component " + name);
+		else
+			analyzer.referTo(implementation);
+
+		name = implementation;
+
+		if (service != null && service.length > 0) {
+			for (String interfaceName : service)
+				analyzer.referTo(interfaceName);
+		} else if (servicefactory != null && servicefactory)
+			analyzer.warning("The servicefactory:=true directive is set but no service is provided, ignoring it");
+	}
+
+	Tag getTag() {
+		Tag component = new Tag("scr:component");
+		component.addAttribute("xmlns:scr", NAMESPACE_STEM + "/" + version);
+		component.addAttribute("name", name);
+
+		if (servicefactory != null)
+			component.addAttribute("servicefactory", servicefactory);
+
+		if (configurationPolicy != null)
+			component.addAttribute("configuration-policy", configurationPolicy.toString()
+					.toLowerCase());
+		if (enabled != null)
+			component.addAttribute("enabled", enabled);
+		if (immediate != null)
+			component.addAttribute("immediate", immediate);
+
+		if (factory != null)
+			component.addAttribute("factory", factory);
+
+		if (activate != null)
+			component.addAttribute("activate", activate);
+
+		if (deactivate != null)
+			component.addAttribute("deactivate", deactivate);
+
+		if (modified != null)
+			component.addAttribute("modified", modified);
+
+		Tag impl = new Tag(component, "implementation");
+		impl.addAttribute("class", implementation);
+
+		if (service != null && service.length != 0) {
+			Tag s = new Tag(component, "service");
+			if (servicefactory != null && servicefactory)
+				s.addAttribute("servicefactory", true);
+
+			for (String ss : service) {
+				Tag provide = new Tag(s, "provide");
+				provide.addAttribute("interface", ss);
+			}
+		}
+
+		for (ReferenceDef ref : references.values()) {
+			Tag refTag = ref.getTag();
+			component.addContent(refTag);
+
+		}
+
+		for (Map.Entry<String, Set<String>> kvs : property.entrySet()) {
+			Tag property = new Tag(component, "property");
+			String name = kvs.getKey();
+			String type = null;
+			int n = name.indexOf(':');
+			if (n > 0) {
+				type = name.substring(n + 1);
+				name = name.substring(0, n);
+			}
+
+			property.addAttribute("name", name);
+			if (type != null) {
+				property.addAttribute("type", type);
+			}
+			StringBuffer sb = new StringBuffer();
+
+			String del = "";
+			for (String v : kvs.getValue()) {
+				sb.append(del);
+				sb.append(v);
+				del = "\n";
+			}
+			property.addContent(sb.toString());
+		}
+
+		for (String entry : properties) {
+			Tag properties = new Tag(component, "properties");
+			properties.addAttribute("entry", entry);
+		}
+		return component;
+	}
+
+}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/DSAnnotations.java b/bundleplugin/src/main/java/aQute/bnd/component/DSAnnotations.java
new file mode 100644
index 0000000..a592377
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/component/DSAnnotations.java
@@ -0,0 +1,25 @@
+package aQute.bnd.component;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+/**
+ * Analyze the class space for any classes that have an OSGi annotation for DS.
+ * 
+ */
+public class DSAnnotations implements AnalyzerPlugin {
+
+	public boolean analyzeJar(Analyzer analyzer) throws Exception {
+
+		for (Clazz c : analyzer.getClassspace().values()) {
+			ComponentDef definition = AnnotationReader.getDefinition(c, analyzer);
+			if (definition != null) {
+				definition.prepare(analyzer);
+				analyzer.getJar().putResource("OSGI-INF/" + definition.name + ".xml",
+						new TagResource(definition.getTag()));
+			}
+		}
+		return false;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java b/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java
new file mode 100644
index 0000000..ca810e6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java
@@ -0,0 +1,98 @@
+package aQute.bnd.component;
+
+import org.osgi.service.component.annotations.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.tag.*;
+import aQute.libg.version.*;
+
+class ReferenceDef {
+	Version					version;
+	String					name;
+	String					interfce;
+	ReferenceCardinality	cardinality;
+	ReferencePolicy			policy;
+	String					target;
+	String					bind;
+	String					unbind;
+	String					modified;
+
+	public void prepare(Analyzer analyzer) {
+		if (name == null)
+			analyzer.error("No name for a reference");
+
+		if (version == null)
+			version = AnnotationReader.V1_1;
+
+	}
+
+	public Tag getTag() {
+		Tag ref = new Tag("reference");
+		ref.addAttribute("name", name);
+		if (cardinality != null)
+			ref.addAttribute("cardinality", p(cardinality));
+		if (policy != null)
+			ref.addAttribute("policy", p(policy));
+
+		if (interfce != null)
+			ref.addAttribute("interface", interfce);
+
+		if (target != null)
+			ref.addAttribute("target", target);
+
+		if (bind != null)
+			ref.addAttribute("bind", bind);
+
+		if (unbind != null)
+			ref.addAttribute("unbind", unbind);
+
+		if (modified != null) {
+			ref.addAttribute("modified", modified);
+			version = max(version, AnnotationReader.V1_2);
+		}
+
+		return ref;
+	}
+
+	private String p(ReferencePolicy policy) {
+		switch(policy) {
+		case DYNAMIC:
+			return "dynamic";
+			
+		case STATIC:
+			return "static";
+		}
+		return policy.toString();
+	}
+
+	private String p(ReferenceCardinality crd) {
+		switch (crd) {
+		case AT_LEAST_ONE:
+			return "1..n";
+
+		case MANDATORY:
+			return "1..1";
+
+		case MULTIPLE:
+			return "0..n";
+
+		case OPTIONAL:
+			return "0..1";
+
+		}
+		return crd.toString();
+	}
+
+	private <T extends Comparable<T>> T max(T a, T b) {
+		int n = a.compareTo(b);
+		if (n >= 0)
+			return a;
+		else
+			return b;
+	}
+
+	public String toString() {
+		return name;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/concurrent/MultiBuilder.java b/bundleplugin/src/main/java/aQute/bnd/concurrent/MultiBuilder.java
new file mode 100644
index 0000000..ad9708d
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/concurrent/MultiBuilder.java
@@ -0,0 +1,141 @@
+package aQute.bnd.concurrent;
+
+import java.io.*;
+import java.util.*;
+
+import aQute.bnd.build.*;
+import aQute.lib.osgi.*;
+import aQute.libg.forker.*;
+
+/**
+ * This class implements a concurrent builder. It manages the build process in
+ * an environment where many threads can initiate builds. Users should call
+ * changed(Project,boolean)
+ * 
+ */
+public class MultiBuilder {
+	Workspace		workspace;
+	Forker<Project>	forker;
+	boolean			building		= false;
+	final Set<File>	filesChanged	= Collections.synchronizedSet(new HashSet<File>());
+
+	/**
+	 * Constructor
+	 * 
+	 * @param workspace
+	 *            the workspace this MultiBuilder works for.
+	 * 
+	 */
+	public MultiBuilder(Workspace workspace) {
+		this.workspace = workspace;
+	}
+
+	/**
+	 * Return the build result of a project.
+	 * 
+	 * @param p
+	 *            the project
+	 * @return the files build by the project
+	 * 
+	 * @throws Exception
+	 */
+	public File[] build(Project p) throws Exception {
+		if (p.isStale()) {
+			startBuild();
+		}
+		syncBuild();
+		return p.build();
+	}
+
+	/**
+	 * Indicate that the project has changed. This will start a build.
+	 * 
+	 * @param p
+	 *            the project that is changed
+	 * @throws Exception
+	 */
+	public void changed(Project p) throws Exception {
+		p.setChanged();
+		cancel();
+		startBuild();
+	}
+
+	/**
+	 * Cancel the current build or do nothing if no build is active.
+	 * 
+	 * @throws InterruptedException
+	 */
+	public synchronized void cancel() throws InterruptedException {
+		if (building) {
+			forker.cancel();
+		}
+	}
+
+	/**
+	 * Synchronize with a current build or return immediately.
+	 * 
+	 * @throws InterruptedException
+	 */
+	public synchronized void syncBuild() throws InterruptedException {
+		if (building) {
+			forker.join();
+		}
+	}
+
+	/**
+	 * Schedule a new build if no build is running otherwise return.
+	 * 
+	 * @throws Exception
+	 */
+	public void startBuild() throws Exception {
+		synchronized (this) {
+			if (building)
+				return;
+
+			forker = new Forker<Project>(Processor.getExecutor());
+			building = true;
+		}
+
+		Processor.getExecutor().execute(new Runnable() {
+			public void run() {
+				try {
+					build();
+					synchronized (MultiBuilder.this) {
+						building = false;
+					}
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		});
+	}
+
+	/**
+	 * Do the whole build using a forker.
+	 * 
+	 * @throws Exception
+	 */
+	private void build() throws Exception {
+		// handle multiple requests
+		Thread.sleep(100);
+		workspace.bracket(true);
+		try {
+			for (final Project p : workspace.getAllProjects()) {
+				forker.doWhen(p.getDependson(), p, new Runnable() {
+
+					public void run() {
+						try {
+							p.build();
+						} catch (Exception e) {
+							e.printStackTrace();
+						}
+					}
+				});
+			}
+			forker.join();
+		} finally {
+			workspace.bracket(false);
+		}
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/help/Errors.java b/bundleplugin/src/main/java/aQute/bnd/help/Errors.java
new file mode 100644
index 0000000..1d950ad
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/help/Errors.java
@@ -0,0 +1,5 @@
+package aQute.bnd.help;
+
+public interface Errors {
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/help/Syntax.java b/bundleplugin/src/main/java/aQute/bnd/help/Syntax.java
new file mode 100644
index 0000000..20a7440
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/help/Syntax.java
@@ -0,0 +1,481 @@
+package aQute.bnd.help;
+
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.lib.osgi.*;
+
+public class Syntax implements Constants {
+    final String                            header;
+    final String                            lead;
+    final String                            example;
+    final Pattern                           pattern;
+    final String                            values;
+    final Syntax[]                          children;
+
+    static Syntax                           version              = new Syntax(
+                                                                         VERSION_ATTRIBUTE,
+                                                                         "A version range to select the version of an export definition. The default value is 0.0.0 .",
+                                                                         "version=\"[1.2,3.0)\"",
+                                                                         null,
+                                                                         Verifier.VERSIONRANGE);
+    static Syntax                           bundle_symbolic_name = new Syntax(
+                                                                         BUNDLE_SYMBOLIC_NAME_ATTRIBUTE,
+                                                                         "The bundle symbolic name of the exporting bundle.",
+                                                                         "bundle-symbolic-name=com.acme.foo.daffy",
+                                                                         null,
+                                                                         Verifier.SYMBOLICNAME);
+
+    static Syntax                           bundle_version       = new Syntax(
+                                                                         BUNDLE_VERSION_ATTRIBUTE,
+                                                                         "a version range to select the bundle version of the exporting bundle. The default value is 0.0.0.",
+                                                                         "bundle-version=1.3",
+                                                                         null,
+                                                                         Verifier.VERSIONRANGE);
+
+    static Syntax                           path_version         = new Syntax(
+                                                                         VERSION_ATTRIBUTE,
+                                                                         "Specifies the range in the repository, project, or file",
+                                                                         "version=project",
+                                                                         "project,type",
+                                                                         Pattern
+                                                                                 .compile("project|type|"
+                                                                                         + Verifier.VERSIONRANGE
+                                                                                                 .toString()));
+
+    @SuppressWarnings("deprecation")
+	static Syntax[]                         syntaxes             = new Syntax[] {
+            new Syntax(
+                    BUNDLE_ACTIVATIONPOLICY,
+                    "The Bundle-ActivationPolicy specifies how the framework should activate the bundle once started. ",
+                    "Bundle-ActivationPolicy: lazy", "lazy", Pattern
+                            .compile("lazy")),
+
+            new Syntax(
+                    BUNDLE_ACTIVATOR,
+                    "The Bundle-Activator header specifies the name of the class used to start and stop the bundle. ",
+                    "Bundle-Activator: com.acme.foo.Activator",
+                    "${classes;implementing;org.osgi.framework.BundleActivator}",
+                    Verifier.FQNPATTERN),
+            new Syntax(
+                    BUNDLE_CATEGORY,
+                    "The Bundle-Category header holds a comma-separated list of category names",
+                    "Bundle-Category: test",
+                    "osgi,test,game,util,eclipse,netbeans,jdk,specification",
+                    null),
+            new Syntax(
+                    BUNDLE_CLASSPATH,
+                    "The Bundle-ClassPath header defines a comma-separated list of JAR file path names or directories (inside the bundle) containing classes and resources. The period (’.’) specifies the root directory of the bundle’s JAR. The period is also the default.",
+                    "Bundle-Classpath: /lib/libnewgen.so, .", null,
+                    Verifier.PATHPATTERN),
+            new Syntax(
+                    BUNDLE_CONTACTADDRESS,
+                    "The Bundle-ContactAddress header provides the contact address of the vendor. ",
+                    "Bundle-ContactAddress: 2400 Oswego Road, Austin, TX 74563",
+                    null, null),
+            new Syntax(
+                    BUNDLE_COPYRIGHT,
+                    "The Bundle-Copyright header contains the copyright specification for this bundle. ",
+                    "Bundle-Copyright: OSGi (c) 2002", null, null),
+            new Syntax(
+                    BUNDLE_DESCRIPTION,
+                    "The Bundle-Description header defines a short description of this bundle.",
+                    "Bundle-Description: Ceci ce n'est pas une bundle", null,
+                    null),
+
+            new Syntax(
+                    BUNDLE_DOCURL,
+                    "The Bundle-DocURL headers must contain a URL pointing to documentation about this bundle.",
+                    "Bundle-DocURL: http://www.aQute.biz/Code/Bnd", null,
+                    Verifier.URLPATTERN),
+
+            new Syntax(
+                    BUNDLE_ICON,
+                    "The optional Bundle-Icon header provides a list of (relative) URLs to icons representing this bundle in different sizes. ",
+                    "Bundle-Icon: /icons/bnd.png;size=64", "/icons/bundle.png",
+                    Verifier.URLPATTERN, new Syntax("size",
+                            "Icons size in pixels, e.g. 64", "64",
+                            "16,32,48,64,128", Verifier.NUMBERPATTERN)),
+
+            new Syntax(
+                    BUNDLE_LICENSE,
+                    "The Bundle-License header provides an optional machine readable form of license information. The purpose of this header is to automate some of the license processing required by many organizations",
+                    "Bundle License: http://www.opensource.org/licenses/jabberpl.php",
+                    "http://www.apache.org/licenses/LICENSE-2.0,<<EXTERNAL>>",
+                    Pattern.compile("(" + Verifier.URLPATTERN
+                            + "|<<EXTERNAL>>)"), new Syntax(
+                            DESCRIPTION_ATTRIBUTE,
+                            "Human readable description of the license",
+                            "description=\"Described the license here\"", null,
+                            Verifier.ANYPATTERN), new Syntax(LINK_ATTRIBUTE,
+                            "", "", null, Verifier.URLPATTERN)),
+            new Syntax(
+                    BUNDLE_LOCALIZATION,
+                    "The Bundle-Localization header contains the location in the bundle where localization files can be found. The default value is OSGI-INF/l10n/bundle. Translations are by default therefore OSGI-INF/l10n/bundle_de.properties, OSGI-INF/l10n/bundle_nl.properties, etc.",
+                    "Bundle-Localization: OSGI-INF/l10n/bundle",
+                    "OSGI-INF/l10n/bundle", Verifier.URLPATTERN),
+            new Syntax(
+                    BUNDLE_MANIFESTVERSION,
+                    "This header is set by bnd automatically to 2. The Bundle-ManifestVersion header defines that the bundle follows the rules of this specification. The Bundle-ManifestVersion header determines whether the bundle follows the rules of this specification.",
+                    "# Bundle-ManifestVersion: 2", "2", Verifier.NUMBERPATTERN),
+            new Syntax(
+                    BUNDLE_NAME,
+                    "This header will be derived from the  Bundle-SymbolicName if not set. The Bundle-Name header defines a readable name for this bundle. This should be a short, human-readable name that can contain spaces.",
+                    "Bundle-Name: My Bundle", null, Verifier.ANYPATTERN),
+            new Syntax(
+                    BUNDLE_NATIVECODE,
+                    "The Bundle-NativeCode header contains a specification of native code libraries contained in this bundle. ",
+                    "Bundle-NativeCode: /lib/http.DLL; osname = QNX; osversion = 3.1",
+                    null,
+                    Verifier.PATHPATTERN,
+                    new Syntax(OSNAME_ATTRIBUTE,
+                            "The name of the operating system", "osname=MacOS",
+                            Processor.join(Verifier.OSNAMES, ","),
+                            Verifier.ANYPATTERN),
+                    new Syntax(OSVERSION_ATTRIBUTE, "Operating System Version",
+                            "osversion=3.1", null, Verifier.ANYPATTERN),
+                    new Syntax(LANGUAGE_ATTRIBUTE, "Language ISO 639 code",
+                            "language=nl", null, Verifier.ISO639),
+                    new Syntax(PROCESSOR_ATTRIBUTE, "Processor name",
+                            "processor=x86", Processor.join(
+                                    Verifier.PROCESSORNAMES, ","),
+                            Verifier.ANYPATTERN),
+                    new Syntax(
+                            SELECTION_FILTER_ATTRIBUTE,
+                            "The value of this attribute must be a filter expression that indicates if the native code clause should be selected or not.",
+                            "selection-filter=\"(com.acme.windowing=win32)\"",
+                            null, Verifier.FILTERPATTERN)),
+            new Syntax(
+                    BUNDLE_REQUIREDEXECUTIONENVIRONMENT,
+                    "The Bundle-RequiredExecutionEnvironment contains a comma-separated list of execution environments that must be present on the Service Platform.",
+                    "Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0",
+                    Processor.join(Verifier.EES, ","), Verifier.ANYPATTERN),
+
+            new Syntax(
+                    BUNDLE_SYMBOLICNAME,
+                    "The Bundle-SymbolicName header specifies a non-localizable name for this bundle. The bundle symbolic name together with a version must identify a  unique bundle. The bundle symbolic name should be based on the reverse  domain name convention",
+                    "Bundle-SymbolicName: com.acme.foo.daffy;singleton:=true",
+                    "${p}",
+                    Verifier.SYMBOLICNAME,
+                    new Syntax(
+                            SINGLETON_DIRECTIVE,
+                            " Indicates that the bundle can only have  a single version resolved.  A value of true indicates that the bundle is a singleton bundle. The default value is false. The Framework must resolve at most one  bundle when multiple versions of a singleton bundle with the same symbolic name are installed. Singleton bundles do not affect the resolution of non-singleton bundles with the same symbolic name.",
+                            "false", "true,false", Verifier.TRUEORFALSEPATTERN),
+                    new Syntax(
+                            FRAGMENT_ATTACHMENT_DIRECTIVE,
+                            "Defines how fragments are allowed to be attached, see the fragments in Fragment Bundles on page73. The following values are valid for this directive:",
+                            "", "always|never|resolve-time", Pattern
+                                    .compile("always|never|resolve-time")),
+                    new Syntax(BLUEPRINT_WAIT_FOR_DEPENDENCIES_ATTRIBUTE, "",
+                            "", "true,false", Verifier.TRUEORFALSEPATTERN),
+                    new Syntax(BLUEPRINT_TIMEOUT_ATTRIBUTE, "", "",
+                            "30000,60000,300000", Verifier.NUMBERPATTERN)),
+
+            new Syntax(
+                    BUNDLE_UPDATELOCATION,
+                    "The Bundle-UpdateLocation header specifies a URL where an update for this bundle should come from. If the bundle is updated, this location should be used, if present, to retrieve the updated JAR file.",
+                    "Bundle-UpdateLocation: http://www.acme.com/Firewall/bundle.jar",
+                    null, Verifier.URLPATTERN),
+
+            new Syntax(
+                    BUNDLE_VENDOR,
+                    "The Bundle-Vendor header contains a human-readable description of the bundle vendor. ",
+                    "Bundle-Vendor: OSGi Alliance ", null, null),
+
+            new Syntax(
+                    BUNDLE_VERSION,
+                    "The Bundle-Version header specifies the version of this bundle",
+                    "Bundle-Version: 1.23.4.build200903221000", null,
+                    Verifier.VERSION),
+
+            new Syntax(
+                    DYNAMICIMPORT_PACKAGE,
+                    "The DynamicImport-Package header contains a comma-separated list of package names that should be dynamically imported when needed.",
+                    "DynamicImport-Package: com.acme.plugin.*", "",
+                    Verifier.WILDCARDNAMEPATTERN, version,
+                    bundle_symbolic_name, bundle_version),
+
+            new Syntax(
+                    EXPORT_PACKAGE,
+                    "The Export-Package header contains a declaration of exported packages.",
+                    "Export-Package: org.osgi.util.tracker;version=1.3",
+                    "${packages}",
+                    null,
+                    new Syntax(
+                            NO_IMPORT_DIRECTIVE,
+                            "By default, bnd makes all exports also imports. Adding a -noimport to an exported package will make it export only",
+                            "-noimport:=true", "true,false",
+                            Verifier.TRUEORFALSEPATTERN),
+                    new Syntax(
+                            USES_DIRECTIVE,
+                            "Calculated by bnd: It is a comma-separated list of package names that are used by the exported package",
+                            "Is calculated by bnd", null, null),
+                    new Syntax(
+                            MANDATORY_DIRECTIVE,
+                            "A comma-separated list of attribute names. Note that the use of a comma in the value requires it to be enclosed in double quotes. A bundle importing the package must specify the mandatory attributes, with a value that matches, to resolve to the exported package",
+                            "mandatory=\"bar,foo\"", null, null),
+                    new Syntax(
+                            INCLUDE_DIRECTIVE,
+                            "A comma-separated list of class names that must be visible to an importer",
+                            "include:=\"Qux*\"", null, null),
+                    new Syntax(
+                            EXCLUDE_DIRECTIVE,
+                            "A comma-separated list of class names that must not be visible to an importer",
+                            "exclude:=\"QuxImpl*,BarImpl\"", null,
+                            Verifier.WILDCARDNAMEPATTERN), new Syntax(
+                            IMPORT_DIRECTIVE, "Experimental", "", null, null)
+
+            ),
+            new Syntax(EXPORT_SERVICE, "Deprecated",
+                    "Export-Service: org.osgi.service.log.LogService ",
+                    "${classes;implementing;*}", null),
+            new Syntax(
+                    FRAGMENT_HOST,
+                    "The Fragment-Host header defines the host bundle for this fragment.",
+                    "Fragment-Host: org.eclipse.swt; bundle-version=\"[3.0.0,4.0.0)\"",
+                    null,
+                    null,
+                    new Syntax(
+                            EXTENSION_DIRECTIVE,
+                            " Indicates this extension is a system or boot class path extension. It is only applicable when the Fragment-Host is the System Bundle",
+                            "extension:=framework", "framework,bootclasspath",
+                            Pattern.compile("framework|bootclasspath")),
+                    bundle_version),
+            new Syntax(
+                    IMPORT_PACKAGE,
+                    "This header is normally calculated by bnd, however, you can decorate packages or skip packages. The Import-Package header declares the imported packages for this bundle",
+                    "Import-Package: !com.exotic.*, com.acme.foo;vendor=ACME, *",
+                    "${exported_packages}",
+                    Verifier.WILDCARDNAMEPATTERN,
+                    new Syntax(
+                            REMOVE_ATTRIBUTE_DIRECTIVE,
+                            "Remove the given attributes from matching imported packages",
+                            "-remove-attribute:=foo.*", null,
+                            Verifier.WILDCARDNAMEPATTERN),
+                    new Syntax(
+                            RESOLUTION_DIRECTIVE,
+                            "Indicates that the packages must be resolved if the value is mandatory, which is the default. If mandatory packages cannot be resolved, then the bundle must fail to resolve. A value of optional indicates that the packages are optional",
+                            "resolution:=optional", "mandatory,optional",
+                            Pattern.compile("mandatory|optional")
+
+                    ), version, bundle_symbolic_name, bundle_version),
+
+            new Syntax(
+                    REQUIRE_BUNDLE,
+                    "The Require-Bundle header specifies the required exports from another bundle.",
+                    "Require-Bundle: com.acme.chess",
+                    null,
+                    Verifier.WILDCARDNAMEPATTERN,
+
+                    new Syntax(
+                            VISIBILITY_DIRECTIVE,
+                            " If the value is private (Default), then all visible packages from the required bundles are not re-exported. If the value is reexport then bundles that require this bundle will transitively have access to these required bundle’s exported packages.",
+                            "visibility:=private", "private,reexport", Pattern
+                                    .compile("private|reexport")),
+
+                    new Syntax(
+                            RESOLUTION_DIRECTIVE,
+                            "If the value is mandatory (default) then the required bundle must exist for this bundle to resolve. If the value is optional, the bundle will resolve even if the required bundle does not exist.",
+                            "resolution:=optional", "mandatory,optional",
+                            Pattern.compile("mandatory|optional")),
+
+                    new Syntax(
+                            SPLIT_PACKAGE_DIRECTIVE,
+                            "Indicates how an imported package should be merged when it is split between different exporters. The default is merge-first with warning",
+                            "-split-package:=merge-first",
+                            "merge-first,merge-last,error,first",
+                            Pattern
+                                    .compile("merge-first|merge-last|error|first")),
+                    bundle_version
+
+            ),
+            new Syntax(
+                    BUILDPATH,
+                    "Provides the class path for building the jar. The entries are references to the repository",
+                    "-buildpath=osgi;version=4.1", "${repo;bsns}",
+                    Verifier.SYMBOLICNAME, path_version),
+            new Syntax(
+                    BUMPPOLICY,
+                    "Sets the version bump policy. This is a parameter to the ${version} macro.",
+                    "-bumppolicy==+0", "==+,=+0,+00", Pattern
+                            .compile("[=+-0][=+-0][=+-0]")),
+
+            new Syntax(
+                    CONDUIT,
+                    "Allows a bnd file to point to files which will be returned when the bnd file is build",
+                    "-conduit= jar/osgi.jar", null, null),
+
+            new Syntax(
+                    DEPENDSON,
+                    "List of project names that this project directly depends on. These projects are always build ahead of this project",
+                    "-dependson=org.acme.cm", "${projects}", null),
+
+            new Syntax(DEPLOYREPO,
+                    "Specifies to which repo the project should be deployed.",
+                    "-deployrepo=cnf", "${repos}", null),
+
+            new Syntax(
+                    DONOTCOPY,
+                    "Regular expression for names of files and directories that should not be copied when discovered",
+                    "-donotcopy=(CVS|\\.svn)", null, null),
+
+            new Syntax(
+                    EXPORT_CONTENTS,
+                    "Build the JAR in the normal way but use this header for the Export-Package header manifest generation, same format",
+                    "-exportcontents=!*impl*,*;version=3.0", null, null),
+
+            new Syntax(
+                    FAIL_OK,
+                    "Return with an ok status (0) even if the build generates errors",
+                    "-failok=true", "true,false", Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(
+                    INCLUDE,
+                    "Include files. If an entry starts with '-', it does not have to exist. If it starts with '~', it must not overwrite any existing properties",
+                    "-include: -${java.user}/.bnd", null, null),
+
+            new Syntax(
+                    INCLUDERESOURCE,
+                    "Include resources from the file system. You can specify a directory, or file. All files are copied to the root, unless a destination directory is indicated",
+                    "-includeresource: lib=jar", null, null),
+
+            new Syntax(
+                    MAKE,
+                    "Set patterns for make plugins. These patterns are used to find a plugin that can make a resource that can not be found.",
+                    "-make: (*).jar;type=bnd;  recipe=\"bnd/$1.bnd\"", null,
+                    null, new Syntax("type", "Type name for plugin",
+                            "type=bnd", "bnd", null), new Syntax("recipe",
+                            "Recipe for the plugin, can use back references",
+                            "recipe=\"bnd/$1.bnd\"", "bnd", null)),
+
+            new Syntax(
+                    MANIFEST,
+                    "Directly include a manifest, do not use the calculated manifest",
+                    "-manifest = META-INF/MANIFEST.MF", null, null),
+
+            new Syntax(NOEXTRAHEADERS, "Do not generate housekeeping headers",
+                    "-noextraheaders", "true,false",
+                    Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(NOUSES,
+                    "Do not calculate the uses: directive on exports",
+                    "-nouses=true", "true,false", Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(NOPE,
+                    "Deprecated, use -nobundles. ",
+                    "-nope=true", "true,false", Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(
+                    PEDANTIC,
+                    "Warn about things that are not really wrong but still not right",
+                    "-nope=true", "true,false", Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(
+                    PLUGIN,
+                    "Define the plugins",
+                    "-plugin=aQute.lib.spring.SpringComponent,aQute.lib.deployer.FileRepo;location=${repo}",
+                    null, null),
+
+            new Syntax(SERVICE_COMPONENT,
+                    "The header for Declarative Services",
+                    "Service-Component=com.acme.Foo?;activate='start'", null,
+                    null),
+
+            new Syntax(POM, "Generate a maven pom", "-pom=true", "true,false",
+                    Verifier.TRUEORFALSEPATTERN),
+
+            new Syntax(RELEASEREPO,
+                    "Specifies to which repo the project should be released.",
+                    "-releaserepo=cnf", "${repos}", null),
+
+            new Syntax(REMOVEHEADERS,
+                    "Remove all headers that match the regular expressions",
+                    "-removeheaders=FOO_.*,Proprietary", null, null),
+            new Syntax(
+                    RESOURCEONLY,
+                    "Normally bnd warns when the JAR does not contain any classes, this option suppresses this warning",
+                    "-resourceonly=true", "true,false",
+                    Verifier.TRUEORFALSEPATTERN),
+            new Syntax(SOURCES, "Include sources in the jar", "-sources=true",
+                    "true,false", Verifier.TRUEORFALSEPATTERN),
+            new Syntax(
+                    SOURCEPATH,
+                    "List of directory names that used to source sources for -sources",
+                    "-sourcepath:= src, test", null, null),
+            new Syntax(
+                    SUB,
+                    "Build a set of bnd files that use this bnd file as a basis. The list of bnd file can be specified with wildcards",
+                    "-sub=com.acme.*.bnd", null, null),
+            new Syntax(
+                    RUNPROPERTIES,
+                    "Properties that are set as system properties before the framework is started",
+                    "-runproperties= foo=3, bar=4", null, null),
+            new Syntax(RUNSYSTEMPACKAGES,
+                    "Add additional system packages to a framework run",
+                    "-runsystempackages=com.acme.foo,javax.management", null,
+                    null),
+            new Syntax(
+                    RUNBUNDLES,
+                    "Add additional bundles, specified with their bsn and version like in -buildpath, that are started before the project is run",
+                    "-runbundles=osgi;version=\"[4.1,4.2)\", junit.junit, com.acme.foo;version=project",
+                    null, Verifier.SYMBOLICNAME, path_version),
+            new Syntax(
+                    RUNPATH,
+                    "Additional JARs for the VM path, should include the framework",
+                    "-runpath=org.eclipse.osgi;version=3.5", null, null,
+                    path_version),
+            new Syntax(
+                    RUNVM,
+                    "Additional arguments for the VM invokation. Keys that start with a - are added as options, otherwise they are treated as -D properties for the VM",
+                    "-runvm=-Xmax=30", null, null),
+            new Syntax(
+                    VERSIONPOLICY,
+                    "Provides a version policy to imports that are calculated from exports",
+                    "-versionpolicy = \"[${version;==;${@}},${version;+;${@}})\"",
+                    null, null)
+
+                                                                 };
+
+    public final static Map<String, Syntax> HELP                 = new HashMap<String, Syntax>();
+
+    static {
+        for (Syntax s : syntaxes) {
+            HELP.put(s.header, s);
+        }
+    }
+
+    public Syntax(String header, String lead, String example, String values,
+            Pattern pattern, Syntax... children) {
+        this.header = header;
+        this.children = children;
+        this.lead = lead;
+        this.example = example;
+        this.values = values;
+        this.pattern = pattern;
+    }
+
+    public String getLead() {
+        return lead;
+    }
+
+    public String getExample() {
+        return example;
+    }
+
+    public String getValues() {
+        return values;
+    }
+
+    public String getPattern() {
+        return lead;
+    }
+
+    public Syntax[] getChildren() {
+        return children;
+    }
+
+    public String getHeader() {
+        return header;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/help/Warnings.java b/bundleplugin/src/main/java/aQute/bnd/help/Warnings.java
new file mode 100644
index 0000000..f2dddc4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/help/Warnings.java
@@ -0,0 +1,5 @@
+package aQute.bnd.help;
+
+public interface Warnings {
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/help/packageinfo b/bundleplugin/src/main/java/aQute/bnd/help/packageinfo
new file mode 100644
index 0000000..a4f1546
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/help/packageinfo
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/Make.java b/bundleplugin/src/main/java/aQute/bnd/make/Make.java
new file mode 100644
index 0000000..6827c6d
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/Make.java
@@ -0,0 +1,99 @@
+package aQute.bnd.make;
+
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+public class Make {
+    Builder                               builder;
+    Map<Instruction, Map<String, String>> make;
+
+    public Make(Builder builder) {
+        this.builder = builder;
+    }
+
+    public Resource process(String source) {
+        Map<Instruction, Map<String, String>> make = getMakeHeader();
+        builder.trace("make " + source);
+
+        for (Map.Entry<Instruction, Map<String, String>> entry : make
+                .entrySet()) {
+            Instruction instr = entry.getKey();
+            Matcher m = instr.getMatcher(source);
+            if (m.matches() || instr.isNegated()) {
+                Map<String, String> arguments = replace(m, entry.getValue());
+                List<MakePlugin> plugins = builder.getPlugins(MakePlugin.class);
+                for (MakePlugin plugin : plugins) {
+                    try {
+                        Resource resource = plugin.make(builder,
+                                source, arguments);
+                        if (resource != null) {
+                            builder.trace("Made " + source + " from args "
+                                    + arguments + " with " + plugin);
+                            return resource;
+                        }
+                    } catch (Exception e) {
+                        builder.error("Plugin " + plugin
+                                + " generates error when use in making "
+                                + source + " with args " + arguments, e);
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    private Map<String, String> replace(Matcher m, Map<String, String> value) {
+        Map<String, String> newArgs = Processor.newMap();
+        for (Map.Entry<String, String> entry : value.entrySet()) {
+            String s = entry.getValue();
+            s = replace(m, s);
+            newArgs.put(entry.getKey(), s);
+        }
+        return newArgs;
+    }
+
+    String replace(Matcher m, CharSequence s) {
+        StringBuffer sb = new StringBuffer();
+        int max = '0' + m.groupCount() + 1;
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            if (c == '$' && i < s.length() - 1) {
+                c = s.charAt(++i);
+                if (c >= '0' && c <= max) {
+                    int index = c - '0';
+                    String replacement = m.group(index);
+                    if (replacement != null)
+                        sb.append(replacement);
+                } else {
+                    if (c == '$')
+                        i++;
+                    sb.append(c);
+                }
+            } else
+                sb.append(c);
+        }
+        return sb.toString();
+    }
+
+    Map<Instruction, Map<String, String>> getMakeHeader() {
+        if (make != null)
+            return make;
+        make = Processor.newMap();
+
+        String s = builder.getProperty(Builder.MAKE);
+        Map<String, Map<String, String>> make = builder.parseHeader(s);
+        for (Iterator<Map.Entry<String, Map<String, String>>> e = make
+                .entrySet().iterator(); e.hasNext();) {
+            Map.Entry<String, Map<String, String>> entry = e.next();
+            String pattern = Processor.removeDuplicateMarker(entry.getKey());
+            
+            Instruction instr = Instruction.getPattern(pattern);
+            this.make.put(instr, entry.getValue());
+        }
+
+        return this.make;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java b/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java
new file mode 100644
index 0000000..f2e90d8
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java
@@ -0,0 +1,65 @@
+package aQute.bnd.make;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.build.*;
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+public class MakeBnd implements MakePlugin, Constants {
+    final static Pattern JARFILE = Pattern.compile("(.+)\\.(jar|ipa)");
+
+    public Resource make(Builder builder, String destination,
+            Map<String, String> argumentsOnMake) throws Exception {
+        String type = (String) argumentsOnMake.get("type");
+        if (!"bnd".equals(type))
+            return null;
+
+        String recipe = (String) argumentsOnMake.get("recipe");
+        if (recipe == null) {
+            builder.error("No recipe specified on a make instruction for "
+                    + destination);
+            return null;
+        }
+        File bndfile = builder.getFile(recipe);
+        if (bndfile.isFile()) {
+            // We do not use a parent because then we would
+            // build ourselves again. So we can not blindly
+            // inherit the properties.
+            Builder bchild = builder.getSubBuilder();
+            bchild.removeBundleSpecificHeaders();
+            
+            // We must make sure that we do not include ourselves again!
+            bchild.setProperty(Analyzer.INCLUDE_RESOURCE, "");
+            bchild.setProperty(Analyzer.INCLUDERESOURCE, "");
+            bchild.setProperties(bndfile, builder.getBase());
+            
+            Jar jar = bchild.build();
+            Jar dot = builder.getTarget();
+
+            if (builder.hasSources()) {
+                for (String key : jar.getResources().keySet()) {
+                    if (key.startsWith("OSGI-OPT/src"))
+                        dot.putResource(key, (Resource) jar.getResource(key));
+                }
+            }
+            builder.getInfo(bchild, bndfile.getName() +": ");
+            String debug = bchild.getProperty(DEBUG);
+            if (Processor.isTrue(debug)) {
+                if ( builder instanceof ProjectBuilder ) {
+                    ProjectBuilder pb = (ProjectBuilder) builder;
+                    File target = pb.getProject().getTarget();
+                    String bsn = bchild.getBsn();
+                    File output = new File(target, bsn+".jar");
+                    jar.write(output);
+                    pb.getProject().getWorkspace().changedFile(output);
+                }
+            }
+            return new JarResource(jar);
+        } else
+            return null;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java b/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java
new file mode 100644
index 0000000..3d5e4c8
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java
@@ -0,0 +1,45 @@
+package aQute.bnd.make;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+
+public class MakeCopy implements MakePlugin {
+
+    public Resource make(Builder builder, String destination,
+            Map<String, String> argumentsOnMake) throws Exception {
+        String type = argumentsOnMake.get("type");
+        if (!type.equals("copy"))
+            return null;
+
+        String from = argumentsOnMake.get("from");
+        if (from == null) {
+            String content = argumentsOnMake.get("content");
+            if (content == null)
+                throw new IllegalArgumentException(
+                        "No 'from' or 'content' field in copy "
+                                + argumentsOnMake);
+            return new EmbeddedResource(content.getBytes("UTF-8"),0);
+        } else {
+
+            File f = builder.getFile(from);
+            if (f.isFile())
+                return new FileResource(f);
+            else {
+                try {
+                    URL url = new URL(from);
+                    return new URLResource(url);
+                } catch(MalformedURLException mfue) {
+                    // We ignore this
+                }
+                throw new IllegalArgumentException(
+                        "Copy source does not exist " + from
+                                + " for destination " + destination);
+            }
+        }
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java b/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java
new file mode 100644
index 0000000..2775a57
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java
@@ -0,0 +1,165 @@
+package aQute.bnd.make.calltree;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+
+/**
+ * Create an XML call tree of a set of classes. The structure of the XML is:
+ * 
+ * <pre>
+ *    calltree ::= &lt;using&gt; &lt;usedby&gt;
+ *    using    ::= &lt;method&gt; *
+ *    usedby   ::= &lt;method&gt; *
+ *    method   ::= &lt;ref&gt; 
+ * </pre>
+ * 
+ * The <code>using</code> element contains methods in the set of classes and
+ * their references. The <code>usedby</code> element contains the used methods
+ * and their references to the set of classes. The <code>ref</code> element
+ * contains the class, the method name, the descriptor, and a pretty print
+ * version of the method.
+ * 
+ * The XML does not contain an XML processor instruction to make it easier to
+ * include in other XML. The encoding is always UTF-8.
+ * 
+ * This class can be used as a resource, just add it to a JAR and the data is
+ * generated when the resource is written (saving time when the JAR is up to
+ * date and does not have to be generated). However, the actual write method is
+ * a static method and can be called as well:
+ * {@link #writeCalltree(PrintWriter, Collection)}.
+ */
+public class CalltreeResource extends WriteResource {
+    Collection<Clazz> classes;
+
+    /**
+     * Create a resource for inclusion that will print a call tree.
+     * 
+     * @param values the classes for which the call tree is generated.
+     */
+    public CalltreeResource(Collection<Clazz> values) {
+        this.classes = values;
+        System.out.println(values);
+    }
+
+    /**
+     * We set the last modified to 0 so this resource does not force
+     * a new JAR if all other resources are up to date.
+     */
+    public long lastModified() {
+        return 0;
+    }
+
+    /**
+     * The write method is called to write the resource. We just call the static
+     * method.
+     */
+    public void write(OutputStream out) throws Exception {
+        OutputStreamWriter osw = new OutputStreamWriter(out, Constants.DEFAULT_CHARSET);
+        PrintWriter pw = new PrintWriter(osw);
+        try {
+            writeCalltree(pw, classes);
+        } finally {
+            pw.flush();
+        }
+    }
+
+    /**
+     * Print the call tree in XML.
+     * 
+     * @param out The output writer
+     * @param classes The set of classes
+     * @throws IOException Any errors
+     */
+    public static void writeCalltree(PrintWriter out, Collection<Clazz> classes)
+            throws Exception {
+
+        final Map<Clazz.MethodDef, Set<Clazz.MethodDef>> using = new TreeMap<Clazz.MethodDef, Set<Clazz.MethodDef>>();
+        final Map<Clazz.MethodDef, Set<Clazz.MethodDef>> usedby = new TreeMap<Clazz.MethodDef, Set<Clazz.MethodDef>>();
+
+        ClassDataCollector cd = new ClassDataCollector() {
+            Clazz.MethodDef source;
+
+            // Before a method is parsed
+            public void method(Clazz.MethodDef source) {
+                this.source = source;
+                xref(using, source, null);
+                xref(usedby, source, null);
+            }
+
+            // For any reference in the previous method.
+            public void reference(Clazz.MethodDef reference) {
+                xref(using, source, reference);
+                xref(usedby, reference, source);
+            }
+        };
+        for (Clazz clazz : classes) {
+            clazz.parseClassFileWithCollector(cd);
+        }
+
+        out.println("<calltree>");
+        xref(out, "using", using);
+        xref(out, "usedby", usedby);
+        out.println("</calltree>");
+    }
+
+    /*
+     * Add a new reference
+     */
+    private static void xref(
+            Map<Clazz.MethodDef, Set<Clazz.MethodDef>> references,
+            Clazz.MethodDef source, Clazz.MethodDef reference) {
+        Set<Clazz.MethodDef> set = references.get(source);
+        if (set == null)
+            references.put(source, set=new TreeSet<Clazz.MethodDef>());
+        if ( reference != null)
+            set.add(reference);
+    }
+
+    /*
+     * Print out either using or usedby sets
+     */
+    private static void xref(PrintWriter out, String group,
+            Map<Clazz.MethodDef, Set<Clazz.MethodDef>> references) {
+        out.println("  <" + group + ">");
+        for (Map.Entry<Clazz.MethodDef, Set<Clazz.MethodDef>> entry : references
+                .entrySet()) {
+            Clazz.MethodDef source = entry.getKey();
+            Set<Clazz.MethodDef> refs = entry.getValue();
+            method(out, "method", source, ">");
+            for (Clazz.MethodDef ref : refs) {
+                method(out, "ref", ref, "/>");
+            }
+            out.println("      </method>");
+        }
+        out.println("  </" + group + ">");
+    }
+
+    /*
+     * Print out a method.
+     */
+    private static void method(PrintWriter out, String element,
+            Clazz.MethodDef source, String closeElement) {
+        out.println("      <" + element + " class='" + source.clazz + "'"
+                + getAccess(source.access) + 
+                ( source.isConstructor() ? "" :  " name='" + source.name + "'") + " descriptor='" + source.descriptor + "' pretty='"
+                + source.getPretty() + "'" + closeElement);
+    }
+
+    private static String getAccess(int access) {
+        StringBuilder sb = new StringBuilder();
+        if ( Modifier.isPublic(access) )
+            sb.append(" public='true'");
+        if ( Modifier.isStatic(access) )
+            sb.append(" static='true'");
+        if ( Modifier.isProtected(access) )
+            sb.append(" protected='true'");
+        if ( Modifier.isInterface(access) )
+            sb.append(" interface='true'");
+        
+        return sb.toString();
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java b/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java
new file mode 100644
index 0000000..a73e714
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java
@@ -0,0 +1,343 @@
+package aQute.bnd.make.component;
+
+import static aQute.bnd.make.component.ServiceComponent.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.annotation.component.*;
+import aQute.lib.osgi.*;
+import aQute.libg.reporter.*;
+
+public class ComponentAnnotationReader extends ClassDataCollector {
+	String						EMPTY[]					= new String[0];
+	private static final String	V1_1					= "1.1.0";																																// "1.1.0"
+	static Pattern				BINDDESCRIPTOR			= Pattern
+																.compile("\\(L([^;]*);(Ljava/util/Map;|Lorg/osgi/framework/ServiceReference;)*\\)V");
+	static Pattern				BINDMETHOD				= Pattern.compile("(set|bind|add)(.)(.*)");
+
+	static Pattern				ACTIVATEDESCRIPTOR		= Pattern
+																.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;))*\\)V");
+	static Pattern				OLDACTIVATEDESCRIPTOR	= Pattern
+																.compile("\\(Lorg/osgi/service/component/ComponentContext;\\)V");
+	static Pattern				OLDBINDDESCRIPTOR		= Pattern.compile("\\(L([^;]*);\\)V");
+	static Pattern				REFERENCEBINDDESCRIPTOR	= Pattern
+																.compile("\\(Lorg/osgi/framework/ServiceReference;\\)V");
+
+	Reporter					reporter				= new Processor();
+	String						method;
+	String						methodDescriptor;
+	int							methodAccess;
+	String						className;
+	Clazz						clazz;
+	String						interfaces[];
+	Set<String>					multiple				= new HashSet<String>();
+	Set<String>					optional				= new HashSet<String>();
+	Set<String>					dynamic					= new HashSet<String>();
+
+	Map<String, String>			map						= new TreeMap<String, String>();
+	Set<String>					descriptors				= new HashSet<String>();
+	List<String>				properties				= new ArrayList<String>();
+	String						version					= null;
+
+	// TODO make patterns for descriptors
+
+	ComponentAnnotationReader(Clazz clazz) {
+		this.clazz = clazz;
+	}
+
+	public void setReporter(Reporter reporter) {
+		this.reporter = reporter;
+	}
+
+	public Reporter getReporter() {
+		return this.reporter;
+	}
+
+	public static Map<String, String> getDefinition(Clazz c) throws Exception {
+		return getDefinition(c, new Processor());
+	}
+
+	public static Map<String, String> getDefinition(Clazz c, Reporter reporter) throws Exception {
+		ComponentAnnotationReader r = new ComponentAnnotationReader(c);
+		r.setReporter(reporter);
+		c.parseClassFileWithCollector(r);
+		r.finish();
+		return r.map;
+	}
+
+	public void annotation(Annotation annotation) {
+
+		if (annotation.getName().equals(Component.RNAME)) {
+			set(COMPONENT_NAME, annotation.get(Component.NAME), "<>");
+			set(COMPONENT_FACTORY, annotation.get(Component.FACTORY), false);
+			setBoolean(COMPONENT_ENABLED, annotation.get(Component.ENABLED), true);
+			setBoolean(COMPONENT_IMMEDIATE, annotation.get(Component.IMMEDIATE), false);
+			setBoolean(COMPONENT_SERVICEFACTORY, annotation.get(Component.SERVICEFACTORY), false);
+
+			if (annotation.get(Component.DESIGNATE) != null) {
+				String configs = annotation.get(Component.DESIGNATE);
+				if (configs != null) {
+					set(COMPONENT_DESIGNATE, Clazz.objectDescriptorToFQN(configs), "");
+				}
+			}
+
+			if (annotation.get(Component.DESIGNATE_FACTORY) != null) {
+				String configs = annotation.get(Component.DESIGNATE_FACTORY);
+				if (configs != null) {
+					set(COMPONENT_DESIGNATEFACTORY, Clazz.objectDescriptorToFQN(configs), "");
+				}
+			}
+
+			setVersion((String) annotation.get(Component.VERSION));
+
+			String configurationPolicy = annotation.get(Component.CONFIGURATION_POLICY);
+			if (configurationPolicy != null)
+				set(COMPONENT_CONFIGURATION_POLICY, configurationPolicy.toLowerCase(), "");
+
+			doProperties(annotation);
+
+			Object[] provides = (Object[]) annotation.get(Component.PROVIDE);
+			String[] p;
+			if (provides == null) {
+				// Use the found interfaces, but convert from internal to
+				// fqn.
+				if (interfaces != null) {
+					List<String> result = new ArrayList<String>();
+					for (int i = 0; i < interfaces.length; i++) {
+						if (!interfaces[i].equals("scala/ScalaObject") )
+							result.add(Clazz.internalToFqn(interfaces[i]));
+					}
+					p = result.toArray(EMPTY);
+				} else
+					p = EMPTY;
+			} else {
+				// We have explicit interfaces set
+				p = new String[provides.length];
+				for (int i = 0; i < provides.length; i++) {
+					p[i] = descriptorToFQN(provides[i].toString());
+				}
+			}
+			if (p.length > 0) {
+				set(COMPONENT_PROVIDE, Processor.join(Arrays.asList(p)), "<>");
+			}
+
+		} else if (annotation.getName().equals(Activate.RNAME)) {
+			if (!checkMethod())
+				setVersion(V1_1);
+
+			if (!ACTIVATEDESCRIPTOR.matcher(methodDescriptor).matches())
+				reporter.error(
+						"Activate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+						className, methodDescriptor);
+
+			if (method.equals("activate")
+					&& OLDACTIVATEDESCRIPTOR.matcher(methodDescriptor).matches()) {
+				// this is the default!
+			} else {
+				setVersion(V1_1);
+				set(COMPONENT_ACTIVATE, method, "<>");
+			}
+
+		} else if (annotation.getName().equals(Deactivate.RNAME)) {
+			if (!checkMethod())
+				setVersion(V1_1);
+
+			if (!ACTIVATEDESCRIPTOR.matcher(methodDescriptor).matches())
+				reporter.error(
+						"Deactivate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+						className, methodDescriptor);
+			if (method.equals("deactivate")
+					&& OLDACTIVATEDESCRIPTOR.matcher(methodDescriptor).matches()) {
+				// This is the default!
+			} else {
+				setVersion(V1_1);
+				set(COMPONENT_DEACTIVATE, method, "<>");
+			}
+		} else if (annotation.getName().equals(Modified.RNAME)) {
+			set(COMPONENT_MODIFIED, method, "<>");
+			setVersion(V1_1);
+		} else if (annotation.getName().equals(Reference.RNAME)) {
+
+			String name = (String) annotation.get(Reference.NAME);
+			String bind = method;
+			String unbind = null;
+
+			if (name == null) {
+				Matcher m = BINDMETHOD.matcher(method);
+				if (m.matches()) {
+					name = m.group(2).toLowerCase() + m.group(3);
+				} else {
+					name = method.toLowerCase();
+				}
+			}
+			String simpleName = name;
+
+			unbind = annotation.get(Reference.UNBIND);
+
+			if (bind != null) {
+				name = name + "/" + bind;
+				if (unbind != null)
+					name = name + "/" + unbind;
+			}
+			String service = annotation.get(Reference.SERVICE);
+
+			if (service != null) {
+				service = Clazz.objectDescriptorToFQN(service);
+			} else {
+				// We have to find the type of the current method to
+				// link it to the referenced service.
+				Matcher m = BINDDESCRIPTOR.matcher(methodDescriptor);
+				if (m.matches()) {
+					service = Clazz.internalToFqn(m.group(1));
+				} else
+					throw new IllegalArgumentException(
+							"Cannot detect the type of a Component Reference from the descriptor: "
+									+ methodDescriptor);
+			}
+
+			// Check if we have a target, this must be a filter
+			String target = annotation.get(Reference.TARGET);
+			if (target != null) {
+				Verifier.verifyFilter(target, 0);
+				service = service + target;
+			}
+
+			Integer c = annotation.get(Reference.TYPE);
+			if (c != null && !c.equals(0) && !c.equals((int) '1')) {
+				service = service + (char) c.intValue();
+			}
+
+			if (map.containsKey(name))
+				reporter.error(
+						"In component %s, Multiple references with the same name: %s. Previous def: %s, this def: %s",
+						name, map.get(name), service, "");
+			map.put(name, service);
+
+			if (isTrue(annotation.get(Reference.MULTIPLE)))
+				multiple.add(simpleName);
+			if (isTrue(annotation.get(Reference.OPTIONAL)))
+				optional.add(simpleName);
+			if (isTrue(annotation.get(Reference.DYNAMIC)))
+				dynamic.add(simpleName);
+
+			if (!checkMethod())
+				setVersion(V1_1);
+			else if (REFERENCEBINDDESCRIPTOR.matcher(methodDescriptor).matches()
+					|| !OLDBINDDESCRIPTOR.matcher(methodDescriptor).matches())
+				setVersion(V1_1);
+		}
+	}
+
+	private void setVersion(String v) {
+		if (v == null)
+			return;
+
+		if (version == null)
+			version = v;
+		else if (v.compareTo(version) > 0) // we're safe to 9.9.9
+			version = v;
+	}
+
+	private boolean checkMethod() {
+		return Modifier.isPublic(methodAccess) || Modifier.isProtected(methodAccess);
+	}
+
+	static Pattern	PROPERTY_PATTERN	= Pattern.compile("[^=]+=.+");
+
+	private void doProperties(Annotation annotation) {
+		Object[] properties = annotation.get(Component.PROPERTIES);
+
+		if (properties != null) {
+			for (Object o : properties) {
+				String p = (String) o;
+				if (PROPERTY_PATTERN.matcher(p).matches())
+					this.properties.add(p);
+				else
+					throw new IllegalArgumentException("Malformed property '" + p + "' on: "
+							+ annotation.get(Component.NAME));
+			}
+		}
+	}
+
+	private boolean isTrue(Object object) {
+		if (object == null)
+			return false;
+		return (Boolean) object;
+	}
+
+	private void setBoolean(String string, Object object, boolean b) {
+		if (object == null)
+			object = b;
+
+		Boolean bb = (Boolean) object;
+		if (bb == b)
+			return;
+
+		map.put(string, bb.toString());
+	}
+
+	private void set(String string, Object object, Object deflt) {
+		if (object == null || object.equals(deflt))
+			return;
+
+		map.put(string, object.toString());
+	}
+
+	/**
+	 * Skip L and ; and replace / for . in an object descriptor.
+	 * 
+	 * A string like Lcom/acme/Foo; becomes com.acme.Foo
+	 * 
+	 * @param string
+	 * @return
+	 */
+
+	private String descriptorToFQN(String string) {
+		StringBuilder sb = new StringBuilder();
+		for (int i = 1; i < string.length() - 1; i++) {
+			char c = string.charAt(i);
+			if (c == '/')
+				c = '.';
+			sb.append(c);
+		}
+		return sb.toString();
+	}
+
+	@Override public void classBegin(int access, String name) {
+		className = name;
+	}
+
+	@Override public void implementsInterfaces(String[] interfaces) {
+		this.interfaces = interfaces;
+	}
+
+	@Override public void method(int access, String name, String descriptor) {
+		this.method = name;
+		this.methodDescriptor = descriptor;
+		this.methodAccess = access;
+		descriptors.add(method);
+	}
+
+	void set(String name, Collection<String> l) {
+		if (l.size() == 0)
+			return;
+
+		set(name, Processor.join(l), "<>");
+	}
+
+	public void finish() {
+		set(COMPONENT_MULTIPLE, multiple);
+		set(COMPONENT_DYNAMIC, dynamic);
+		set(COMPONENT_OPTIONAL, optional);
+		set(COMPONENT_IMPLEMENTATION, clazz.getFQN(), "<>");
+		set(COMPONENT_PROPERTIES, properties);
+		if (version != null) {
+			set(COMPONENT_VERSION, version, "<>");
+			reporter.trace("Component %s is v1.1", map);
+		}
+		set(COMPONENT_DESCRIPTORS, descriptors);
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java b/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java
new file mode 100644
index 0000000..652d367
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java
@@ -0,0 +1,665 @@
+package aQute.bnd.make.component;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.annotation.component.*;
+import aQute.bnd.make.metatype.*;
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.*;
+import aQute.libg.version.*;
+
+/**
+ * This class is an analyzer plugin. It looks at the properties and tries to
+ * find out if the Service-Component header contains the bnd shortut syntax. If
+ * not, the header is copied to the output, if it does, an XML file is created
+ * and added to the JAR and the header is modified appropriately.
+ */
+public class ServiceComponent implements AnalyzerPlugin {
+	public final static String			NAMESPACE_STEM					= "http://www.osgi.org/xmlns/scr";
+	public final static String			JIDENTIFIER						= "<<identifier>>";
+	public final static String			COMPONENT_NAME					= "name:";
+	public final static String			COMPONENT_FACTORY				= "factory:";
+	public final static String			COMPONENT_SERVICEFACTORY		= "servicefactory:";
+	public final static String			COMPONENT_IMMEDIATE				= "immediate:";
+	public final static String			COMPONENT_ENABLED				= "enabled:";
+	public final static String			COMPONENT_DYNAMIC				= "dynamic:";
+	public final static String			COMPONENT_MULTIPLE				= "multiple:";
+	public final static String			COMPONENT_PROVIDE				= "provide:";
+	public final static String			COMPONENT_OPTIONAL				= "optional:";
+	public final static String			COMPONENT_PROPERTIES			= "properties:";
+	public final static String			COMPONENT_IMPLEMENTATION		= "implementation:";
+	public final static String			COMPONENT_DESIGNATE				= "designate:";
+	public final static String			COMPONENT_DESIGNATEFACTORY		= "designateFactory:";
+	public final static String			COMPONENT_DESCRIPTORS			= ".descriptors:";
+
+	// v1.1.0
+	public final static String			COMPONENT_VERSION				= "version:";
+	public final static String			COMPONENT_CONFIGURATION_POLICY	= "configuration-policy:";
+	public final static String			COMPONENT_MODIFIED				= "modified:";
+	public final static String			COMPONENT_ACTIVATE				= "activate:";
+	public final static String			COMPONENT_DEACTIVATE			= "deactivate:";
+
+	final static Map<String, String>	EMPTY							= Collections.emptyMap();
+
+	public final static String[]		componentDirectives				= new String[] {
+			COMPONENT_FACTORY, COMPONENT_IMMEDIATE, COMPONENT_ENABLED, COMPONENT_DYNAMIC,
+			COMPONENT_MULTIPLE, COMPONENT_PROVIDE, COMPONENT_OPTIONAL, COMPONENT_PROPERTIES,
+			COMPONENT_IMPLEMENTATION, COMPONENT_SERVICEFACTORY, COMPONENT_VERSION,
+			COMPONENT_CONFIGURATION_POLICY, COMPONENT_MODIFIED, COMPONENT_ACTIVATE,
+			COMPONENT_DEACTIVATE, COMPONENT_NAME, COMPONENT_DESCRIPTORS, COMPONENT_DESIGNATE,
+			COMPONENT_DESIGNATEFACTORY									};
+
+	public final static Set<String>		SET_COMPONENT_DIRECTIVES		= new HashSet<String>(
+																				Arrays.asList(componentDirectives));
+
+	public final static Set<String>		SET_COMPONENT_DIRECTIVES_1_1	= //
+																		new HashSet<String>(
+																				Arrays.asList(
+																						COMPONENT_VERSION,
+																						COMPONENT_CONFIGURATION_POLICY,
+																						COMPONENT_MODIFIED,
+																						COMPONENT_ACTIVATE,
+																						COMPONENT_DEACTIVATE));
+
+	public boolean analyzeJar(Analyzer analyzer) throws Exception {
+
+		ComponentMaker m = new ComponentMaker(analyzer);
+
+		Map<String, Map<String, String>> l = m.doServiceComponent();
+
+		analyzer.setProperty(Constants.SERVICE_COMPONENT, Processor.printClauses(l));
+
+		analyzer.getInfo(m, "Service-Component: ");
+		m.close();
+
+		return false;
+	}
+
+	private static class ComponentMaker extends Processor {
+		Analyzer	analyzer;
+
+		ComponentMaker(Analyzer analyzer) {
+			super(analyzer);
+			this.analyzer = analyzer;
+		}
+
+		/**
+		 * Iterate over the Service Component entries. There are two cases:
+		 * <ol>
+		 * <li>An XML file reference</li>
+		 * <li>A FQN/wildcard with a set of attributes</li>
+		 * </ol>
+		 * 
+		 * An XML reference is immediately expanded, an FQN/wildcard is more
+		 * complicated and is delegated to
+		 * {@link #componentEntry(Map, String, Map)}.
+		 * 
+		 * @throws Exception
+		 */
+		Map<String, Map<String, String>> doServiceComponent() throws Exception {
+			Map<String, Map<String, String>> serviceComponents = newMap();
+			String header = getProperty(SERVICE_COMPONENT);
+			Map<String, Map<String, String>> sc = parseHeader(header);
+
+			for (Map.Entry<String, Map<String, String>> entry : sc.entrySet()) {
+				String name = entry.getKey();
+				Map<String, String> info = entry.getValue();
+
+				try {
+					if (name.indexOf('/') >= 0 || name.endsWith(".xml")) {
+						// Normal service component, we do not process it
+						serviceComponents.put(name, EMPTY);
+					} else {
+						componentEntry(serviceComponents, name, info);
+					}
+				} catch (Exception e) {
+					e.printStackTrace();
+					error("Invalid Service-Component header: %s %s, throws %s", name, info, e);
+				}
+			}
+			return serviceComponents;
+		}
+
+		/**
+		 * Parse an entry in the Service-Component header. This header supports
+		 * the following types:
+		 * <ol>
+		 * <li>An FQN + attributes describing a component</li>
+		 * <li>A wildcard expression for finding annotated components.</li>
+		 * </ol>
+		 * The problem is the distinction between an FQN and a wildcard because
+		 * an FQN can also be used as a wildcard.
+		 * 
+		 * If the info specifies {@link Constants#NOANNOTATIONS} then wildcards
+		 * are an error and the component must be fully described by the info.
+		 * Otherwise the FQN/wildcard is expanded into a list of classes with
+		 * annotations. If this list is empty, the FQN case is interpreted as a
+		 * complete component definition. For the wildcard case, it is checked
+		 * if any matching classes for the wildcard have been compiled for a
+		 * class file format that does not support annotations, this can be a
+		 * problem with JSR14 who silently ignores annotations. An error is
+		 * reported in such a case.
+		 * 
+		 * @param serviceComponents
+		 * @param name
+		 * @param info
+		 * @throws Exception
+		 * @throws IOException
+		 */
+		private void componentEntry(Map<String, Map<String, String>> serviceComponents,
+				String name, Map<String, String> info) throws Exception, IOException {
+
+			boolean annotations = !Processor.isTrue(info.get(NOANNOTATIONS));
+			boolean fqn = Verifier.isFQN(name);
+
+			if (annotations) {
+
+				// Annotations possible!
+
+				Collection<Clazz> annotatedComponents = analyzer.getClasses("",
+						QUERY.ANNOTATION.toString(), Component.class.getName(), //
+						QUERY.NAMED.toString(), name //
+						);
+
+				if (fqn) {
+					if (annotatedComponents.isEmpty()) {
+
+						// No annotations, fully specified in header
+
+						createComponentResource(serviceComponents, name, info);
+					} else {
+
+						// We had a FQN so expect only one
+
+						for (Clazz c : annotatedComponents) {
+							annotated(serviceComponents, c, info);
+						}
+					}
+				} else {
+
+					// We did not have an FQN, so expect the use of wildcards
+
+					if (annotatedComponents.isEmpty())
+						checkAnnotationsFeasible(name);
+					else
+						for (Clazz c : annotatedComponents) {
+							annotated(serviceComponents, c, info);
+						}
+				}
+			} else {
+				// No annotations
+				if (fqn)
+					createComponentResource(serviceComponents, name, info);
+				else
+					error("Set to %s but entry %s is not an FQN ", NOANNOTATIONS, name);
+
+			}
+		}
+
+		/**
+		 * Check if annotations are actually feasible looking at the class
+		 * format. If the class format does not provide annotations then it is
+		 * no use specifying annotated components.
+		 * 
+		 * @param name
+		 * @return
+		 * @throws Exception
+		 */
+		private Collection<Clazz> checkAnnotationsFeasible(String name) throws Exception {
+			Collection<Clazz> not = analyzer.getClasses("", QUERY.NAMED.toString(), name //
+					);
+			
+			if (not.isEmpty())
+				if ( "*".equals(name))
+					return not;
+				else
+					error("Specified %s but could not find any class matching this pattern", name);
+
+			for (Clazz c : not) {
+				if (c.getFormat().hasAnnotations())
+					return not;
+			}
+			
+			warning("Wildcards are used (%s) requiring annotations to decide what is a component. Wildcard maps to classes that are compiled with java.target < 1.5. Annotations were introduced in Java 1.5",
+					name);
+			
+			return not;
+		}
+
+		void annotated(Map<String, Map<String, String>> components, Clazz c,
+				Map<String, String> info) throws Exception {
+			// Get the component definition
+			// from the annotations
+			Map<String, String> map = ComponentAnnotationReader.getDefinition(c, this);
+
+			// Pick the name, the annotation can override
+			// the name.
+			String localname = map.get(COMPONENT_NAME);
+			if (localname == null)
+				localname = c.getFQN();
+
+			// Override the component info without manifest
+			// entries. We merge the properties though.
+
+			String merged = Processor.merge(info.remove(COMPONENT_PROPERTIES),
+					map.remove(COMPONENT_PROPERTIES));
+			if (merged != null && merged.length() > 0)
+				map.put(COMPONENT_PROPERTIES, merged);
+			map.putAll(info);
+			createComponentResource(components, localname, map);
+		}
+
+		private void createComponentResource(Map<String, Map<String, String>> components,
+				String name, Map<String, String> info) throws IOException {
+
+			// We can override the name in the parameters
+			if (info.containsKey(COMPONENT_NAME))
+				name = info.get(COMPONENT_NAME);
+
+			// Assume the impl==name, but allow override
+			String impl = name;
+			if (info.containsKey(COMPONENT_IMPLEMENTATION))
+				impl = info.get(COMPONENT_IMPLEMENTATION);
+
+			// Check if such a class exists
+			analyzer.referTo(impl);
+
+			boolean designate = designate(name, info.get(COMPONENT_DESIGNATE), false)
+					|| designate(name, info.get(COMPONENT_DESIGNATEFACTORY), true);
+
+			// If we had a designate, we want a default configuration policy of
+			// require.
+			if (designate && info.get(COMPONENT_CONFIGURATION_POLICY) == null)
+				info.put(COMPONENT_CONFIGURATION_POLICY, "require");
+
+			// We have a definition, so make an XML resources
+			Resource resource = createComponentResource(name, impl, info);
+			analyzer.getJar().putResource("OSGI-INF/" + name + ".xml", resource);
+
+			components.put("OSGI-INF/" + name + ".xml", EMPTY);
+
+		}
+
+		/**
+		 * Create a Metatype and Designate record out of the given
+		 * configurations.
+		 * 
+		 * @param name
+		 * @param config
+		 */
+		private boolean designate(String name, String config, boolean factory) {
+			if (config == null)
+				return false;
+
+			for (String c : Processor.split(config)) {
+				Clazz clazz = analyzer.getClassspace().get(Clazz.fqnToPath(c));
+				if (clazz != null) {
+					analyzer.referTo(c);
+					MetaTypeReader r = new MetaTypeReader(clazz, analyzer);
+					r.setDesignate(name, factory);
+					String rname = "OSGI-INF/metatype/" + name + ".xml";
+
+					analyzer.getJar().putResource(rname, r);
+				} else {
+					analyzer.error(
+							"Cannot find designated configuration class %s for component %s", c,
+							name);
+				}
+			}
+			return true;
+		}
+
+		/**
+		 * Create the resource for a DS component.
+		 * 
+		 * @param list
+		 * @param name
+		 * @param info
+		 * @throws UnsupportedEncodingException
+		 */
+		Resource createComponentResource(String name, String impl, Map<String, String> info)
+				throws IOException {
+			String namespace = getNamespace(info);
+			ByteArrayOutputStream out = new ByteArrayOutputStream();
+			PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, Constants.DEFAULT_CHARSET));
+			pw.println("<?xml version='1.0' encoding='utf-8'?>");
+			if (namespace != null)
+				pw.print("<scr:component xmlns:scr='" + namespace + "'");
+			else
+				pw.print("<component");
+
+			doAttribute(pw, name, "name");
+			doAttribute(pw, info.get(COMPONENT_FACTORY), "factory");
+			doAttribute(pw, info.get(COMPONENT_IMMEDIATE), "immediate", "false", "true");
+			doAttribute(pw, info.get(COMPONENT_ENABLED), "enabled", "true", "false");
+			doAttribute(pw, info.get(COMPONENT_CONFIGURATION_POLICY), "configuration-policy",
+					"optional", "require", "ignore");
+			doAttribute(pw, info.get(COMPONENT_ACTIVATE), "activate", JIDENTIFIER);
+			doAttribute(pw, info.get(COMPONENT_DEACTIVATE), "deactivate", JIDENTIFIER);
+			doAttribute(pw, info.get(COMPONENT_MODIFIED), "modified", JIDENTIFIER);
+
+			pw.println(">");
+
+			// Allow override of the implementation when people
+			// want to choose their own name
+			pw.println("  <implementation class='" + (impl == null ? name : impl) + "'/>");
+
+			String provides = info.get(COMPONENT_PROVIDE);
+			boolean servicefactory = Processor.isTrue(info.get(COMPONENT_SERVICEFACTORY));
+
+			if (servicefactory && Processor.isTrue(info.get(COMPONENT_IMMEDIATE))) {
+				// TODO can become error() if it is up to me
+				warning("For a Service Component, the immediate option and the servicefactory option are mutually exclusive for %(%s)",
+						name, impl);
+			}
+			provide(pw, provides, servicefactory, impl);
+			properties(pw, info);
+			reference(info, pw);
+
+			if (namespace != null)
+				pw.println("</scr:component>");
+			else
+				pw.println("</component>");
+
+			pw.close();
+			byte[] data = out.toByteArray();
+			out.close();
+			return new EmbeddedResource(data, 0);
+		}
+
+		private void doAttribute(PrintWriter pw, String value, String name, String... matches) {
+			if (value != null) {
+				if (matches.length != 0) {
+					if (matches.length == 1 && matches[0].equals(JIDENTIFIER)) {
+						if (!Verifier.isIdentifier(value))
+							error("Component attribute %s has value %s but is not a Java identifier",
+									name, value);
+					} else {
+
+						if (!Verifier.isMember(value, matches))
+							error("Component attribute %s has value %s but is not a member of %s",
+									name, value, Arrays.toString(matches));
+					}
+				}
+				pw.print(" ");
+				pw.print(name);
+				pw.print("='");
+				pw.print(value);
+				pw.print("'");
+			}
+		}
+
+		/**
+		 * Check if we need to use the v1.1 namespace (or later).
+		 * 
+		 * @param info
+		 * @return
+		 */
+		private String getNamespace(Map<String, String> info) {
+			String version = info.get(COMPONENT_VERSION);
+			if (version != null) {
+				try {
+					Version v = new Version(version);
+					return NAMESPACE_STEM + "/v" + v;
+				} catch (Exception e) {
+					error("version: specified on component header but not a valid version: "
+							+ version);
+					return null;
+				}
+			}
+			for (String key : info.keySet()) {
+				if (SET_COMPONENT_DIRECTIVES_1_1.contains(key)) {
+					return NAMESPACE_STEM + "/v1.1.0";
+				}
+			}
+			return null;
+		}
+
+		/**
+		 * Print the Service-Component properties element
+		 * 
+		 * @param pw
+		 * @param info
+		 */
+		void properties(PrintWriter pw, Map<String, String> info) {
+			Collection<String> properties = split(info.get(COMPONENT_PROPERTIES));
+			for (Iterator<String> p = properties.iterator(); p.hasNext();) {
+				String clause = p.next();
+				int n = clause.indexOf('=');
+				if (n <= 0) {
+					error("Not a valid property in service component: " + clause);
+				} else {
+					String type = null;
+					String name = clause.substring(0, n);
+					if (name.indexOf('@') >= 0) {
+						String parts[] = name.split("@");
+						name = parts[1];
+						type = parts[0];
+					} else if (name.indexOf(':') >= 0) {
+						String parts[] = name.split(":");
+						name = parts[0];
+						type = parts[1];
+					}
+					String value = clause.substring(n + 1).trim();
+					// TODO verify validity of name and value.
+					pw.print("  <property name='");
+					pw.print(name);
+					pw.print("'");
+
+					if (type != null) {
+						if (VALID_PROPERTY_TYPES.matcher(type).matches()) {
+							pw.print(" type='");
+							pw.print(type);
+							pw.print("'");
+						} else {
+							warning("Invalid property type '" + type + "' for property " + name);
+						}
+					}
+
+					String parts[] = value.split("\\s*(\\||\\n)\\s*");
+					if (parts.length > 1) {
+						pw.println(">");
+						for (String part : parts) {
+							pw.println(part);
+						}
+						pw.println("</property>");
+					} else {
+						pw.print(" value='");
+						pw.print(parts[0]);
+						pw.println("'/>");
+					}
+				}
+			}
+		}
+
+		/**
+		 * @param pw
+		 * @param provides
+		 */
+		void provide(PrintWriter pw, String provides, boolean servicefactory, String impl) {
+			if (provides != null) {
+				if (!servicefactory)
+					pw.println("  <service>");
+				else
+					pw.println("  <service servicefactory='true'>");
+
+				StringTokenizer st = new StringTokenizer(provides, ",");
+				while (st.hasMoreTokens()) {
+					String interfaceName = st.nextToken();
+					pw.println("    <provide interface='" + interfaceName + "'/>");
+					analyzer.referTo(interfaceName);
+
+					// TODO verifies the impl. class extends or implements the
+					// interface
+				}
+				pw.println("  </service>");
+			} else if (servicefactory)
+				warning("The servicefactory:=true directive is set but no service is provided, ignoring it");
+		}
+
+		public final static Pattern	REFERENCE	= Pattern.compile("([^(]+)(\\(.+\\))?");
+
+		/**
+		 * @param info
+		 * @param pw
+		 */
+
+		void reference(Map<String, String> info, PrintWriter pw) {
+			Collection<String> dynamic = new ArrayList<String>(split(info.get(COMPONENT_DYNAMIC)));
+			Collection<String> optional = new ArrayList<String>(split(info.get(COMPONENT_OPTIONAL)));
+			Collection<String> multiple = new ArrayList<String>(split(info.get(COMPONENT_MULTIPLE)));
+
+			Collection<String> descriptors = split(info.get(COMPONENT_DESCRIPTORS));
+
+			for (Map.Entry<String, String> entry : info.entrySet()) {
+
+				// Skip directives
+				String referenceName = entry.getKey();
+				if (referenceName.endsWith(":")) {
+					if (!SET_COMPONENT_DIRECTIVES.contains(referenceName))
+						error("Unrecognized directive in Service-Component header: "
+								+ referenceName);
+					continue;
+				}
+
+				// Parse the bind/unbind methods from the name
+				// if set. They are separated by '/'
+				String bind = null;
+				String unbind = null;
+
+				boolean unbindCalculated = false;
+
+				if (referenceName.indexOf('/') >= 0) {
+					String parts[] = referenceName.split("/");
+					referenceName = parts[0];
+					bind = parts[1];
+					if (parts.length > 2) {
+						unbind = parts[2];
+					} else {
+						unbindCalculated = true;
+						if (bind.startsWith("add"))
+							unbind = bind.replaceAll("add(.+)", "remove$1");
+						else
+							unbind = "un" + bind;
+					}
+				} else if (Character.isLowerCase(referenceName.charAt(0))) {
+					unbindCalculated = true;
+					bind = "set" + Character.toUpperCase(referenceName.charAt(0))
+							+ referenceName.substring(1);
+					unbind = "un" + bind;
+				}
+
+				String interfaceName = entry.getValue();
+				if (interfaceName == null || interfaceName.length() == 0) {
+					error("Invalid Interface Name for references in Service Component: "
+							+ referenceName + "=" + interfaceName);
+					continue;
+				}
+
+				// If we have descriptors, we have analyzed the component.
+				// So why not check the methods
+				if (descriptors.size() > 0) {
+					// Verify that the bind method exists
+					if (!descriptors.contains(bind))
+						error("The bind method %s for %s not defined", bind, referenceName);
+
+					// Check if the unbind method exists
+					if (!descriptors.contains(unbind)) {
+						if (unbindCalculated)
+							// remove it
+							unbind = null;
+						else
+							error("The unbind method %s for %s not defined", unbind, referenceName);
+					}
+				}
+				// Check tje cardinality by looking at the last
+				// character of the value
+				char c = interfaceName.charAt(interfaceName.length() - 1);
+				if ("?+*~".indexOf(c) >= 0) {
+					if (c == '?' || c == '*' || c == '~')
+						optional.add(referenceName);
+					if (c == '+' || c == '*')
+						multiple.add(referenceName);
+					if (c == '+' || c == '*' || c == '?')
+						dynamic.add(referenceName);
+					interfaceName = interfaceName.substring(0, interfaceName.length() - 1);
+				}
+
+				// Parse the target from the interface name
+				// The target is a filter.
+				String target = null;
+				Matcher m = REFERENCE.matcher(interfaceName);
+				if (m.matches()) {
+					interfaceName = m.group(1);
+					target = m.group(2);
+				}
+
+				analyzer.referTo(interfaceName);
+
+				pw.printf("  <reference name='%s'", referenceName);
+				pw.printf(" interface='%s'", interfaceName);
+
+				String cardinality = optional.contains(referenceName) ? "0" : "1";
+				cardinality += "..";
+				cardinality += multiple.contains(referenceName) ? "n" : "1";
+				if (!cardinality.equals("1..1"))
+					pw.print(" cardinality='" + cardinality + "'");
+
+				if (bind != null) {
+					pw.printf(" bind='%s'", bind);
+					if (unbind != null) {
+						pw.printf(" unbind='%s'", unbind);
+					}
+				}
+
+				if (dynamic.contains(referenceName)) {
+					pw.print(" policy='dynamic'");
+				}
+
+				if (target != null) {
+					// Filter filter = new Filter(target);
+					// if (filter.verify() == null)
+					// pw.print(" target='" + filter.toString() + "'");
+					// else
+					// error("Target for " + referenceName
+					// + " is not a correct filter: " + target + " "
+					// + filter.verify());
+					pw.print(" target='" + escape(target) + "'");
+				}
+				pw.println("/>");
+			}
+		}
+	}
+
+	/**
+	 * Escape a string, do entity conversion.
+	 */
+	static 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;
+			case '\'':
+				sb.append("&quot;");
+				break;
+			default:
+				sb.append(c);
+				break;
+			}
+		}
+		return sb.toString();
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java b/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java
new file mode 100644
index 0000000..bc33dc2
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java
@@ -0,0 +1,95 @@
+package aQute.bnd.make.coverage;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.*;
+
+/**
+ * This class can create a coverage table between two classspaces. The
+ * destination class space is used to create a table of methods. All source
+ * methods that refer to a specific dest are then filled into the table.
+ * 
+ */
+public class Coverage {
+
+    /**
+     * Create a cross reference table from source to dest.
+     * 
+     * @param source
+     *            The methods that refer to dest
+     * @param dest
+     *            The methods that are being referred to
+     * @return A mapping of source methods to destination methods.
+     * @throws IOException
+     */
+    public static Map<MethodDef, List<MethodDef>> getCrossRef(
+            Collection<Clazz> source, Collection<Clazz> dest)
+            throws Exception {
+        final Map<MethodDef, List<MethodDef>> catalog = buildCatalog(dest);
+        crossRef(source, catalog);
+        return catalog;
+    }
+
+    private static void crossRef(Collection<Clazz> source,
+            final Map<MethodDef, List<MethodDef>> catalog) throws Exception {
+        for (final Clazz clazz : source) {
+            clazz.parseClassFileWithCollector(new ClassDataCollector() {
+                MethodDef source;
+
+                public void implementsInterfaces(String names[]) {
+                    MethodDef def = new MethodDef(0, clazz.getFQN(),
+                            "<implements>", "()V");
+                    for (String interfaceName : names) {
+                        interfaceName = Clazz.internalToFqn(interfaceName);
+                        for (Map.Entry<MethodDef, List<MethodDef>> entry : catalog
+                                .entrySet()) {
+                            String catalogClass = entry.getKey().clazz;
+                            List<MethodDef> references = entry.getValue();
+
+                            if (catalogClass.equals(interfaceName)) {
+                                references.add(def);
+                            }
+                        }
+                    }
+                }
+
+                // Method definitions
+                public void method(MethodDef source) {
+                    this.source = source;
+                }
+
+                public void reference(MethodDef reference) {
+                    List<MethodDef> references = catalog.get(reference);
+                    if (references != null) {
+                        references.add(source);
+                    }
+                }
+            });
+        }
+    }
+
+    private static Map<MethodDef, List<MethodDef>> buildCatalog(
+            Collection<Clazz> sources) throws Exception {
+        final Map<MethodDef, List<MethodDef>> catalog = new TreeMap<MethodDef, List<MethodDef>>();
+        for (final Clazz clazz : sources) {
+            clazz.parseClassFileWithCollector(new ClassDataCollector() {
+
+                public boolean classStart(int access, String name) {
+                    return clazz.isPublic();
+                }
+
+                public void method(MethodDef source) {
+                    if (java.lang.reflect.Modifier.isPublic(source.access)
+                            || Modifier.isProtected(source.access))
+                        catalog.put(source, new ArrayList<MethodDef>());
+                }
+
+            });
+        }
+        return catalog;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/coverage/CoverageResource.java b/bundleplugin/src/main/java/aQute/bnd/make/coverage/CoverageResource.java
new file mode 100644
index 0000000..3827391
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/coverage/CoverageResource.java
@@ -0,0 +1,92 @@
+package aQute.bnd.make.coverage;
+
+import static aQute.bnd.make.coverage.Coverage.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.*;
+import aQute.lib.tag.*;
+
+/**
+ * Creates an XML Coverage report. This class can be used as a resource so the
+ * report is created only when the JAR is written.
+ * 
+ */
+public class CoverageResource extends WriteResource {
+    Collection<Clazz> testsuite;
+    Collection<Clazz> service;
+
+    public CoverageResource(Collection<Clazz> testsuite,
+            Collection<Clazz> service) {
+        this.testsuite = testsuite;
+        this.service = service;
+    }
+
+    @Override
+    public long lastModified() {
+        return 0;
+    }
+
+    @Override
+    public void write(OutputStream out) throws IOException {
+        try {
+            Map<MethodDef, List<MethodDef>> table = getCrossRef(testsuite,
+                    service);
+            Tag coverage = toTag(table);
+            PrintWriter pw = new PrintWriter(new OutputStreamWriter(out,
+                    Constants.DEFAULT_CHARSET));
+            try {
+                coverage.print(0, pw);
+            } finally {
+                pw.flush();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static Tag toTag(Map<MethodDef, List<MethodDef>> catalog) {
+        Tag coverage = new Tag("coverage");
+        String currentClass = null;
+        Tag classTag = null;
+
+        for (Map.Entry<MethodDef, List<MethodDef>> m : catalog.entrySet()) {
+            String className = m.getKey().clazz;
+            if (!className.equals(currentClass)) {
+                classTag = new Tag("class");
+                classTag.addAttribute("name", className);
+                classTag.addAttribute("package", Clazz.getPackage(className));
+                classTag.addAttribute("short", Clazz.getShortName(className));
+                coverage.addContent(classTag);
+                currentClass = className;
+            }
+            Tag method = doMethod(new Tag("method"), m.getKey());
+            classTag.addContent(method);
+            for (MethodDef r : m.getValue()) {
+                Tag ref = doMethod(new Tag("ref"), r);
+                method.addContent(ref);
+            }
+        }
+        return coverage;
+    }
+
+    private static Tag doMethod(Tag tag, MethodDef method) {
+        tag.addAttribute("pretty", method.getPretty());
+        if (Modifier.isPublic(method.access))
+            tag.addAttribute("public", true);
+        if (Modifier.isStatic(method.access))
+            tag.addAttribute("static", true);
+        if (Modifier.isProtected(method.access))
+            tag.addAttribute("protected", true);
+        if (Modifier.isInterface(method.access))
+            tag.addAttribute("interface", true);
+        tag.addAttribute("constructor", method.isConstructor());
+        if (!method.isConstructor())
+            tag.addAttribute("name", method.name);
+        tag.addAttribute("descriptor", method.descriptor);
+        return tag;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/metatype/MetaTypeReader.java b/bundleplugin/src/main/java/aQute/bnd/make/metatype/MetaTypeReader.java
new file mode 100644
index 0000000..94a65ae
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/metatype/MetaTypeReader.java
@@ -0,0 +1,341 @@
+package aQute.bnd.make.metatype;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.regex.*;
+
+import aQute.bnd.annotation.metatype.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.MethodDef;
+import aQute.lib.tag.*;
+import aQute.libg.generics.*;
+
+public class MetaTypeReader extends ClassDataCollector implements Resource {
+	final Analyzer				reporter;
+	Clazz						clazz;
+	String						interfaces[];
+	Tag							metadata	= new Tag("metatype:MetaData", new String[] {
+			"xmlns:metatype", "http://www.osgi.org/xmlns/metatype/v1.1.0" });
+	Tag							ocd			= new Tag(metadata, "OCD");
+	Tag							designate	= new Tag(metadata, "Designate");
+	Tag							object		= new Tag(designate, "Object");
+
+	// Resource
+	String						extra;
+
+	// One time init
+	boolean						finished;
+
+	// Designate
+	boolean						override;
+	String						designatePid;
+	boolean						factory;
+
+	// AD
+	Map<MethodDef, Meta.AD>	methods		= new LinkedHashMap<MethodDef, Meta.AD>();
+
+	// OCD
+	Annotation					ocdAnnotation;
+
+	MethodDef					method;
+
+	public MetaTypeReader(Clazz clazz, Analyzer reporter) {
+		this.clazz = clazz;
+		this.reporter = reporter;
+	}
+
+	public void annotation(Annotation annotation) {
+		try {
+			Meta.OCD ocd = annotation.getAnnotation(Meta.OCD.class);
+			Meta.AD ad = annotation.getAnnotation(Meta.AD.class);
+			if (ocd != null) {
+				this.ocdAnnotation = annotation;
+			}
+			if (ad != null) {
+				assert method != null;
+				methods.put(method, ad);
+			}
+		} catch (Exception e) {
+			reporter.error("Error during annotation parsing %s : %s", clazz, e);
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * @param id
+	 * @param name
+	 * @param cardinality
+	 * @param required
+	 * @param deflt
+	 * @param type
+	 * @param max
+	 * @param min
+	 * @param optionLabels
+	 * @param optionValues
+	 */
+
+	static Pattern	COLLECTION	= Pattern
+										.compile("(.*(Collection|Set|List|Queue|Stack|Deque))<(L.+;)>");
+
+	private void addMethod(MethodDef method, Meta.AD ad) throws Exception {
+
+		// Set all the defaults.
+		String rtype = method.getReturnType();
+		String id = Configurable.mangleMethodName(method.name);
+		String name = Clazz.unCamel(id);
+
+		int cardinality = 0;
+
+		if (rtype.endsWith("[]")) {
+			cardinality = Integer.MAX_VALUE;
+			rtype = rtype.substring(0, rtype.length() - 2);
+		}
+		if (rtype.indexOf('<') > 0) {
+			if (cardinality != 0)
+				reporter.error(
+						"AD for %s.%s uses an array of collections in return type (%s), Metatype allows either Vector or array",
+						clazz.getFQN(), method.name, method.getReturnType());
+			Matcher m = COLLECTION.matcher(rtype);
+			if (m.matches()) {
+				rtype = Clazz.objectDescriptorToFQN(m.group(3));
+				cardinality = Integer.MIN_VALUE;
+			}
+		}
+
+		Meta.Type type = getType(rtype);
+		
+		boolean required = ad ==null || ad.required();
+		String deflt = null;
+		String max = null;
+		String min = null;
+		String[] optionLabels = null;
+		String[] optionValues = null;
+		String description = null;
+
+		Clazz c = reporter.findClass(Clazz.fqnToPath(rtype));
+		if (c != null && c.isEnum()) {
+			optionValues = parseOptionValues(c);
+		}
+
+		// Now parse the annotation for any overrides
+
+		if (ad != null) {
+			if (ad.id() != null)
+				id = ad.id();
+			if (ad.name() != null)
+				name = ad.name();
+			if (ad.cardinality() != 0)
+				cardinality = ad.cardinality();
+			if (ad.type() != null)
+				type = ad.type();
+			if (ad.required() || ad.deflt() == null)
+				required = true;
+
+			if (ad.description() != null)
+				description = ad.description();
+
+			if (ad.optionLabels() != null)
+				optionLabels = ad.optionLabels();
+			if (ad.optionValues() != null )
+				optionValues = ad.optionValues();
+
+			if (ad.min() != null)
+				min = ad.min();
+			if (ad.max() != null)
+				max = ad.max();
+
+			if (ad.deflt() != null)
+				deflt = ad.deflt();
+		}
+
+		if (optionValues != null) {
+			if (optionLabels == null || optionLabels.length == 0) {
+				optionLabels = new String[optionValues.length];
+				for (int i = 0; i < optionValues.length; i++)
+					optionLabels[i] = Clazz.unCamel(optionValues[i]);
+			}
+
+			if (optionLabels.length != optionValues.length) {
+				reporter.error("Option labels and option values not the same length for %s", id);
+				optionLabels = optionValues;
+			}
+		}
+
+		Tag adt = new Tag(this.ocd, "AD");
+		adt.addAttribute("name", name);
+		adt.addAttribute("id", id);
+		adt.addAttribute("cardinality", cardinality);
+		adt.addAttribute("required", required);
+		adt.addAttribute("default", deflt);
+		adt.addAttribute("type", type);
+		adt.addAttribute("max", max);
+		adt.addAttribute("min", min);
+		adt.addAttribute("description", description);
+
+		if (optionLabels != null) {
+			for (int i = 0; i < optionLabels.length; i++) {
+				Tag option = new Tag(adt, "Option");
+				option.addAttribute("label", optionLabels[i]);
+				option.addAttribute("value", optionValues[i]);
+			}
+		}
+	}
+
+	private String[] parseOptionValues(Clazz c) throws Exception {
+		final List<String> values = Create.list();
+
+		c.parseClassFileWithCollector(new ClassDataCollector() {
+			public void field(Clazz.FieldDef def) {
+				if (def.isEnum()) {
+					values.add(def.name);
+				}
+			}
+		});
+		return values.toArray(new String[values.size()]);
+	}
+
+	Meta.Type getType(String rtype) {
+		if (rtype.endsWith("[]")) {
+			rtype = rtype.substring(0, rtype.length() - 2);
+			if (rtype.endsWith("[]"))
+				throw new IllegalArgumentException("Can only handle array of depth one");
+		}
+
+		if ("boolean".equals(rtype) || Boolean.class.getName().equals(rtype))
+			return Meta.Type.Boolean;
+		else if ("byte".equals(rtype) || Byte.class.getName().equals(rtype))
+			return Meta.Type.Byte;
+		else if ("char".equals(rtype) || Character.class.getName().equals(rtype))
+			return Meta.Type.Character;
+		else if ("short".equals(rtype) || Short.class.getName().equals(rtype))
+			return Meta.Type.Short;
+		else if ("int".equals(rtype) || Integer.class.getName().equals(rtype))
+			return Meta.Type.Integer;
+		else if ("long".equals(rtype) || Long.class.getName().equals(rtype))
+			return Meta.Type.Long;
+		else if ("float".equals(rtype) || Float.class.getName().equals(rtype))
+			return Meta.Type.Float;
+		else if ("double".equals(rtype) || Double.class.getName().equals(rtype))
+			return Meta.Type.Double;
+		else
+			return Meta.Type.String;
+	}
+
+	@Override public void method(MethodDef mdef) {
+		method = mdef;
+		methods.put(mdef, null);
+	}
+
+	public String getExtra() {
+		return extra;
+	}
+
+	public long lastModified() {
+		return 0;
+	}
+
+	public InputStream openInputStream() throws IOException {
+		final PipedInputStream pin = new PipedInputStream();
+		final PipedOutputStream pout = new PipedOutputStream(pin);
+		getExecutor().execute(new Runnable() {
+			public void run() {
+				try {
+					write(pout);
+				} catch (IOException e) {
+					// Cause an exception in the other end
+					IO.close(pin);
+				}
+				IO.close(pout);
+			}
+		});
+		return pin;
+	}
+
+	private Executor getExecutor() {
+		return reporter.getPlugin(Executor.class);
+	}
+
+	public void setExtra(String extra) {
+		this.extra = extra;
+	}
+
+	public void write(OutputStream out) throws IOException {
+		try {
+			finish();
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		PrintWriter pw = new PrintWriter(new OutputStreamWriter(out));
+		pw.println("<?xml version='1.0'?>");
+		metadata.print(0, pw);
+		pw.flush();
+	}
+
+	void finish() throws Exception {
+		if (!finished) {
+			finished = true;
+			clazz.parseClassFileWithCollector(this);
+			Meta.OCD ocd = null;
+			if (this.ocdAnnotation != null)
+				ocd = this.ocdAnnotation.getAnnotation(Meta.OCD.class);
+			else
+				ocd = Configurable.createConfigurable(Meta.OCD.class,
+						new HashMap<String, Object>());
+
+			// defaults
+			String id = clazz.getFQN();
+			String name = Clazz.unCamel(Clazz.getShortName(clazz.getFQN()));
+			String description = null;
+			String localization = id;
+			boolean factory = this.factory;
+
+			if (ocd.id() != null)
+				id = ocd.id();
+
+			
+			if (ocd.name() != null)
+				name = ocd.name();
+
+			if (ocd.localization() != null)
+				localization = ocd.localization();
+
+			if (ocd.description() != null)
+				description = ocd.description();
+
+			String pid = id;
+			if (override) {
+				pid = this.designatePid;
+				factory = this.factory;
+				id = this.designatePid; // for the felix problems
+			} else {
+				if (ocdAnnotation.get("factory") != null) {
+					factory = true;
+				}
+			}
+
+			this.ocd.addAttribute("name", name);
+			this.ocd.addAttribute("id", id);
+			this.ocd.addAttribute("description", description);
+			this.ocd.addAttribute("localization", localization);
+
+			// do ADs
+			for (Map.Entry<MethodDef, Meta.AD> entry : methods.entrySet())
+				addMethod(entry.getKey(), entry.getValue());
+
+			this.designate.addAttribute("pid", pid);
+			if (factory)
+				this.designate.addAttribute("factoryPid", pid);
+
+			this.object.addAttribute("ocdref", id);
+
+		}
+	}
+
+	public void setDesignate(String pid, boolean factory) {
+		this.override = true;
+		this.factory = factory;
+		this.designatePid = pid;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/metatype/MetatypePlugin.java b/bundleplugin/src/main/java/aQute/bnd/make/metatype/MetatypePlugin.java
new file mode 100644
index 0000000..4801ec9
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/metatype/MetatypePlugin.java
@@ -0,0 +1,35 @@
+package aQute.bnd.make.metatype;
+
+import java.util.*;
+
+import aQute.bnd.annotation.metatype.*;
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.*;
+
+/**
+ * This class is responsible for meta type types. It is a plugin that can 
+ * @author aqute
+ *
+ */
+public class MetatypePlugin implements AnalyzerPlugin {
+
+	public boolean analyzeJar(Analyzer analyzer) throws Exception {
+
+		Map<String, Map<String, String>> map = analyzer.parseHeader(analyzer
+				.getProperty(Constants.METATYPE));
+
+		Jar jar = analyzer.getJar();
+		for (String name : map.keySet()) {
+			Collection<Clazz> metatypes = analyzer.getClasses("", QUERY.ANNOTATION.toString(),
+					Meta.OCD.class.getName(), // 
+					QUERY.NAMED.toString(), name //
+					);
+			for (Clazz c : metatypes) {
+				jar.putResource("OSGI-INF/metatype/" + c.getFQN() + ".xml", new MetaTypeReader(c,
+						analyzer));
+			}
+		}
+		return false;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/BsnToMavenPath.java b/bundleplugin/src/main/java/aQute/bnd/maven/BsnToMavenPath.java
new file mode 100644
index 0000000..6dc716c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/BsnToMavenPath.java
@@ -0,0 +1,5 @@
+package aQute.bnd.maven;
+
+public interface BsnToMavenPath {
+    String[] getGroupAndArtifact(String bsn);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/MavenCommand.java b/bundleplugin/src/main/java/aQute/bnd/maven/MavenCommand.java
new file mode 100644
index 0000000..c274ca5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenCommand.java
@@ -0,0 +1,615 @@
+package aQute.bnd.maven;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.bnd.maven.support.*;
+import aQute.bnd.maven.support.Pom.*;
+import aQute.bnd.settings.*;
+import aQute.lib.collections.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+import aQute.libg.command.*;
+import aQute.libg.header.*;
+
+public class MavenCommand extends Processor {
+	final Settings	settings	= new Settings();
+	File			temp;
+
+	public MavenCommand() {
+	}
+
+	public MavenCommand(Processor p) {
+		super(p);
+	}
+
+	/**
+	 * maven deploy [-url repo] [-passphrase passphrase] [-homedir homedir]
+	 * [-keyname keyname] bundle ...
+	 * 
+	 * @param args
+	 * @param i
+	 * @throws Exception
+	 */
+	public void run(String args[], int i) throws Exception {
+		temp = new File("maven-bundle");
+
+		if (i >= args.length) {
+			help();
+			return;
+		}
+
+		while (i < args.length && args[i].startsWith("-")) {
+			String option = args[i];
+			trace("option " + option);
+			if (option.equals("-temp"))
+				temp = getFile(args[++i]);
+			else {
+				help();
+				error("Invalid option " + option);
+			}
+			i++;
+		}
+
+		String cmd = args[i++];
+
+		trace("temp dir " + temp);
+		IO.delete(temp);
+		temp.mkdirs();
+		if (!temp.isDirectory())
+			throw new IOException("Cannot create temp directory");
+
+		if (cmd.equals("settings"))
+			settings();
+		else if (cmd.equals("help"))
+			help();
+		else if (cmd.equals("bundle"))
+			bundle(args, i);
+		else if (cmd.equals("view"))
+			view(args, i);
+		else
+			error("No such command %s, type help", cmd);
+	}
+
+	private void help() {
+		System.err.println("Usage:\n");
+		System.err
+				.println("  maven \n" //
+						+ "  [-temp <dir>]            use as temp directory\n" //
+						+ "  settings                 show maven settings\n" //
+						+ "  bundle                   turn a bundle into a maven bundle\n" //
+						+ "    [-properties <file>]   provide properties, properties starting with javadoc are options for javadoc, like javadoc-tag=...\n"
+						+ "    [-javadoc <file|url>]  where to find the javadoc (zip/dir), otherwise generated\n" //
+						+ "    [-source <file|url>]   where to find the source (zip/dir), otherwise from OSGI-OPT/src\n" //
+						+ "    [-scm <url>]           required scm in pom, otherwise from Bundle-SCM\n" //
+						+ "    [-url <url>]           required project url in pom\n" //
+						+ "    [-bsn bsn]             overrides bsn\n" //
+						+ "    [-version <version>]   overrides version\n" //
+						+ "    [-developer <email>]   developer email\n" //
+						+ "    [-nodelete]            do not delete temp files\n" //
+						+ "    [-passphrase <gpgp passphrase>] signer password\n"//
+						+ "        <file|url> ");
+	}
+
+	/**
+	 * Show the maven settings
+	 * 
+	 * @throws FileNotFoundException
+	 * @throws Exception
+	 */
+	private void settings() throws FileNotFoundException, Exception {
+		File userHome = new File(System.getProperty("user.home"));
+		File m2 = new File(userHome, ".m2");
+		if (!m2.isDirectory()) {
+			error("There is no m2 directory at %s", userHome);
+			return;
+		}
+		File settings = new File(m2, "settings.xml");
+		if (!settings.isFile()) {
+			error("There is no settings file at '%s'", settings.getAbsolutePath());
+			return;
+		}
+
+		FileReader rdr = new FileReader(settings);
+
+		LineCollection lc = new LineCollection(new BufferedReader(rdr));
+		while (lc.hasNext()) {
+			System.out.println(lc.next());
+		}
+	}
+
+	/**
+	 * Create a maven bundle.
+	 * 
+	 * @param args
+	 * @param i
+	 * @throws Exception
+	 */
+	private void bundle(String args[], int i) throws Exception {
+		List<String> developers = new ArrayList<String>();
+		Properties properties = new Properties();
+
+		String scm = null;
+		String passphrase = null;
+		String javadoc = null;
+		String source = null;
+		String output = "bundle.jar";
+		String url = null;
+		String artifact = null;
+		String group = null;
+		String version = null;
+		boolean nodelete = false;
+
+		while (i < args.length && args[i].startsWith("-")) {
+			String option = args[i++];
+			trace("bundle option %s", option);
+			if (option.equals("-scm"))
+				scm = args[i++];
+			else if (option.equals("-group"))
+				group = args[i++];
+			else if (option.equals("-artifact"))
+				artifact = args[i++];
+			else if (option.equals("-version"))
+				version = args[i++];
+			else if (option.equals("-developer"))
+				developers.add(args[i++]);
+			else if (option.equals("-passphrase")) {
+				passphrase = args[i++];
+			} else if (option.equals("-url")) {
+				url = args[i++];
+			} else if (option.equals("-javadoc"))
+				javadoc = args[i++];
+			else if (option.equals("-source"))
+				source = args[i++];
+			else if (option.equals("-output"))
+				output = args[i++];
+			else if (option.equals("-nodelete"))
+				nodelete=true;
+			else if (option.startsWith("-properties")) {
+				InputStream in = new FileInputStream(args[i++]);
+				try {
+					properties.load(in);
+				} catch (Exception e) {
+					in.close();
+				}
+			}
+		}
+
+		if (developers.isEmpty()) {
+			String email = settings.globalGet(Settings.EMAIL, null);
+			if (email == null)
+				error("No developer email set, you can set global default email with: bnd global email Peter.Kriens@aQute.biz");
+			else
+				developers.add(email);
+		}
+
+		if (i == args.length) {
+			error("too few arguments, no bundle specified");
+			return;
+		}
+
+		if (i != args.length - 1) {
+			error("too many arguments, only one bundle allowed");
+			return;
+		}
+
+		String input = args[i++];
+
+		Jar binaryJar = getJarFromFileOrURL(input);
+		trace("got %s", binaryJar);
+		if (binaryJar == null) {
+			error("JAR does not exist: %s", input);
+			return;
+		}
+
+		File original = getFile(temp, "original");
+		original.mkdirs();
+		binaryJar.expand(original);
+		binaryJar.calcChecksums(null);
+
+		Manifest manifest = binaryJar.getManifest();
+		trace("got manifest");
+
+		PomFromManifest pom = new PomFromManifest(manifest);
+
+		if (scm != null)
+			pom.setSCM(scm);
+		if (url != null)
+			pom.setURL(url);
+		if (artifact != null)
+			pom.setArtifact(artifact);
+		if (artifact != null)
+			pom.setGroup(group);
+		if (version != null)
+			pom.setVersion(version);
+		trace(url);
+		for (String d : developers)
+			pom.addDeveloper(d);
+
+		Set<String> exports = OSGiHeader.parseHeader(
+				manifest.getMainAttributes().getValue(Constants.EXPORT_PACKAGE)).keySet();
+
+		Jar sourceJar;
+		if (source == null) {
+			trace("Splitting source code");
+			sourceJar = new Jar("source");
+			for (Map.Entry<String, Resource> entry : binaryJar.getResources().entrySet()) {
+				if (entry.getKey().startsWith("OSGI-OPT/src")) {
+					sourceJar.putResource(entry.getKey().substring("OSGI-OPT/src/".length()),
+							entry.getValue());
+				}
+			}
+			copyInfo(binaryJar, sourceJar, "source");
+		} else {
+			sourceJar = getJarFromFileOrURL(source);
+		}
+		sourceJar.calcChecksums(null);
+		
+		Jar javadocJar;
+		if (javadoc == null) {
+			trace("creating javadoc because -javadoc not used");
+			javadocJar = javadoc(getFile(original, "OSGI-OPT/src"), exports, manifest, properties);
+			if (javadocJar == null) {
+				error("Cannot find source code in OSGI-OPT/src to generate Javadoc");
+				return;
+			}
+			copyInfo(binaryJar, javadocJar, "javadoc");
+		} else {
+			trace("Loading javadoc externally %s", javadoc);
+			javadocJar = getJarFromFileOrURL(javadoc);
+		}
+		javadocJar.calcChecksums(null);
+		
+		addClose(binaryJar);
+		addClose(sourceJar);
+		addClose(javadocJar);
+
+		trace("creating bundle dir");
+		File bundle = new File(temp, "bundle");
+		bundle.mkdirs();
+
+		String prefix = pom.getArtifactId() + "-" + pom.getVersion();
+		File binaryFile = new File(bundle, prefix + ".jar");
+		File sourceFile = new File(bundle, prefix + "-sources.jar");
+		File javadocFile = new File(bundle, prefix + "-javadoc.jar");
+		File pomFile = new File(bundle, "pom.xml").getAbsoluteFile();
+		trace("creating output files %s, %s,%s, and %s", binaryFile, sourceFile, javadocFile,
+				pomFile);
+
+		IO.copy(pom.openInputStream(), pomFile);
+		trace("copied pom");
+
+		trace("writing binary %s", binaryFile);
+		binaryJar.write(binaryFile);
+
+		trace("writing source %s", sourceFile);
+		sourceJar.write(sourceFile);
+
+		trace("writing javadoc %s", javadocFile);
+		javadocJar.write(javadocFile);
+
+		sign(binaryFile, passphrase);
+		sign(sourceFile, passphrase);
+		sign(javadocFile, passphrase);
+		sign(pomFile, passphrase);
+
+		trace("create bundle");
+		Jar bundleJar = new Jar(bundle);
+		addClose(bundleJar);
+		File outputFile = getFile(output);
+		bundleJar.write(outputFile);
+		trace("created bundle %s", outputFile);
+
+		binaryJar.close();
+		sourceJar.close();
+		javadocJar.close();
+		bundleJar.close();
+		if (!nodelete)
+			IO.delete(temp);
+	}
+
+	private void copyInfo(Jar source, Jar dest, String type) throws Exception {
+		source.ensureManifest();
+		dest.ensureManifest();
+		copyInfoResource( source, dest, "LICENSE");
+		copyInfoResource( source, dest, "LICENSE.html");
+		copyInfoResource( source, dest, "about.html");
+		
+		Manifest sm = source.getManifest();
+		Manifest dm = dest.getManifest();
+		copyInfoHeader( sm, dm, "Bundle-Description","");
+		copyInfoHeader( sm, dm, "Bundle-Vendor","");
+		copyInfoHeader( sm, dm, "Bundle-Copyright","");
+		copyInfoHeader( sm, dm, "Bundle-DocURL","");
+		copyInfoHeader( sm, dm, "Bundle-License","");
+		copyInfoHeader( sm, dm, "Bundle-Name", " " + type);
+		copyInfoHeader( sm, dm, "Bundle-SymbolicName", "." + type);
+		copyInfoHeader( sm, dm, "Bundle-Version", "");
+	}
+
+	private void copyInfoHeader(Manifest sm, Manifest dm, String key, String value) {
+		String v = sm.getMainAttributes().getValue(key);
+		if ( v == null) {
+			trace("no source for " + key);
+			return;
+		}
+		
+		if ( dm.getMainAttributes().getValue(key) != null) {
+			trace("already have " + key );
+			return;
+		}
+		
+		dm.getMainAttributes().putValue(key, v + value);
+	}
+
+	private void copyInfoResource(Jar source, Jar dest, String type) {
+		if ( source.getResources().containsKey(type) && !dest.getResources().containsKey(type))
+			dest.putResource(type, source.getResource(type));
+	}
+
+	/**
+	 * @return
+	 * @throws IOException
+	 * @throws MalformedURLException
+	 */
+	protected Jar getJarFromFileOrURL(String spec) throws IOException, MalformedURLException {
+		Jar jar;
+		File jarFile = getFile(spec);
+		if (jarFile.exists()) {
+			jar = new Jar(jarFile);
+		} else {
+			URL url = new URL(spec);
+			InputStream in = url.openStream();
+			try {
+				jar = new Jar(url.getFile(), in);
+			} finally {
+				in.close();
+			}
+		}
+		addClose(jar);
+		return jar;
+	}
+
+	private void sign(File file, String passphrase) throws Exception {
+		trace("signing %s", file);
+		File asc = new File(file.getParentFile(), file.getName() + ".asc");
+		asc.delete();
+
+		Command command = new Command();
+		command.setTrace();
+
+		command.add(getProperty("gpgp", "gpg"));
+		if (passphrase != null)
+			command.add("--passphrase", passphrase);
+		command.add("-ab", "--sign"); // not the -b!!
+		command.add(file.getAbsolutePath());
+		System.out.println(command);
+		StringBuffer stdout = new StringBuffer();
+		StringBuffer stderr = new StringBuffer();
+		int result = command.execute(stdout, stderr);
+		if (result != 0) {
+			error("gpg signing %s failed because %s", file, "" + stdout + stderr);
+		}
+	}
+
+	private Jar javadoc(File source, Set<String> exports, Manifest m, Properties p)
+			throws Exception {
+		File tmp = new File(temp, "javadoc");
+		tmp.mkdirs();
+
+		Command command = new Command();
+		command.add(getProperty("javadoc", "javadoc"));
+		command.add("-quiet");
+		command.add("-protected");
+		// command.add("-classpath");
+		// command.add(binary.getAbsolutePath());
+		command.add("-d");
+		command.add(tmp.getAbsolutePath());
+		command.add("-charset");
+		command.add("UTF-8");
+		command.add("-sourcepath");
+		command.add(source.getAbsolutePath());
+
+		Attributes attr = m.getMainAttributes();
+		Properties pp = new Properties(p);
+		set(pp, "-doctitle", description(attr));
+		set(pp, "-header", description(attr));
+		set(pp, "-windowtitle", name(attr));
+		set(pp, "-bottom", copyright(attr));
+		set(pp, "-footer", license(attr));
+
+		command.add("-tag");
+		command.add("Immutable:t:Immutable");
+		command.add("-tag");
+		command.add("ThreadSafe:t:ThreadSafe");
+		command.add("-tag");
+		command.add("NotThreadSafe:t:NotThreadSafe");
+		command.add("-tag");
+		command.add("GuardedBy:mf:Guarded By:");
+		command.add("-tag");
+		command.add("security:m:Required Permissions");
+		command.add("-tag");
+		command.add("noimplement:t:Consumers of this API must not implement this interface");
+
+		for (Enumeration<?> e = pp.propertyNames(); e.hasMoreElements();) {
+			String key = (String) e.nextElement();
+			String value = pp.getProperty(key);
+
+			if (key.startsWith("javadoc")) {
+				key = key.substring("javadoc".length());
+				removeDuplicateMarker(key);
+				command.add(key);
+				command.add(value);
+			}
+		}
+		for (String packageName : exports) {
+			command.add(packageName);
+		}
+
+		StringBuffer out = new StringBuffer();
+		StringBuffer err = new StringBuffer();
+
+		System.out.println(command);
+
+		int result = command.execute(out, err);
+		if (result != 0) {
+			warning("Error during execution of javadoc command: %s\n******************\n%s", out,
+					err);
+		}
+		Jar jar = new Jar(tmp);
+		addClose(jar);
+		return jar;
+	}
+
+	/**
+	 * Generate a license string
+	 * 
+	 * @param attr
+	 * @return
+	 */
+	private String license(Attributes attr) {
+		Map<String, Map<String, String>> map = Processor.parseHeader(
+				attr.getValue(Constants.BUNDLE_LICENSE), null);
+		if (map.isEmpty())
+			return null;
+
+		StringBuilder sb = new StringBuilder();
+		String sep = "Licensed under ";
+		for (Map.Entry<String, Map<String, String>> entry : map.entrySet()) {
+			sb.append(sep);
+			String key = entry.getKey();
+			String link = entry.getValue().get("link");
+			String description = entry.getValue().get("description");
+
+			if (description == null)
+				description = key;
+
+			if (link != null) {
+				sb.append("<a href='");
+				sb.append(link);
+				sb.append("'>");
+			}
+			sb.append(description);
+			if (link != null) {
+				sb.append("</a>");
+			}
+			sep = ",<br/>";
+		}
+
+		return sb.toString();
+	}
+
+	/**
+	 * Generate the copyright statement.
+	 * 
+	 * @param attr
+	 * @return
+	 */
+	private String copyright(Attributes attr) {
+		return attr.getValue(Constants.BUNDLE_COPYRIGHT);
+	}
+
+	private String name(Attributes attr) {
+		String name = attr.getValue(Constants.BUNDLE_NAME);
+		if (name == null)
+			name = attr.getValue(Constants.BUNDLE_SYMBOLICNAME);
+		return name;
+	}
+
+	private String description(Attributes attr) {
+		String descr = attr.getValue(Constants.BUNDLE_DESCRIPTION);
+		if (descr == null)
+			descr = attr.getValue(Constants.BUNDLE_NAME);
+		if (descr == null)
+			descr = attr.getValue(Constants.BUNDLE_SYMBOLICNAME);
+		return descr;
+	}
+
+	private void set(Properties pp, String option, String defaultValue) {
+		String key = "javadoc" + option;
+		String existingValue = pp.getProperty(key);
+		if (existingValue != null)
+			return;
+
+		pp.setProperty(key, defaultValue);
+	}
+
+	
+	/**
+	 * View - Show the dependency details of an artifact
+	 */
+	
+
+	static Executor executor = Executors.newCachedThreadPool();
+	static Pattern GROUP_ARTIFACT_VERSION = Pattern.compile("([^+]+)\\+([^+]+)\\+([^+]+)");
+	void view( String args[], int i) throws Exception {
+		Maven maven = new Maven(executor);
+		OutputStream out = System.out;
+		
+		List<URI>	urls = new ArrayList<URI>();
+		
+		while ( i < args.length && args[i].startsWith("-")) {
+			if( "-r".equals(args[i])) {
+				URI uri = new URI(args[++i]);
+				urls.add( uri );
+				System.out.println("URI for repo " + uri);
+			}
+			else
+				if ( "-o".equals(args[i])) {
+					out = new FileOutputStream(args[++i]);
+				}
+				else
+					throw new IllegalArgumentException("Unknown option: " + args[i]);
+			
+			i++;
+		}
+		
+		URI[] urls2 = urls.toArray(new URI[urls.size()]);
+		PrintWriter pw = new PrintWriter(out);
+		
+		while ( i < args.length) {
+			String ref = args[i++];
+			pw.println("Ref " + ref);
+			
+			Matcher matcher = GROUP_ARTIFACT_VERSION.matcher(ref);
+			if (matcher.matches()) {
+				
+				String group = matcher.group(1);
+				String artifact = matcher.group(2);
+				String version = matcher.group(3);
+				CachedPom pom = maven.getPom(group, artifact, version, urls2);
+				
+				Builder a = new Builder();
+				a.setProperty("Private-Package", "*");
+				Set<Pom> dependencies = pom.getDependencies(Scope.compile, urls2);
+				for ( Pom dep : dependencies ) {
+					System.out.printf( "%20s %-20s %10s\n", dep.getGroupId(), dep.getArtifactId(), dep.getVersion());
+					a.addClasspath(dep.getArtifact());
+				}
+				pw.println(a.getClasspath());
+				a.build();
+
+				TreeSet<String> sorted = new TreeSet<String>( a.getImports().keySet());
+				for ( String p :sorted) {
+					pw.printf("%-40s\n",p);
+				}
+//				for ( Map.Entry<String, Set<String>> entry : a.getUses().entrySet()) {
+//					String from = entry.getKey();
+//					for ( String uses : entry.getValue()) {
+//						System.out.printf("%40s %s\n", from, uses);
+//						from = "";
+//					}
+//				}
+				a.close();
+			} else
+				System.err.println("Wrong, must look like group+artifact+version, is " + ref);
+			
+		}
+	}
+	
+	
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/MavenDependencyGraph.java b/bundleplugin/src/main/java/aQute/bnd/maven/MavenDependencyGraph.java
new file mode 100644
index 0000000..6278be2
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenDependencyGraph.java
@@ -0,0 +1,139 @@
+package aQute.bnd.maven;
+
+import java.net.*;
+import java.util.*;
+
+import javax.xml.parsers.*;
+import javax.xml.xpath.*;
+
+import org.w3c.dom.*;
+
+public class MavenDependencyGraph {
+	final static DocumentBuilderFactory	docFactory		= DocumentBuilderFactory.newInstance();
+	final static XPathFactory			xpathFactory	= XPathFactory.newInstance();
+	final List<Artifact>				dependencies	= new ArrayList<Artifact>();
+	final List<URL>						repositories	= new ArrayList<URL>();
+	final XPath							xpath			= xpathFactory.newXPath();
+	final Map<URL, Artifact>			cache			= new HashMap<URL, Artifact>();
+	Artifact						root;
+
+	enum Scope {
+		COMPILE, RUNTIME, TEST, PROVIDED, SYSTEM, IMPORT,
+	};
+
+	
+	public class Artifact {
+
+		String			groupId;
+		String			artifactId;
+		String			version;
+		Scope			scope			= Scope.COMPILE;
+		boolean			optional;
+		String			type;
+		URL				url;
+		List<Artifact>	dependencies	= new ArrayList<Artifact>();
+
+		public Artifact(URL url) throws Exception {
+			if (url != null) {
+				this.url = url;
+				DocumentBuilder db = docFactory.newDocumentBuilder();
+				Document doc = db.parse(url.toString());
+				Node node = (Node) xpath.evaluate("/project", doc, XPathConstants.NODE);
+
+				groupId = xpath.evaluate("groupId", node);
+				artifactId = xpath.evaluate("artifactId", node);
+				version = xpath.evaluate("version", node);
+				type = xpath.evaluate("type", node);
+				optional = (Boolean) xpath.evaluate("optinal", node, XPathConstants.BOOLEAN);
+				String scope = xpath.evaluate("scope", node);
+				if (scope != null && scope.length() > 0) {
+					this.scope = Scope.valueOf(scope.toUpperCase());
+				}
+				NodeList evaluate = (NodeList) xpath.evaluate("//dependencies/dependency", doc,
+						XPathConstants.NODESET);
+
+				for (int i = 0; i < evaluate.getLength(); i++) {
+					Node childNode = evaluate.item(i);
+					Artifact artifact = getArtifact(xpath.evaluate("groupId", childNode), xpath
+							.evaluate("artifactId", childNode), xpath.evaluate("version", childNode));
+					add(artifact);
+				}
+			}
+		}
+		
+		
+
+		public void add(Artifact artifact) {
+			dependencies.add(artifact);
+		}
+
+
+
+		public String toString() {
+			return groupId + "." + artifactId + "-" + version + "[" + scope + "," + optional + "]";
+		}
+
+		public String getPath() throws URISyntaxException {
+			return groupId.replace('.', '/') + "/" + artifactId + "/" + version + "/" + artifactId
+					+ "-" + version;
+		}
+
+	}
+
+	public void addRepository(URL repository) {
+		repositories.add(repository);
+	}
+
+	/**
+	 * @param xp
+	 * @param node
+	 * @param d
+	 * @throws XPathExpressionException
+	 */
+
+	public Artifact getArtifact(String groupId, String artifactId, String version) {
+		for (URL repository : repositories) {
+			String path = getPath(repository.toString(), groupId, artifactId, version);
+
+			try {
+				URL url = new URL(path + ".pom");
+				if (cache.containsKey(url)) {
+					return cache.get(url);
+				} else {
+					return new Artifact(url);
+				}
+			} catch (Exception e) {
+				System.err.println("Failed to get " + artifactId + " from " + repository);
+			}
+		}
+		return null;
+	}
+
+	private String getPath(String path, String groupId, String artifactId, String version) {
+		StringBuilder sb = new StringBuilder();
+		sb.append(path);
+		if (!path.endsWith("/"))
+			sb.append("/");
+
+		sb.append(groupId.replace('.', '/'));
+		sb.append('/');
+		sb.append(artifactId);
+		sb.append('/');
+		sb.append(version);
+		sb.append('/');
+		sb.append(artifactId);
+		sb.append('-');
+		sb.append(version);
+		return null;
+	}
+
+	
+	
+	public void addArtifact( Artifact artifact ) throws Exception {
+		if ( root == null)
+			root = new Artifact(null);
+		root.add(artifact);
+	}
+	
+	
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/MavenDeploy.java b/bundleplugin/src/main/java/aQute/bnd/maven/MavenDeploy.java
new file mode 100644
index 0000000..24981ca
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenDeploy.java
@@ -0,0 +1,186 @@
+package aQute.bnd.maven;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.bnd.build.*;
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.libg.command.*;
+import aQute.libg.reporter.*;
+
+public class MavenDeploy implements Deploy, Plugin {
+
+	String		repository;
+	String		url;
+	String		homedir;
+	String		keyname;
+
+	String		passphrase;
+	Reporter	reporter;
+
+	public void setProperties(Map<String, String> map) {
+		repository = map.get("repository");
+		url = map.get("url");
+		passphrase = map.get("passphrase");
+		homedir = map.get("homedir");
+		keyname = map.get("keyname");
+
+		if (url == null)
+			throw new IllegalArgumentException("MavenDeploy plugin must get a repository URL");
+		if (repository == null)
+			throw new IllegalArgumentException("MavenDeploy plugin must get a repository name");
+	}
+
+	public void setReporter(Reporter processor) {
+		this.reporter = processor;
+	}
+
+	/**
+	 */
+	public boolean deploy(Project project, Jar original) throws Exception {
+		Map<String, Map<String, String>> deploy = project.parseHeader(project
+				.getProperty(Constants.DEPLOY));
+
+		Map<String, String> maven = deploy.get(repository);
+		if (maven == null)
+			return false; // we're not playing for this bundle
+
+		project.progress("deploying %s to Maven repo: %s", original, repository);
+		File target = project.getTarget();
+		File tmp = Processor.getFile(target, repository);
+		tmp.mkdirs();
+
+		Manifest manifest = original.getManifest();
+		if (manifest == null)
+			project.error("Jar has no manifest: %s", original);
+		else {
+			project.progress("Writing pom.xml");
+			PomResource pom = new PomResource(manifest);
+			pom.setProperties(maven);
+			File pomFile = write(tmp, pom, "pom.xml");
+
+			Jar main = new Jar("main");
+			Jar src = new Jar("src");
+			try {
+				split(original, main, src);
+				Map<String, Map<String, String>> exports = project.parseHeader(manifest
+						.getMainAttributes().getValue(Constants.EXPORT_PACKAGE));
+				File jdoc = new File(tmp, "jdoc");
+				jdoc.mkdirs();
+				project.progress("Generating Javadoc for: " + exports.keySet());
+				Jar javadoc = javadoc(jdoc, project, exports.keySet());
+				project.progress("Writing javadoc jar");
+				File javadocFile = write(tmp, new JarResource(javadoc), "javadoc.jar");
+				project.progress("Writing main file");
+				File mainFile = write(tmp, new JarResource(main), "main.jar");
+				project.progress("Writing sources file");
+				File srcFile = write(tmp, new JarResource(main), "src.jar");
+
+				project.progress("Deploying main file");
+				maven_gpg_sign_and_deploy(project, mainFile, null, pomFile);
+				project.progress("Deploying main sources file");
+				maven_gpg_sign_and_deploy(project, srcFile, "sources", null);
+				project.progress("Deploying main javadoc file");
+				maven_gpg_sign_and_deploy(project, javadocFile, "javadoc", null);
+
+			} finally {
+				main.close();
+				src.close();
+			}
+		}
+		return true;
+	}
+
+	private void split(Jar original, Jar main, Jar src) {
+		for (Map.Entry<String, Resource> e : original.getResources().entrySet()) {
+			String path = e.getKey();
+			if (path.startsWith("OSGI-OPT/src/")) {
+				src.putResource(path.substring("OSGI-OPT/src/".length()), e.getValue());
+			} else {
+				main.putResource(path, e.getValue());
+			}
+		}
+	}
+
+	// gpg:sign-and-deploy-file \
+	// -Durl=http://oss.sonatype.org/service/local/staging/deploy/maven2
+	// \
+	// -DrepositoryId=sonatype-nexus-staging \
+	// -DupdateReleaseInfo=true \
+	// -DpomFile=pom.xml \
+	// -Dfile=/Ws/bnd/biz.aQute.bndlib/tmp/biz.aQute.bndlib.jar \
+	// -Dpassphrase=a1k3v3t5x3
+
+	private void maven_gpg_sign_and_deploy(Project b, File file, String classifier, File pomFile)
+			throws Exception {
+		Command command = new Command();
+		command.setTrace();
+		command.add(b.getProperty("mvn", "mvn"));
+		command.add("gpg:sign-and-deploy-file", "-DreleaseInfo=true", "-DpomFile=pom.xml");
+		command.add("-Dfile=" + file.getAbsolutePath());
+		command.add("-DrepositoryId=" + repository);
+		command.add("-Durl=" + url);
+		optional(command, "passphrase", passphrase);
+		optional(command, "keyname", keyname);
+		optional(command, "homedir", homedir);
+		optional(command, "classifier", classifier);
+		optional(command, "pomFile", pomFile == null ? null : pomFile.getAbsolutePath());
+
+		StringBuffer stdout = new StringBuffer();
+		StringBuffer stderr = new StringBuffer();
+
+		int result = command.execute(stdout, stderr);
+		if (result != 0) {
+			b.error("Maven deploy to %s failed to sign and transfer %s because %s", repository,
+					file, "" + stdout + stderr);
+		}
+	}
+
+	private void optional(Command command, String key, String value) {
+		if (value == null)
+			return;
+
+		command.add("-D=" + value);
+	}
+
+	private Jar javadoc(File tmp, Project b, Set<String> exports) throws Exception {
+		Command command = new Command();
+		
+		command.add(b.getProperty("javadoc", "javadoc"));
+		command.add("-d");
+		command.add(tmp.getAbsolutePath());
+		command.add("-sourcepath");
+		command.add( Processor.join(b.getSourcePath(),File.pathSeparator));
+
+		for (String packageName : exports) {
+			command.add(packageName);
+		}
+
+		StringBuffer out = new StringBuffer();
+		StringBuffer err = new StringBuffer();
+		Command c = new Command();
+		c.setTrace();
+		int result = c.execute(out, err);
+		if (result == 0) {
+			Jar jar = new Jar(tmp);
+			b.addClose(jar);
+			return jar;
+		}
+		b.error("Error during execution of javadoc command: %s / %s", out, err);
+		return null;
+	}
+
+	private File write(File base, Resource r, String fileName) throws Exception {
+		File f = Processor.getFile(base, fileName);
+		OutputStream out = new FileOutputStream(f);
+		try {
+			r.write(out);
+		} finally {
+			out.close();
+		}
+		return f;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/MavenDeployCmd.java b/bundleplugin/src/main/java/aQute/bnd/maven/MavenDeployCmd.java
new file mode 100644
index 0000000..aaa23ff
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenDeployCmd.java
@@ -0,0 +1,221 @@
+package aQute.bnd.maven;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.bnd.build.*;
+import aQute.lib.osgi.*;
+import aQute.libg.command.*;
+import aQute.libg.reporter.*;
+
+public class MavenDeployCmd extends Processor {
+
+	String		repository	= "nexus";
+	String		url			= "http://oss.sonatype.org/service/local/staging/deploy/maven2";
+	String		homedir;
+	String		keyname;
+
+	String		passphrase;
+	Reporter	reporter;
+
+	/**
+	 * maven deploy [-url repo] [-passphrase passphrase] [-homedir homedir]
+	 * [-keyname keyname] bundle ...
+	 * 
+	 * @param args
+	 * @param i
+	 * @throws Exception
+	 */
+	void run(String args[], int i) throws Exception {
+		if (i >= args.length) {
+			System.err
+					.println("Usage:\n");
+			System.err.println("  deploy [-url repo] [-passphrase passphrase] [-homedir homedir] [-keyname keyname] bundle ...");
+			System.err.println("  settings");
+			return;
+		}
+
+		@SuppressWarnings("unused") String cmd = args[i++];
+		
+		while (i < args.length && args[i].startsWith("-")) {
+			String option = args[i];
+			if (option.equals("-url"))
+				repository = args[++i];
+			else if (option.equals("-passphrase"))
+				passphrase = args[++i];
+			else if (option.equals("-url"))
+				homedir = args[++i];
+			else if (option.equals("-keyname"))
+				keyname = args[++i];
+			else
+				error("Invalid command ");
+		}
+
+		
+	}
+
+	public void setProperties(Map<String, String> map) {
+		repository = map.get("repository");
+		url = map.get("url");
+		passphrase = map.get("passphrase");
+		homedir = map.get("homedir");
+		keyname = map.get("keyname");
+
+		if (url == null)
+			throw new IllegalArgumentException("MavenDeploy plugin must get a repository URL");
+		if (repository == null)
+			throw new IllegalArgumentException("MavenDeploy plugin must get a repository name");
+	}
+
+	public void setReporter(Reporter processor) {
+		this.reporter = processor;
+	}
+
+	/**
+	 */
+	public boolean deploy(Project project, Jar original) throws Exception {
+		Map<String, Map<String, String>> deploy = project.parseHeader(project
+				.getProperty(Constants.DEPLOY));
+
+		Map<String, String> maven = deploy.get(repository);
+		if (maven == null)
+			return false; // we're not playing for this bundle
+
+		project.progress("deploying %s to Maven repo: %s", original, repository);
+		File target = project.getTarget();
+		File tmp = Processor.getFile(target, repository);
+		tmp.mkdirs();
+
+		Manifest manifest = original.getManifest();
+		if (manifest == null)
+			project.error("Jar has no manifest: %s", original);
+		else {
+			project.progress("Writing pom.xml");
+			PomResource pom = new PomResource(manifest);
+			pom.setProperties(maven);
+			File pomFile = write(tmp, pom, "pom.xml");
+
+			Jar main = new Jar("main");
+			Jar src = new Jar("src");
+			try {
+				split(original, main, src);
+				Map<String, Map<String, String>> exports = project.parseHeader(manifest
+						.getMainAttributes().getValue(Constants.EXPORT_PACKAGE));
+				File jdoc = new File(tmp, "jdoc");
+				jdoc.mkdirs();
+				project.progress("Generating Javadoc for: " + exports.keySet());
+				Jar javadoc = javadoc(jdoc, project, exports.keySet());
+				project.progress("Writing javadoc jar");
+				File javadocFile = write(tmp, new JarResource(javadoc), "javadoc.jar");
+				project.progress("Writing main file");
+				File mainFile = write(tmp, new JarResource(main), "main.jar");
+				project.progress("Writing sources file");
+				File srcFile = write(tmp, new JarResource(main), "src.jar");
+
+				project.progress("Deploying main file");
+				maven_gpg_sign_and_deploy(project, mainFile, null, pomFile);
+				project.progress("Deploying main sources file");
+				maven_gpg_sign_and_deploy(project, srcFile, "sources", null);
+				project.progress("Deploying main javadoc file");
+				maven_gpg_sign_and_deploy(project, javadocFile, "javadoc", null);
+
+			} finally {
+				main.close();
+				src.close();
+			}
+		}
+		return true;
+	}
+
+	private void split(Jar original, Jar main, Jar src) {
+		for (Map.Entry<String, Resource> e : original.getResources().entrySet()) {
+			String path = e.getKey();
+			if (path.startsWith("OSGI-OPT/src/")) {
+				src.putResource(path.substring("OSGI-OPT/src/".length()), e.getValue());
+			} else {
+				main.putResource(path, e.getValue());
+			}
+		}
+	}
+
+	// gpg:sign-and-deploy-file \
+	// -Durl=http://oss.sonatype.org/service/local/staging/deploy/maven2
+	// \
+	// -DrepositoryId=sonatype-nexus-staging \
+	// -DupdateReleaseInfo=true \
+	// -DpomFile=pom.xml \
+	// -Dfile=/Ws/bnd/biz.aQute.bndlib/tmp/biz.aQute.bndlib.jar \
+	// -Dpassphrase=a1k3v3t5x3
+
+	private void maven_gpg_sign_and_deploy(Project b, File file, String classifier, File pomFile)
+			throws Exception {
+		Command command = new Command();
+		command.setTrace();
+		command.add(b.getProperty("mvn", "mvn"));
+		command.add("gpg:sign-and-deploy-file", "-DreleaseInfo=true", "-DpomFile=pom.xml");
+		command.add("-Dfile=" + file.getAbsolutePath());
+		command.add("-DrepositoryId=" + repository);
+		command.add("-Durl=" + url);
+		optional(command, "passphrase", passphrase);
+		optional(command, "keyname", keyname);
+		optional(command, "homedir", homedir);
+		optional(command, "classifier", classifier);
+		optional(command, "pomFile", pomFile == null ? null : pomFile.getAbsolutePath());
+
+		StringBuffer stdout = new StringBuffer();
+		StringBuffer stderr = new StringBuffer();
+
+		int result = command.execute(stdout, stderr);
+		if (result != 0) {
+			b.error("Maven deploy to %s failed to sign and transfer %s because %s", repository,
+					file, "" + stdout + stderr);
+		}
+	}
+
+	private void optional(Command command, String key, String value) {
+		if (value == null)
+			return;
+
+		command.add("-D=" + value);
+	}
+
+	private Jar javadoc(File tmp, Project b, Set<String> exports) throws Exception {
+		Command command = new Command();
+
+		command.add(b.getProperty("javadoc", "javadoc"));
+		command.add("-d");
+		command.add(tmp.getAbsolutePath());
+		command.add("-sourcepath");
+		command.add(Processor.join(b.getSourcePath(), File.pathSeparator));
+
+		for (String packageName : exports) {
+			command.add(packageName);
+		}
+
+		StringBuffer out = new StringBuffer();
+		StringBuffer err = new StringBuffer();
+		Command c = new Command();
+		c.setTrace();
+		int result = c.execute(out, err);
+		if (result == 0) {
+			Jar jar = new Jar(tmp);
+			b.addClose(jar);
+			return jar;
+		}
+		b.error("Error during execution of javadoc command: %s / %s", out, err);
+		return null;
+	}
+
+	private File write(File base, Resource r, String fileName) throws Exception {
+		File f = Processor.getFile(base, fileName);
+		OutputStream out = new FileOutputStream(f);
+		try {
+			r.write(out);
+		} finally {
+			out.close();
+		}
+		return f;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/MavenGroup.java b/bundleplugin/src/main/java/aQute/bnd/maven/MavenGroup.java
new file mode 100644
index 0000000..2d49be6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenGroup.java
@@ -0,0 +1,27 @@
+package aQute.bnd.maven;
+
+import java.util.*;
+
+import aQute.bnd.service.*;
+import aQute.libg.reporter.*;
+
+public class MavenGroup implements BsnToMavenPath, Plugin {
+    String    groupId = "";
+
+    public String[] getGroupAndArtifact(String bsn) {
+        String[] result = new String[2];
+        result[0] = groupId;
+        result[1] = bsn;
+        return result;
+    }
+
+    public void setProperties(Map<String, String> map) {
+        if (map.containsKey("groupId")) {
+            groupId = map.get("groupId");
+        }
+    }
+
+    public void setReporter(Reporter processor) {
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/MavenRepository.java b/bundleplugin/src/main/java/aQute/bnd/maven/MavenRepository.java
new file mode 100644
index 0000000..506ea53
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenRepository.java
@@ -0,0 +1,194 @@
+package aQute.bnd.maven;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.libg.reporter.*;
+import aQute.libg.version.*;
+
+public class MavenRepository implements RepositoryPlugin, Plugin, BsnToMavenPath {
+
+	public static String	NAME	= "name";
+
+	File					root;
+	Reporter				reporter;
+	String					name;
+
+	public String toString() {
+		return "maven:" + root;
+	}
+
+	public boolean canWrite() {
+		return false;
+	}
+
+	public File[] get(String bsn, String version) throws Exception {
+		VersionRange range = new VersionRange("0");
+		if (version != null)
+			range = new VersionRange(version);
+
+		List<BsnToMavenPath> plugins = ((Processor) reporter).getPlugins(BsnToMavenPath.class);
+		if ( plugins.isEmpty())
+			plugins.add(this);
+		
+		for (BsnToMavenPath cvr : plugins) {
+			String[] paths = cvr.getGroupAndArtifact(bsn);
+			if (paths != null) {
+				File[] files = find(paths[0], paths[1], range);
+				if (files != null)
+					return files;
+			}
+		}
+		reporter.trace("Cannot find in maven: %s-%s", bsn, version);
+		return null;
+	}
+
+	File[] find(String groupId, String artifactId, VersionRange range) {
+		String path = groupId.replace(".", "/");
+		File vsdir = Processor.getFile(root, path);
+		if (!vsdir.isDirectory())
+			return null;
+
+		vsdir = Processor.getFile(vsdir, artifactId);
+
+		List<File> result = new ArrayList<File>();
+		if (vsdir.isDirectory()) {
+			String versions[] = vsdir.list();
+			for (String v : versions) {
+				String vv = Analyzer.cleanupVersion(v);
+				if (Verifier.isVersion(vv)) {
+					Version vvv = new Version(vv);
+					if (range.includes(vvv)) {
+						File file = Processor.getFile(vsdir, v + "/" + artifactId + "-" + v
+								+ ".jar");
+						if (file.isFile())
+							result.add(file);
+						else
+							reporter.warning("Expected maven entry was not a valid file %s ", file);
+					}
+				} else {
+					reporter
+							.warning(
+									"Expected a version directory in maven: dir=%s raw-version=%s cleaned-up-version=%s",
+									vsdir, vv, v);
+				}
+			}
+		} else
+			return null;
+
+		return result.toArray(new File[result.size()]);
+	}
+
+	public List<String> list(String regex) {
+		List<String> bsns = new ArrayList<String>();
+		Pattern match = Pattern.compile(".*");
+		if (regex != null)
+			match = Pattern.compile(regex);
+		find(bsns, match, root, "");
+		return bsns;
+	}
+
+	void find(List<String> bsns, Pattern pattern, File base, String name) {
+		if (base.isDirectory()) {
+			String list[] = base.list();
+			boolean found = false;
+			for (String entry : list) {
+				char c = entry.charAt(0);
+				if (c >= '0' && c <= '9') {
+					if (pattern.matcher(name).matches())
+						found = true;
+				} else {
+					String nextName = entry;
+					if (name.length() != 0)
+						nextName = name + "." + entry;
+
+					File next = Processor.getFile(base, entry);
+					find(bsns, pattern, next, nextName);
+				}
+			}
+			if (found)
+				bsns.add(name);
+		}
+	}
+
+	public File put(Jar jar) throws Exception {
+		throw new IllegalStateException("Maven does not support the put command");
+	}
+
+	public List<Version> versions(String bsn) throws Exception {
+		
+		File files[] = get( bsn, null);
+		List<Version> versions = new ArrayList<Version>();
+		for ( File f : files ) {
+			Version v = new Version( f.getParentFile().getName());
+			versions.add(v);
+		}
+		return versions;
+	}
+
+	public void setProperties(Map<String, String> map) {
+		File home = new File("");
+		String root = map.get("root");
+		if (root == null) {
+			home = new File( System.getProperty("user.home") );
+			this.root = Processor.getFile(home , ".m2/repository").getAbsoluteFile();
+		} else
+			this.root = Processor.getFile(home, root).getAbsoluteFile();
+		
+		if (!this.root.isDirectory()) {
+			reporter.error("Maven repository did not get a proper URL to the repository %s", root);
+		}
+		name = (String) map.get(NAME);
+
+	}
+
+	public void setReporter(Reporter processor) {
+		this.reporter = processor;
+	}
+
+	public String[] getGroupAndArtifact(String bsn) {
+		String groupId;
+		String artifactId;
+		int n = bsn.indexOf('.');
+		
+		while ( n > 0 ) {
+			artifactId = bsn.substring(n+1);
+			groupId = bsn.substring(0,n);
+			
+			File gdir = new File(root, groupId.replace('.',File.separatorChar)).getAbsoluteFile();
+			File adir = new File( gdir, artifactId).getAbsoluteFile();
+			if ( adir.isDirectory() )
+				return new String[] {groupId, artifactId};
+			
+			n = bsn.indexOf('.',n+1);
+		}
+		return null;
+	}
+	
+	public String getName() {
+		if (name == null) {
+			return toString();
+		}
+		return name;
+	}
+
+	public File get(String bsn, String range, Strategy strategy, Map<String,String> properties) throws Exception {
+		File[] files = get(bsn, range);
+		if (files.length >= 0) {
+			switch (strategy) {
+			case LOWEST:
+				return files[0];
+			case HIGHEST:
+				return files[files.length - 1];
+			}
+		}
+		return null;
+	}
+
+	public void setRoot( File f  ) {
+		root = f;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java b/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java
new file mode 100644
index 0000000..3ed560d
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java
@@ -0,0 +1,247 @@
+package aQute.bnd.maven;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.tag.*;
+import aQute.libg.version.*;
+
+public class PomFromManifest extends WriteResource {
+	final Manifest			manifest;
+	private List<String>	scm			= new ArrayList<String>();
+	private List<String>	developers	= new ArrayList<String>();
+	final static Pattern	NAME_URL	= Pattern.compile("(.*)(http://.*)");
+	String					xbsn;
+	String					xversion;
+	String					xgroupId;
+	String					xartifactId;
+	private String			projectURL;
+
+	public String getBsn() {
+		if (xbsn == null)
+			xbsn = manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
+		if (xbsn == null)
+			throw new RuntimeException("Cannot create POM unless bsn is set");
+
+		xbsn = xbsn.trim();
+		int n = xbsn.lastIndexOf('.');
+		if (n < 0) {
+			n = xbsn.length();
+			xbsn = xbsn + "." + xbsn;
+		}
+
+		if (xgroupId == null)
+			xgroupId = xbsn.substring(0, n);
+		if (xartifactId == null) {
+			xartifactId = xbsn.substring(n + 1);
+			n = xartifactId.indexOf(';');
+			if (n > 0)
+				xartifactId = xartifactId.substring(0, n).trim();
+		}
+
+		return xbsn;
+	}
+
+	public String getGroupId() {
+		getBsn();
+		return xgroupId;
+	}
+
+	public String getArtifactId() {
+		getBsn();
+		return xartifactId;
+	}
+
+	public Version getVersion() {
+		if (xversion != null)
+			return new Version(xversion);
+		String version = manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
+		Version v = new Version(version);
+		return new Version(v.getMajor(), v.getMinor(), v.getMicro());
+	}
+
+	public PomFromManifest(Manifest manifest) {
+		this.manifest = manifest;
+	}
+
+	@Override public long lastModified() {
+		return 0;
+	}
+
+	@Override public void write(OutputStream out) throws IOException {
+		PrintWriter ps = new PrintWriter(out);
+
+		String name = manifest.getMainAttributes().getValue(Analyzer.BUNDLE_NAME);
+
+		String description = manifest.getMainAttributes().getValue(Constants.BUNDLE_DESCRIPTION);
+		String docUrl = manifest.getMainAttributes().getValue(Constants.BUNDLE_DOCURL);
+		String bundleVendor = manifest.getMainAttributes().getValue(Constants.BUNDLE_VENDOR);
+
+		String licenses = manifest.getMainAttributes().getValue(Constants.BUNDLE_LICENSE);
+
+		Tag project = new Tag("project");
+		project.addAttribute("xmlns", "http://maven.apache.org/POM/4.0.0");
+		project.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+		project.addAttribute("xsi:schemaLocation",
+				"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd");
+
+		project.addContent(new Tag("modelVersion").addContent("4.0.0"));
+		project.addContent(new Tag("groupId").addContent(getGroupId()));
+		project.addContent(new Tag("artifactId").addContent(getArtifactId()));
+		project.addContent(new Tag("version").addContent(getVersion().toString()));
+
+		if (description != null) {
+			new Tag(project, "description").addContent(description);
+		}
+		if (name != null) {
+			new Tag(project, "name").addContent(name);
+		}
+
+		if (projectURL != null)
+			new Tag(project, "url").addContent(projectURL);
+		else if (docUrl != null) {
+			new Tag(project, "url").addContent(docUrl);
+		} else
+			new Tag(project, "url").addContent("http://no-url");
+
+		String scmheader = manifest.getMainAttributes().getValue("Bundle-SCM");
+		if (scmheader != null)
+			scm.add(scmheader);
+
+		Tag scmtag = new Tag(project, "scm");
+		if (scm != null && !scm.isEmpty()) {
+			for (String cm : this.scm) {
+				new Tag(scmtag, "url").addContent(cm);
+				new Tag(scmtag, "connection").addContent(cm);
+				new Tag(scmtag, "developerConnection").addContent(cm);
+			}
+		} else {
+			new Tag(scmtag, "url").addContent("private");
+			new Tag(scmtag, "connection").addContent("private");
+			new Tag(scmtag, "developerConnection").addContent("private");
+		}
+
+		if (bundleVendor != null) {
+			Matcher m = NAME_URL.matcher(bundleVendor);
+			String namePart = bundleVendor;
+			String urlPart = this.projectURL;
+			if (m.matches()) {
+				namePart = m.group(1);
+				urlPart = m.group(2);
+			}
+			Tag organization = new Tag(project, "organization");
+			new Tag(organization, "name").addContent(namePart.trim());
+			if (urlPart != null) {
+				new Tag(organization, "url").addContent(urlPart.trim());
+			}
+		}
+		if (!developers.isEmpty()) {
+			Tag d = new Tag(project, "developers");
+			for (String email : developers) {
+				String id = email;
+				String xname = email;
+				String organization = null;
+
+				Matcher m = Pattern.compile("([^@]+)@([\\d\\w\\-_\\.]+)\\.([\\d\\w\\-_\\.]+)")
+						.matcher(email);
+				if (m.matches()) {
+					xname = m.group(1);
+					organization = m.group(2);
+				}
+
+				Tag developer = new Tag(d, "developer");
+				new Tag(developer, "id").addContent(id);
+				new Tag(developer, "name").addContent(xname);
+				new Tag(developer, "email").addContent(email);
+				if (organization != null)
+					new Tag(developer, "organization").addContent(organization);
+			}
+		}
+		if (licenses != null) {
+			Tag ls = new Tag(project, "licenses");
+
+			Map<String, Map<String, String>> map = Processor.parseHeader(licenses, null);
+			for (Iterator<Map.Entry<String, Map<String, String>>> e = map.entrySet().iterator(); e
+					.hasNext();) {
+
+				// Bundle-License:
+				// http://www.opensource.org/licenses/apache2.0.php; \
+				// description="${Bundle-Copyright}"; \
+				// link=LICENSE
+				//
+				//  <license>
+				//    <name>This material is licensed under the Apache
+				// Software License, Version 2.0</name>
+				//    <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+				//    <distribution>repo</distribution>
+				//    </license>
+
+				Map.Entry<String, Map<String, String>> entry = e.next();
+				Tag l = new Tag(ls, "license");
+				Map<String, String> values = entry.getValue();
+				String url = entry.getKey();
+
+				if (values.containsKey("description"))
+					tagFromMap(l, values, "description", "name", url);
+				else
+					tagFromMap(l, values, "name", "name", url);
+
+				tagFromMap(l, values, "url", "url", url);
+				tagFromMap(l, values, "distribution", "distribution", "repo");
+			}
+		}
+		project.print(0, ps);
+		ps.flush();
+	}
+
+	/**
+	 * Utility function to print a tag from a map
+	 * 
+	 * @param ps
+	 * @param values
+	 * @param string
+	 * @param tag
+	 * @param object
+	 */
+	private Tag tagFromMap(Tag parent, Map<String, String> values, String string, String tag,
+			String object) {
+		String value = (String) values.get(string);
+		if (value == null)
+			value = object;
+		if (value == null)
+			return parent;
+		new Tag(parent, tag).addContent(value.trim());
+		return parent;
+	}
+
+	public void setSCM(String scm) {
+		this.scm.add(scm);
+	}
+
+	public void setURL(String url) {
+		this.projectURL = url;
+	}
+
+	public void setBsn(String bsn) {
+		this.xbsn = bsn;
+	}
+
+	public void addDeveloper(String email) {
+		this.developers.add(email);
+	}
+
+	public void setVersion(String version) {
+		this.xversion = version;
+	}
+
+	public void setArtifact(String artifact) {
+		this.xartifactId = artifact;
+	}
+
+	public void setGroup(String group) {
+		this.xgroupId = group;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/PomParser.java b/bundleplugin/src/main/java/aQute/bnd/maven/PomParser.java
new file mode 100644
index 0000000..e529141
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/PomParser.java
@@ -0,0 +1,144 @@
+package aQute.bnd.maven;
+
+import java.io.*;
+import java.util.*;
+
+import javax.xml.parsers.*;
+import javax.xml.xpath.*;
+
+import org.w3c.dom.*;
+
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+
+/**
+ * Provides a way to parse a maven pom as properties.
+ * 
+ * This provides most of the maven elements as properties. It also
+ * provides pom.scope.[compile|test|runtime|provided|system] properties
+ * that can be appended to the build and run path. That is, they are
+ * in the correct format for this.
+ */
+public class PomParser extends Processor {
+	static DocumentBuilderFactory	dbf			= DocumentBuilderFactory.newInstance();
+	static XPathFactory				xpathf		= XPathFactory.newInstance();
+	static Set<String>				multiple	= new HashSet<String>();
+	static Set<String>				skip	= new HashSet<String>();
+
+	static {
+		dbf.setNamespaceAware(false);
+		
+		// Set all elements that need enumeration of their elements
+		// these will not use the name of the subelement but instead
+		// they use an index from 0..n
+		multiple.add("mailingLists");
+		multiple.add("pluginRepositories");
+		multiple.add("repositories");
+		multiple.add("resources");
+		multiple.add("executions");
+		multiple.add("goals");
+		multiple.add("includes");
+		multiple.add("excludes");
+
+		// These properties are not very useful and
+		// pollute the property space.
+		skip.add("plugins");
+		skip.add("dependencies");
+		skip.add("reporting");
+		skip.add("extensions");
+		
+	}
+
+	public Properties getProperties(File pom) throws Exception {
+		DocumentBuilder db = dbf.newDocumentBuilder();
+		XPath xpath = xpathf.newXPath();
+		pom = pom.getAbsoluteFile();
+		Document doc = db.parse(pom);
+		Properties p = new Properties();
+
+		// Check if there is a parent pom
+		String relativePath = xpath.evaluate("project/parent/relativePath", doc);
+		if (relativePath != null && relativePath.length()!=0) {
+			File parentPom = IO.getFile(pom.getParentFile(), relativePath);
+			if (parentPom.isFile()) {
+				Properties parentProps = getProperties(parentPom);
+				p.putAll(parentProps);
+			} else {
+				error("Parent pom for %s is not an existing file (could be directory): %s", pom, parentPom);
+			}
+		}
+
+		Element e = doc.getDocumentElement();
+		traverse("pom", e, p);
+
+		String scopes[] = { "provided", "runtime", "test", "system" };
+		NodeList set = (NodeList) xpath.evaluate("//dependency[not(scope) or scope='compile']", doc,
+				XPathConstants.NODESET);
+		if (set.getLength() != 0)
+			p.put("pom.scope.compile", toBsn(set));
+
+		for (String scope : scopes) {
+			set = (NodeList) xpath.evaluate("//dependency[scope='" + scope + "']", doc,
+					XPathConstants.NODESET);
+			if (set.getLength() != 0)
+				p.put("pom.scope." + scope, toBsn(set));
+		}
+
+		return p;
+	}
+
+	private Object toBsn(NodeList set) throws XPathExpressionException {
+		XPath xpath = xpathf.newXPath();
+		StringBuilder sb = new StringBuilder();
+		String del = "";
+		for (int i = 0; i < set.getLength(); i++) {
+			Node child = set.item(i);
+			String version = xpath.evaluate("version", child);
+			sb.append(del);
+			sb.append(xpath.evaluate("groupId", child));
+			sb.append(".");
+			sb.append(xpath.evaluate("artifactId", child));
+			if (version != null && version.trim().length()!=0) {
+				sb.append(";version=");
+				sb.append( Analyzer.cleanupVersion(version));
+			}
+			del = ", ";
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * The maven POM is quite straightforward, it is basically a structured property file.
+	 * @param name
+	 * @param parent
+	 * @param p
+	 */
+	static void traverse(String name, Node parent, Properties p) {
+		if ( skip.contains(parent.getNodeName()))
+			return;
+		
+		NodeList children = parent.getChildNodes();
+		if (multiple.contains(parent.getNodeName())) {
+			int n = 0;
+			for (int i = 0; i < children.getLength(); i++) {
+				Node child = children.item(i);
+				if (!(child instanceof Text)) {
+
+					traverse(name + "." + n++, child, p);
+				}
+			}
+		} else {
+			for (int i = 0; i < children.getLength(); i++) {
+				Node child = children.item(i);
+				if (child instanceof Text) {
+					String value = child.getNodeValue().trim();
+					if (value.length()!=0) {
+						p.put(name, value);
+					}
+				} else {
+					traverse(name + "." + child.getNodeName(), child, p);
+				}
+			}
+		}
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/PomResource.java b/bundleplugin/src/main/java/aQute/bnd/maven/PomResource.java
new file mode 100644
index 0000000..e5e6b8d
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/PomResource.java
@@ -0,0 +1,159 @@
+package aQute.bnd.maven;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.tag.*;
+
+public class PomResource extends WriteResource {
+	final Manifest				manifest;
+	private Map<String, String>	scm;
+	final static Pattern		NAME_URL	= Pattern.compile("(.*)(http://.*)");
+
+	public PomResource(Manifest manifest) {
+		this.manifest = manifest;
+	}
+
+	@Override public long lastModified() {
+		return 0;
+	}
+
+	@Override public void write(OutputStream out) throws IOException {
+		PrintWriter ps = new PrintWriter(out);
+
+		String name = manifest.getMainAttributes().getValue(Analyzer.BUNDLE_NAME);
+
+		String description = manifest.getMainAttributes().getValue(Constants.BUNDLE_DESCRIPTION);
+		String docUrl = manifest.getMainAttributes().getValue(Constants.BUNDLE_DOCURL);
+		String version = manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION);
+		String bundleVendor = manifest.getMainAttributes().getValue(Constants.BUNDLE_VENDOR);
+
+		String bsn = manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
+		String licenses = manifest.getMainAttributes().getValue(Constants.BUNDLE_LICENSE);
+
+		if (bsn == null) {
+			throw new RuntimeException("Cannot create POM unless bsn is set");
+		}
+
+		bsn = bsn.trim();
+		int n = bsn.lastIndexOf('.');
+		if (n <= 0)
+			throw new RuntimeException(
+					"Can not create POM unless Bundle-SymbolicName contains a . to separate group and  artifact id");
+
+		if (version == null)
+			version = "0";
+
+		String groupId = bsn.substring(0, n);
+		String artifactId = bsn.substring(n + 1);
+		n = artifactId.indexOf(';');
+		if (n > 0)
+			artifactId = artifactId.substring(0, n).trim();
+
+		Tag project = new Tag("project");
+		project.addAttribute("xmlns", "http://maven.apache.org/POM/4.0.0");
+		project.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
+		project.addAttribute("xmlns:xsi", "");
+		project.addAttribute("xsi:schemaLocation",
+				"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd");
+
+		project.addContent(new Tag("modelVersion").addContent("4.0.0"));
+		project.addContent(new Tag("groupId").addContent(groupId));
+		project.addContent(new Tag("artifactId").addContent(artifactId));
+		project.addContent(new Tag("version").addContent(version));
+
+		if (description != null) {
+			new Tag(project, "description").addContent(description);
+		}
+		if (name != null) {
+			new Tag(project, "name").addContent(name);
+		}
+		if (docUrl != null) {
+			new Tag(project, "url").addContent(docUrl);
+		}
+
+		if (scm != null) {
+			Tag scm = new Tag(project, "scm");
+			for (Map.Entry<String, String> e : this.scm.entrySet()) {
+				new Tag(scm, e.getKey()).addContent(e.getValue());
+			}
+		}
+
+		if (bundleVendor != null) {
+			Matcher m = NAME_URL.matcher(bundleVendor);
+			String namePart = bundleVendor;
+			String urlPart = null;
+			if (m.matches()) {
+				namePart = m.group(1);
+				urlPart = m.group(2);
+			}
+			Tag organization = new Tag(project, "organization");
+			new Tag(organization, "name").addContent(namePart.trim());
+			if (urlPart != null) {
+				new Tag(organization, "url").addContent(urlPart.trim());
+			}
+		}
+		if (licenses != null) {
+			Tag ls = new Tag(project, "licenses");
+
+			Map<String, Map<String, String>> map = Processor.parseHeader(licenses, null);
+			for (Iterator<Map.Entry<String, Map<String, String>>> e = map.entrySet().iterator(); e
+					.hasNext();) {
+
+				// Bundle-License:
+				// http://www.opensource.org/licenses/apache2.0.php; \
+				// description="${Bundle-Copyright}"; \
+				// link=LICENSE
+				//
+				//  <license>
+				//    <name>This material is licensed under the Apache
+				// Software License, Version 2.0</name>
+				//    <url>http://www.apache.org/licenses/LICENSE-2.0</url>
+				//    <distribution>repo</distribution>
+				//    </license>
+
+				Map.Entry<String, Map<String, String>> entry = e.next();
+				Tag l = new Tag(ls, "license");
+				Map<String, String> values = entry.getValue();
+				String url = entry.getKey();
+
+				if (values.containsKey("description"))
+					tagFromMap(l, values, "description", "name", url);
+				else
+					tagFromMap(l, values, "name", "name", url);
+
+				tagFromMap(l, values, "url", "url", url);
+				tagFromMap(l, values, "distribution", "distribution", "repo");
+			}
+		}
+		project.print(0, ps);
+		ps.flush();
+	}
+
+	/**
+	 * Utility function to print a tag from a map
+	 * 
+	 * @param ps
+	 * @param values
+	 * @param string
+	 * @param tag
+	 * @param object
+	 */
+	private Tag tagFromMap(Tag parent, Map<String, String> values, String string, String tag,
+			String object) {
+		String value = (String) values.get(string);
+		if (value == null)
+			value = object;
+		if (value == null)
+			return parent;
+		new Tag(parent, tag).addContent(value.trim());
+		return parent;
+	}
+
+	public void setProperties(Map<String, String> scm) {
+		this.scm = scm;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/CachedPom.java b/bundleplugin/src/main/java/aQute/bnd/maven/support/CachedPom.java
new file mode 100644
index 0000000..02449fa
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/CachedPom.java
@@ -0,0 +1,18 @@
+package aQute.bnd.maven.support;
+
+import java.io.*;
+import java.net.*;
+
+public class CachedPom extends Pom {
+	final MavenEntry				maven;
+
+	CachedPom(MavenEntry mavenEntry, URI repo) throws Exception {
+		super(mavenEntry.maven, mavenEntry.getPomFile(), repo);
+		this.maven = mavenEntry;
+	}
+
+	public File getArtifact() throws Exception {
+		return maven.getArtifact();
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/Maven.java b/bundleplugin/src/main/java/aQute/bnd/maven/support/Maven.java
new file mode 100644
index 0000000..2124a05
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/Maven.java
@@ -0,0 +1,88 @@
+package aQute.bnd.maven.support;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.regex.*;
+
+/*
+ http://repository.springsource.com/maven/bundles/external/org/apache/coyote/com.springsource.org.apache.coyote/6.0.24/com.springsource.org.apache.coyote-6.0.24.pom
+ http://repository.springsource.com/maven/bundles/external/org/apache/coyote/com.springsource.org.apache.coyote/6.0.24/com.springsource.org.apache.coyote-6.0.24.pom
+ */
+public class Maven {
+	final File						userHome	= new File(System.getProperty("user.home"));
+	final Map<String, MavenEntry>	entries		= new ConcurrentHashMap<String, MavenEntry>();
+	final static String[]			ALGORITHMS	= { "md5", "sha1" };
+	boolean							usecache	= false;
+	final Executor					executor;
+	File							m2			= new File(userHome, ".m2");
+	File							repository	= new File(m2, "repository");
+
+	public Maven(Executor executor) {
+		if ( executor == null)
+			this.executor = Executors.newCachedThreadPool();
+		else
+			this.executor = executor;
+	}
+	
+	//http://repo1.maven.org/maven2/junit/junit/maven-metadata.xml
+	
+	static Pattern MAVEN_RANGE = Pattern.compile("(\\[|\\()(.+)(,(.+))(\\]|\\))");
+	public CachedPom getPom(String groupId, String artifactId, String version, URI... extra)
+			throws Exception {		
+		MavenEntry entry = getEntry(groupId, artifactId, version);
+		return entry.getPom(extra);
+	}
+
+	/**
+	 * @param groupId
+	 * @param artifactId
+	 * @param version
+	 * @param extra
+	 * @return
+	 * @throws Exception
+	 */
+	public MavenEntry getEntry(String groupId, String artifactId, String version) throws Exception {
+		String path = path(groupId, artifactId, version);
+
+		MavenEntry entry;
+		synchronized (entries) {
+			entry = entries.get(path);
+			if (entry != null)
+				return entry;
+
+			entry = new MavenEntry(this, path);
+			entries.put(path, entry);
+		}
+		return entry;
+	}
+
+	private String path(String groupId, String artifactId, String version) {
+		return groupId.replace('.', '/') + '/' + artifactId + '/' + version + "/" + artifactId
+				+ "-" + version;
+	}
+
+	public void schedule(Runnable runnable) {
+		if (executor == null)
+			runnable.run();
+		else
+			executor.execute(runnable);
+	}
+
+	public ProjectPom createProjectModel(File file) throws Exception {
+		ProjectPom pom = new ProjectPom(this, file);
+		pom.parse();
+		return pom;
+	}
+
+	public MavenEntry getEntry(Pom pom) throws Exception {
+		return getEntry(pom.getGroupId(), pom.getArtifactId(), pom.getVersion());
+	}
+
+	public void setM2(File dir) {
+		this.m2 = dir;
+		this.repository = new File(dir,"repository");
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenEntry.java b/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenEntry.java
new file mode 100644
index 0000000..f23ba82
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenEntry.java
@@ -0,0 +1,338 @@
+package aQute.bnd.maven.support;
+
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import aQute.lib.hex.*;
+import aQute.lib.io.*;
+import aQute.libg.filelock.*;
+
+/**
+ * An entry (a group/artifact) in the maven cache in the .m2/repository
+ * directory. It provides methods to get the pom and the artifact.
+ * 
+ */
+public class MavenEntry implements Closeable {
+	final Maven					maven;
+	final File					root;
+	final File					dir;
+	final String				path;
+	final DirectoryLock			lock;
+	final Map<URI, CachedPom>	poms	= new HashMap<URI, CachedPom>();
+	final File					pomFile;
+	final File					artifactFile;
+	final String				pomPath;
+	final File					propertiesFile;
+	Properties					properties;
+	private boolean				propertiesChanged;
+	FutureTask<File>			artifact;
+	private String				artifactPath;
+
+	/**
+	 * Constructor.
+	 * 
+	 * @param maven
+	 * @param path
+	 */
+	MavenEntry(Maven maven, String path) {
+		this.root = maven.repository;
+		this.maven = maven;
+		this.path = path;
+		this.pomPath = path + ".pom";
+		this.artifactPath = path + ".jar";
+		this.dir = IO.getFile(maven.repository, path).getParentFile();
+		this.dir.mkdirs();
+		this.pomFile = new File(maven.repository, pomPath);
+		this.artifactFile = new File(maven.repository, artifactPath);
+		this.propertiesFile = new File(dir, "bnd.properties");
+		this.lock = new DirectoryLock(dir, 5 * 60000); // 5 mins
+	}
+
+	/**
+	 * This is the method to get the POM for a cached entry.
+	 * 
+	 * @param urls
+	 *            The allowed URLs
+	 * @return a CachedPom for this maven entry
+	 * 
+	 * @throws Exception
+	 *             If something goes haywire
+	 */
+	public CachedPom getPom(URI[] urls) throws Exception {
+
+		// First check if we have the pom cached in memory
+		synchronized (this) {
+			// Try to find it in the in-memory cache
+			for (URI url : urls) {
+				CachedPom pom = poms.get(url);
+				if (pom != null)
+					return pom;
+			}
+		}
+
+		// Ok, we need to see if it exists on disk
+
+		// lock.lock();
+		try {
+
+			if (isValid()) {
+				// Check if one of our repos had the correct file.
+				for (URI url : urls) {
+					String valid = getProperty(url.toASCIIString());
+					if (valid != null)
+						return createPom(url);
+				}
+
+				// we have the info, but have to verify that it
+				// exists in one of our repos but we do not have
+				// to download it as our cache is already ok.
+				for (URI url : urls) {
+					if (verify(url, pomPath)) {
+						return createPom(url);
+					}
+				}
+
+				// It does not exist in out repo
+				// so we have to fail even though we do have
+				// the file.
+
+			} else {
+				dir.mkdirs();
+				// We really do not have the file
+				// so we have to find out who has it.
+				for (final URI url : urls) {
+
+					if (download(url, pomPath)) {
+						if (verify(url, pomPath)) {
+							artifact = new FutureTask<File>(new Callable<File>() {
+
+								public File call() throws Exception {
+									if (download(url, artifactPath)) {
+										verify(url, artifactPath);
+									}
+									return artifactFile;
+								}
+
+							});
+							maven.executor.execute(artifact);
+							return createPom(url);
+						}
+					}
+				}
+			}
+			return null;
+		} finally {
+			saveProperties();
+			// lock.release();
+		}
+	}
+
+	/**
+	 * Download a resource from the given repo.
+	 * 
+	 * @param url
+	 *            The base url for the repo
+	 * @param path
+	 *            The path part
+	 * @return
+	 * @throws MalformedURLException
+	 */
+	private boolean download(URI repo, String path) throws MalformedURLException {
+		try {
+			URL url = toURL(repo, path);
+			System.out.println("Downloading "  + repo + " path " + path + " url " + url);
+			File file = new File(root, path);
+			IO.copy(url.openStream(), file);
+			System.out.println("Downloaded "  + url);
+			return true;
+		} catch (Exception e) {
+			System.err.println("debug: " + e);
+			return false;
+		}
+	}
+
+	/**
+	 * Converts a repo + path to a URL..
+	 * 
+	 * @param base
+	 *            The base repo
+	 * @param path
+	 *            The path in the directory + url
+	 * @return a URL that points to the file in the repo
+	 * 
+	 * @throws MalformedURLException
+	 */
+	URL toURL(URI base, String path) throws MalformedURLException {
+		StringBuilder r = new StringBuilder();
+		r.append(base.toString());
+		if (r.charAt(r.length() - 1) != '/')
+			r.append('/');
+		r.append(path);
+		return new URL(r.toString());
+	}
+
+	/**
+	 * Check if this is a valid cache directory, might probably need some more
+	 * stuff.
+	 * 
+	 * @return true if valid
+	 */
+	private boolean isValid() {
+		return pomFile.isFile() && pomFile.length() > 100 && artifactFile.isFile()
+				&& artifactFile.length() > 100;
+	}
+
+	/**
+	 * We maintain a set of bnd properties in the cache directory.
+	 * 
+	 * @param key
+	 *            The key for the property
+	 * @param value
+	 *            The value for the property
+	 */
+	private void setProperty(String key, String value) {
+		Properties properties = getProperties();
+		properties.setProperty(key, value);
+		propertiesChanged = true;
+	}
+
+	/**
+	 * Answer the properties, loading if needed.
+	 */
+	protected Properties getProperties() {
+		if (properties == null) {
+			properties = new Properties();
+			File props = new File(dir, "bnd.properties");
+			if (props.exists()) {
+				try {
+					FileInputStream in = new FileInputStream(props);
+					properties.load(in);
+				} catch (Exception e) {
+					// we ignore for now, will handle it on safe
+				}
+			}
+		}
+		return properties;
+	}
+
+	/**
+	 * Answer a property.
+	 * 
+	 * @param key
+	 *            The key
+	 * @return The value
+	 */
+	private String getProperty(String key) {
+		Properties properties = getProperties();
+		return properties.getProperty(key);
+	}
+
+	private void saveProperties() throws IOException {
+		if (propertiesChanged) {
+			FileOutputStream fout = new FileOutputStream(propertiesFile);
+			try {
+				properties.store(fout, "");
+			} finally {
+				properties = null;
+				propertiesChanged = false;
+				fout.close();
+			}
+		}
+	}
+
+	/**
+	 * Help function to create the POM and record its source.
+	 * 
+	 * @param url
+	 *            the repo from which it was constructed
+	 * @return the new pom
+	 * @throws Exception
+	 */
+	private CachedPom createPom(URI url) throws Exception {
+		CachedPom pom = new CachedPom(this, url);
+		pom.parse();
+		poms.put(url, pom);
+		setProperty(url.toASCIIString(), "true");
+		return pom;
+	}
+
+	/**
+	 * Verify that the repo has a checksum file for the given path and that this
+	 * checksum matchs.
+	 * 
+	 * @param repo
+	 *            The repo
+	 * @param path
+	 *            The file id
+	 * @return true if there is a digest and it matches one of the algorithms
+	 * @throws Exception
+	 */
+	boolean verify(URI repo, String path) throws Exception {
+		for (String algorithm : Maven.ALGORITHMS) {
+			if (verify(repo, path, algorithm))
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Verify the path against its digest for the given algorithm.
+	 * 
+	 * @param repo
+	 * @param path
+	 * @param algorithm
+	 * @return
+	 * @throws Exception
+	 */
+	private boolean verify(URI repo, String path, String algorithm) throws Exception {
+		String digestPath = path + "." + algorithm;
+		File actualFile = new File(root, path);
+
+		if (download(repo, digestPath)) {
+			File digestFile = new File(root, digestPath);
+			final MessageDigest md = MessageDigest.getInstance(algorithm);
+			IO.copy(actualFile, new OutputStream() {
+				@Override public void write(int c) throws IOException {
+					md.update((byte) c);
+				}
+
+				@Override public void write(byte[] buffer, int offset, int length) {
+					md.update(buffer, offset, length);
+				}
+			});
+			byte[] digest = md.digest();
+			String source = IO.collect(digestFile).toUpperCase();
+			String hex = Hex.toHexString(digest).toUpperCase();
+			if (source.startsWith(hex)) {
+				System.out.println("Verified ok " + actualFile + " digest " + algorithm);
+				return true;
+			}
+		}
+		System.out.println("Failed to verify " + actualFile + " for digest " + algorithm);
+		return false;
+	}
+
+	public File getArtifact() throws Exception {
+		if (artifact == null )
+			return artifactFile;
+		return artifact.get();
+	}
+
+	public File getPomFile() {
+		return pomFile;
+	}
+
+	public void close() throws IOException {
+
+	}
+
+	public void remove() {
+		if (dir.getParentFile() != null) {
+			IO.delete(dir);
+		}
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenRemoteRepository.java b/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenRemoteRepository.java
new file mode 100644
index 0000000..bbe2411
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenRemoteRepository.java
@@ -0,0 +1,130 @@
+package aQute.bnd.maven.support;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+import aQute.libg.reporter.*;
+import aQute.libg.version.*;
+
+public class MavenRemoteRepository implements RepositoryPlugin, RegistryPlugin, Plugin {
+	Reporter	reporter;
+	URI[]		repositories;
+	Registry	registry;
+	Maven		maven;
+
+	public File[] get(String bsn, String range) throws Exception {
+		File f = get(bsn, range, Strategy.HIGHEST, null);
+		if (f == null)
+			return null;
+
+		return new File[] { f };
+	}
+
+	public File get(String bsn, String version, Strategy strategy, Map<String, String> properties)
+			throws Exception {
+		String groupId = null;
+		
+		if (properties != null)
+			groupId = properties.get("groupId");
+		
+		if (groupId == null) {
+			int n = bsn.indexOf('+');
+			if ( n < 0)
+				return null;
+			
+			groupId = bsn.substring(0,n);
+			bsn = bsn.substring(n+1);
+		}
+
+		String artifactId = bsn;
+
+		if (version == null) {
+			if (reporter != null)
+				reporter.error("Maven dependency version not set for %s - %s", groupId, artifactId);
+			return null;
+		}
+
+		CachedPom pom = getMaven().getPom(groupId, artifactId, version, repositories);
+
+		String value = properties == null ? null : properties.get("scope");
+		if (value == null)
+			return pom.getArtifact();
+
+		Pom.Scope action = null;
+
+		try {
+			action = Pom.Scope.valueOf(value);
+			return pom.getLibrary(action, repositories);
+		} catch (Exception e) {
+			return pom.getArtifact();
+		}
+	}
+
+	public Maven getMaven() {
+		if ( maven != null)
+			return maven;
+		
+		maven = registry.getPlugin(Maven.class);
+		return maven;
+	}
+
+	public boolean canWrite() {
+		return false;
+	}
+
+	public File put(Jar jar) throws Exception {
+		throw new UnsupportedOperationException("cannot do put");
+	}
+
+	public List<String> list(String regex) throws Exception {
+		throw new UnsupportedOperationException("cannot do list");
+	}
+
+	public List<Version> versions(String bsn) throws Exception {
+		throw new UnsupportedOperationException("cannot do versions");
+	}
+
+	public String getName() {
+		return "maven";
+	}
+
+	public void setRepositories(URI... urls) {
+		repositories = urls;
+	}
+
+	public void setProperties(Map<String, String> map) {
+		String repoString = map.get("repositories");
+		if (repoString != null) {
+			String[] repos = repoString.split("\\s*,\\s*");
+			repositories = new URI[repos.length];
+			int n = 0;
+			for (String repo : repos) {
+				try {
+					URI uri = new URI(repo);
+					if ( !uri.isAbsolute())
+						uri = IO.getFile( new File(""),repo).toURI();
+					repositories[n++] = uri;
+				} catch (Exception e) {
+					if (reporter != null)
+						reporter.error("Invalid repository %s for maven plugin, %s", repo, e);
+				}
+			}
+		}
+	}
+
+	public void setReporter(Reporter reporter) {
+		this.reporter = reporter;
+	}
+
+	public void setRegistry(Registry registry) {
+		this.registry = registry;
+	}
+
+	public void setMaven(Maven maven) {
+		this.maven = maven;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/Pom.java b/bundleplugin/src/main/java/aQute/bnd/maven/support/Pom.java
new file mode 100644
index 0000000..2b7ab46
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/Pom.java
@@ -0,0 +1,350 @@
+package aQute.bnd.maven.support;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+import javax.xml.parsers.*;
+import javax.xml.xpath.*;
+
+import org.w3c.dom.*;
+
+public abstract class Pom {
+	static DocumentBuilderFactory	dbf	= DocumentBuilderFactory.newInstance();
+	static XPathFactory				xpf	= XPathFactory.newInstance();
+
+	static {
+		dbf.setNamespaceAware(false);
+	}
+	
+	public enum Scope {
+		compile, runtime, system, import_, provided, test, ;
+		
+		private boolean includes(Scope other) {
+			if (other == this) return true;
+			switch (this) {
+			case compile:
+				return other == provided || other == test;
+			default:
+				return false;
+			}
+		}
+	};
+
+	final Maven			maven;
+	final URI			home;
+
+	String				groupId;
+	String				artifactId;
+	String				version;
+	List<Dependency>	dependencies	= new ArrayList<Dependency>();
+	Exception			exception;
+	File				pomFile;
+	String				description="";
+	String				name;
+
+	public String getDescription() {
+		return description;
+	}
+
+	public class Dependency {
+		Scope		scope;
+		String		type;
+		boolean		optional;
+		String		groupId;
+		String		artifactId;
+		String		version;
+		Set<String>	exclusions	= new HashSet<String>();
+
+		public Scope getScope() {
+			return scope;
+		}
+
+		public String getType() {
+			return type;
+		}
+
+		public boolean isOptional() {
+			return optional;
+		}
+
+		public String getGroupId() {
+			return replace(groupId);
+		}
+
+		public String getArtifactId() {
+			return replace(artifactId);
+		}
+
+		public String getVersion() {
+			return replace(version);
+		}
+
+		public Set<String> getExclusions() {
+			return exclusions;
+		}
+
+		public Pom getPom() throws Exception {
+			return maven.getPom(groupId, artifactId, version);
+		}
+		@Override
+		public String toString() {
+			StringBuilder builder = new StringBuilder();
+			builder.append("Dependency [");
+			if (groupId != null)
+				builder.append("groupId=").append(groupId).append(", ");
+			if (artifactId != null)
+				builder.append("artifactId=").append(artifactId).append(", ");
+			if (version != null)
+				builder.append("version=").append(version).append(", ");
+			if (type != null)
+				builder.append("type=").append(type).append(", ");
+			if (scope != null)
+				builder.append("scope=").append(scope).append(", ");
+			builder.append("optional=").append(optional).append(", ");
+			if (exclusions != null)
+				builder.append("exclusions=").append(exclusions);
+			builder.append("]");
+			return builder.toString();
+		}
+	}
+
+	public Pom(Maven maven, File pomFile, URI home) throws Exception {
+		this.maven = maven;
+		this.home = home;
+		this.pomFile = pomFile;
+	}
+
+	void parse() throws Exception {
+		DocumentBuilder db = dbf.newDocumentBuilder();
+		System.out.println("Parsing " + pomFile.getAbsolutePath());
+		Document doc = db.parse(pomFile);
+		XPath xp = xpf.newXPath();
+		parse(doc, xp);
+	}
+
+	protected void parse(Document doc, XPath xp) throws XPathExpressionException, Exception {
+
+		this.artifactId = replace(xp.evaluate("project/artifactId", doc).trim(), this.artifactId);
+		this.groupId = replace(xp.evaluate("project/groupId", doc).trim(), this.groupId);
+		this.version = replace(xp.evaluate("project/version", doc).trim(), this.version);
+		
+		String nextDescription = xp.evaluate("project/description", doc).trim();
+		if ( this.description.length() != 0 && nextDescription.length() != 0)
+			this.description += "\n";
+		this.description += replace(nextDescription);
+		
+		this.name = replace(xp.evaluate("project/name", doc).trim(), this.name);
+
+		NodeList list = (NodeList) xp.evaluate("project/dependencies/dependency", doc,
+				XPathConstants.NODESET);
+		for (int i = 0; i < list.getLength(); i++) {
+			Node node = list.item(i);
+			Dependency dep = new Dependency();
+			String scope = xp.evaluate("scope", node).trim();
+			if (scope.length() == 0)
+				dep.scope = Scope.compile;
+			else
+				dep.scope = Scope.valueOf(scope);
+			dep.type = xp.evaluate("type", node).trim();
+
+			String opt = xp.evaluate("optional", node).trim();
+			dep.optional = opt != null && opt.equalsIgnoreCase("true");
+			dep.groupId = replace(xp.evaluate("groupId", node));
+			dep.artifactId = replace(xp.evaluate("artifactId", node).trim());
+
+			dep.version = replace(xp.evaluate("version", node).trim());
+			dependencies.add(dep);
+
+			NodeList exclusions = (NodeList) xp
+					.evaluate("exclusions", node, XPathConstants.NODESET);
+			for (int e = 0; e < exclusions.getLength(); e++) {
+				Node exc = exclusions.item(e);
+				String exclGroupId = xp.evaluate("groupId", exc).trim();
+				String exclArtifactId = xp.evaluate("artifactId", exc).trim();
+				dep.exclusions.add(exclGroupId + "+" + exclArtifactId);
+			}
+		}
+
+	}
+
+	private String replace(String key, String dflt) {
+		if ( key == null || key.length() == 0)
+			return dflt;
+		
+		return replace(key);
+	}
+
+	public String getArtifactId() throws Exception {
+		return replace(artifactId);
+	}
+
+	public String getGroupId() throws Exception {
+		return replace(groupId);
+	}
+
+	public String getVersion() throws Exception {
+		if ( version == null)
+			return "<not set>";
+		return replace(version);
+	}
+
+	public List<Dependency> getDependencies() throws Exception {
+		return dependencies;
+	}
+
+	class Rover {
+
+		public Rover(Rover rover, Dependency d) {
+			this.previous = rover;
+			this.dependency = d;
+		}
+
+		final Rover			previous;
+		final Dependency	dependency;
+
+		public boolean excludes(String name) {
+			return dependency.exclusions.contains(name) && previous != null
+					&& previous.excludes(name);
+		}
+	}
+
+	public Set<Pom> getDependencies(Scope scope, URI... urls) throws Exception {
+		Set<Pom> result = new LinkedHashSet<Pom>();
+
+		List<Rover> queue = new ArrayList<Rover>();
+		for (Dependency d : dependencies) {
+			queue.add(new Rover(null, d));
+		}
+
+		while (!queue.isEmpty()) {
+			Rover rover = queue.remove(0);
+			Dependency dep = rover.dependency;
+			String groupId = replace(dep.groupId);
+			String artifactId = replace(dep.artifactId);
+			String version = replace(dep.version);
+
+			String name = groupId + "+" + artifactId;
+
+			if (rover.excludes(name) || dep.optional)
+				continue;
+			
+			if (dep.scope == scope && !dep.optional) {
+				try {
+					Pom sub = maven.getPom(groupId, artifactId, version, urls);
+					if (sub != null) {
+						if (!result.contains(sub)) {
+							result.add(sub);
+							for (Dependency subd : sub.dependencies) {
+								queue.add(new Rover(rover, subd));
+							}
+						}
+					} else
+						if (rover.previous != null)
+							System.out.println("Cannot find " + dep + " from "
+									+ rover.previous.dependency);
+						else
+							System.out.println("Cannot find " + dep + " from top");
+				} catch (Exception e) {
+					if (rover.previous != null)
+						System.out.println("Cannot find " + dep + " from "
+								+ rover.previous.dependency);
+					else
+						System.out.println("Cannot find " + dep + " from top");
+
+//			boolean include = false;
+//			if (dep.scope == Scope.compile) {
+//				include = true;
+//			} else if (dep.scope == Scope.test) {
+//				include = rover.previous == null && (action == Action.compile || action == Action.test);
+//			} else if (dep.scope == Scope.runtime) {
+//				include = action == Action.run;
+//			}
+//			if (include) {
+//				Pom sub = maven.getPom(groupId, artifactId, version, urls);
+//				if (!result.contains(sub)) {
+//					result.add(sub);
+//					for (Dependency subd : sub.dependencies) {
+//						queue.add(new Rover(rover, subd));
+//					}
+					
+				}
+			}
+		}
+		return result;
+	}
+
+	protected String replace(String in) {
+		System.out.println("replace: " + in);
+		if (in == null)
+			return "null";
+
+		in = in.trim();
+		if ("${pom.version}".equals(in) || "${version}".equals(in)
+				|| "${project.version}".equals(in))
+			return version;
+
+		if ("${basedir}".equals(in))
+			return pomFile.getParentFile().getAbsolutePath();
+
+		if ("${pom.name}".equals(in) || "${project.name}".equals(in))
+			return name;
+
+		if ("${pom.artifactId}".equals(in) || "${project.artifactId}".equals(in))
+			return artifactId;
+		if ("${pom.groupId}".equals(in) || "${project.groupId}".equals(in))
+			return groupId;
+
+		return in;
+	}
+
+	public String toString() {
+		return groupId + "+" + artifactId + "-" + version;
+	}
+
+	public File getLibrary(Scope action, URI... repositories) throws Exception {
+		MavenEntry entry = maven.getEntry(this);
+		File file = new File(entry.dir, action + ".lib");
+
+		if (file.isFile() && file.lastModified() >= getPomFile().lastModified())
+			return file;
+
+		file.delete();
+
+		Writer writer = new FileWriter(file);
+		doEntry(writer, this);
+		try {
+			for (Pom dep : getDependencies(action, repositories)) {
+				doEntry(writer, dep);
+			}
+		} finally {
+			writer.close();
+		}
+		return file;
+	}
+
+	/**
+	 * @param writer
+	 * @param dep
+	 * @throws IOException
+	 * @throws Exception
+	 */
+	private void doEntry(Writer writer, Pom dep) throws IOException, Exception {
+		writer.append(dep.getGroupId());
+		writer.append("+");
+		writer.append(dep.getArtifactId());
+		writer.append(";version=\"");
+		writer.append(dep.getVersion());
+		writer.append("\"\n");
+	}
+
+	public File getPomFile() {
+		return pomFile;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public abstract java.io.File getArtifact() throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/ProjectPom.java b/bundleplugin/src/main/java/aQute/bnd/maven/support/ProjectPom.java
new file mode 100644
index 0000000..8187954
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/ProjectPom.java
@@ -0,0 +1,204 @@
+package aQute.bnd.maven.support;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.regex.*;
+
+import javax.xml.xpath.*;
+
+import org.w3c.dom.*;
+
+import aQute.lib.io.*;
+
+public class ProjectPom extends Pom {
+
+	final List<URI>	repositories	= new ArrayList<URI>();
+	final Properties	properties		= new Properties();
+	String 		packaging;
+	String 		url;
+	
+	ProjectPom(Maven maven, File pomFile) throws Exception {
+		super(maven, pomFile, pomFile.toURI());
+	}
+
+	@Override protected void parse(Document doc, XPath xp) throws Exception {
+
+		packaging = xp.evaluate("project/packaging", doc);
+		url = xp.evaluate("project/url", doc);
+		
+		Node parent = (Node) xp.evaluate("project/parent", doc, XPathConstants.NODE);
+		if (parent != null && parent.hasChildNodes()) {
+			File parentFile = IO.getFile(getPomFile().getParentFile(), "../pom.xml");
+
+			String parentGroupId = xp.evaluate("groupId", parent).trim();
+			String parentArtifactId = xp.evaluate("artifactId", parent).trim();
+			String parentVersion = xp.evaluate("version", parent).trim();
+			String parentPath = xp.evaluate("relativePath", parent).trim();
+			if (parentPath != null && parentPath.length()!=0) {
+				parentFile = IO.getFile(getPomFile().getParentFile(), parentPath);
+			}
+			if (parentFile.isFile()) {
+				ProjectPom parentPom = new ProjectPom(maven, parentFile);
+				parentPom.parse();
+				dependencies.addAll(parentPom.dependencies);
+				for ( Enumeration<?> e = parentPom.properties.propertyNames(); e.hasMoreElements(); ) {
+					String key = (String) e.nextElement();
+					if ( ! properties.contains(key))
+						properties.put(key, parentPom.properties.get(key));
+				}
+				repositories.addAll(parentPom.repositories);
+				
+				setNames(parentPom);
+			} else {
+				// This seems to be a bit bizarre, extending an external pom?
+				CachedPom parentPom = maven.getPom(parentGroupId, parentArtifactId, parentVersion);
+				dependencies.addAll(parentPom.dependencies);
+				setNames(parentPom);
+			}
+		}
+
+		NodeList propNodes = (NodeList) xp.evaluate("project/properties/*", doc,
+				XPathConstants.NODESET);
+		for (int i = 0; i < propNodes.getLength(); i++) {
+			Node node = propNodes.item(i);
+			String key = node.getNodeName();
+			String value = node.getTextContent();
+			if ( key == null || key.length()==0)
+				throw new IllegalArgumentException("Pom has an empty or null key");
+			if ( value == null || value.length()==0)
+				throw new IllegalArgumentException("Pom has an empty or null value for property " + key);
+			properties.setProperty(key, value.trim());
+		}
+
+		NodeList repos = (NodeList) xp.evaluate("project/repositories/repository/url", doc,
+				XPathConstants.NODESET);
+		for (int i = 0; i < repos.getLength(); i++) {
+			Node node = repos.item(i);
+			String URIString = node.getTextContent().trim();
+			URI uri = new URI(URIString);
+			if ( uri.getScheme() ==null )
+				uri = IO.getFile(pomFile.getParentFile(),URIString).toURI();
+			repositories.add(uri);
+		}
+
+		super.parse(doc, xp);
+	}
+
+//	private void print(Node node, String indent) {
+//		System.out.print(indent);
+//		System.out.println(node.getNodeName());
+//		Node rover = node.getFirstChild();
+//		while ( rover != null) {
+//			print( rover, indent+" ");
+//			rover = rover.getNextSibling();
+//		}
+//	}
+
+	/**
+	 * @param parentArtifactId
+	 * @param parentGroupId
+	 * @param parentVersion
+	 * @throws Exception
+	 */
+	private void setNames(Pom pom) throws Exception {
+		if (artifactId == null || artifactId.length()==0)
+			artifactId = pom.getArtifactId();
+		if (groupId == null || groupId.length()==0)
+			groupId = pom.getGroupId();
+		if (version == null || version.length()==0)
+			version = pom.getVersion();
+		if ( description == null )
+			description = pom.getDescription();
+		else
+			description = pom.getDescription() + "\n" + description;
+	
+	}
+
+	class Rover {
+
+		public Rover(Rover rover, Dependency d) {
+			this.previous = rover;
+			this.dependency = d;
+		}
+
+		final Rover			previous;
+		final Dependency	dependency;
+
+		public boolean excludes(String name) {
+			return dependency.exclusions.contains(name) && previous != null
+					&& previous.excludes(name);
+		}
+	}
+
+	public Set<Pom> getDependencies(Scope action) throws Exception {
+		return getDependencies(action, repositories.toArray(new URI[0]));
+	}
+
+	// Match any macros
+	final static Pattern	MACRO	= Pattern.compile("(\\$\\{\\s*([^}\\s]+)\\s*\\})");
+
+	protected String replace(String in) {
+		System.out.println("Replce: " + in);
+		if ( in == null) {
+			System.out.println("null??");
+		}
+		Matcher matcher = MACRO.matcher(in);
+		int last = 0;
+		StringBuilder sb = new StringBuilder();
+		while (matcher.find()) {
+			int n = matcher.start();
+			sb.append( in, last, n);
+			String replacement = get(matcher.group(2));
+			if ( replacement == null )
+				sb.append( matcher.group(1));
+			else
+				sb.append( replacement );
+			last = matcher.end();
+		}
+		if ( last == 0)
+			return in;
+		
+		sb.append( in, last, in.length());
+		return sb.toString();
+	}
+
+	private String get(String key) {
+		if (key.equals("pom.artifactId"))
+			return artifactId;
+		if (key.equals("pom.groupId"))
+			return groupId;
+		if (key.equals("pom.version"))
+			return version;
+		
+		if (key.equals("pom.name"))
+			return name;
+		
+		String prop = properties.getProperty(key);
+		if ( prop != null )
+			return prop;
+		
+		return System.getProperty(key);
+	}
+
+	public Properties getProperties() {
+		return properties;
+	}
+
+	public String getPackaging() {
+		return packaging;
+	}
+
+	public String getUrl() {
+		return url;
+	}
+
+	public String getProperty(String key) {
+		String s = properties.getProperty(key);
+		return replace(s);
+	}
+
+	@Override public File getArtifact() throws Exception {
+		return null;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/Repo.java b/bundleplugin/src/main/java/aQute/bnd/maven/support/Repo.java
new file mode 100644
index 0000000..dd1939f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/Repo.java
@@ -0,0 +1,5 @@
+package aQute.bnd.maven.support;
+
+public class Repo {
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/repo/eclipse/EclipseRepo.java b/bundleplugin/src/main/java/aQute/bnd/repo/eclipse/EclipseRepo.java
new file mode 100644
index 0000000..3fa967a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/repo/eclipse/EclipseRepo.java
@@ -0,0 +1,199 @@
+package aQute.bnd.repo.eclipse;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.libg.generics.*;
+import aQute.libg.reporter.*;
+import aQute.libg.version.*;
+
+public class EclipseRepo implements Plugin, RepositoryPlugin {
+    File                             root;
+    Reporter                         reporter;
+    String                           name;
+    Map<String, Map<String, String>> index;
+
+    public static String             LOCATION = "location";
+    public static String             NAME     = "name";
+
+    public void setProperties(Map<String, String> map) {
+        String location = (String) map.get(LOCATION);
+        if (location == null)
+            throw new IllegalArgumentException(
+                    "Location muse be set on a EclipseRepo plugin");
+
+        root = new File(location);
+        if (!root.isDirectory())
+            throw new IllegalArgumentException(
+                    "Repository is not a valid directory " + root);
+
+        if (!new File(root, "plugins").isDirectory())
+            throw new IllegalArgumentException(
+                    "Repository is not a valid directory (no plugins directory)"
+                            + root);
+
+        name = (String) map.get(NAME);
+
+        try {
+            index = buildIndex();
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "Could not build index for eclipse repo: " + root);
+        }
+    }
+
+    Map<String, Map<String, String>> buildIndex() throws Exception {
+        File index = new File(root, "bnd.index").getAbsoluteFile();
+        File[] plugins = new File(root, "plugins").listFiles();
+
+        for (File f : plugins) {
+            f = f.getAbsoluteFile();
+            if (f.isFile()) {
+                if (f.lastModified() > index.lastModified()) {
+
+                    Map<String, Map<String, String>> map = buildIndex(plugins);
+                    write(index, map);
+                    return map;
+                }
+            }
+        }
+
+        String s = read(index);
+        return Processor.parseHeader(s, null);
+    }
+
+    private String read(File index) throws Exception {
+        if (index.isFile()) {
+            BufferedReader fr = new BufferedReader(new FileReader(index));
+            StringBuilder sb = new StringBuilder();
+
+            try {
+                String s = fr.readLine();
+                while (s != null) {
+                    sb.append(s);
+                    s = fr.readLine();
+                }
+            } finally {
+                fr.close();
+            }
+        }
+        return null;
+    }
+
+    private void write(File index, Map<String, Map<String, String>> map)
+            throws Exception {
+        String s = Processor.printClauses(map);
+        index.getParentFile().mkdirs();
+        FileWriter fw = new FileWriter(index);
+        try {
+            fw.write(s);
+        } finally {
+            fw.close();
+        }
+    }
+
+    private Map<String, Map<String, String>> buildIndex(File[] plugins) {
+        Map<String, Map<String, String>> map = Create.map();
+        for (File plugin : plugins) {
+            try {
+                Jar jar = new Jar(plugin);
+                Manifest manifest = jar.getManifest();
+                String bsn = manifest.getMainAttributes().getValue(
+                        Constants.BUNDLE_SYMBOLICNAME);
+                String version = manifest.getMainAttributes().getValue(
+                        Constants.BUNDLE_VERSION);
+
+                if (bsn != null) {
+                    if (version == null)
+                        version = "0";
+
+                    Map<String, String> instance = map.get(bsn);
+                    if (instance == null) {
+                        instance = Create.map();
+                    }
+                    instance.put(version, plugin.getAbsolutePath());
+                }
+            } catch (Exception e) {
+                // Ignore exceptions in the plugins dir.
+            }
+        }
+        return map;
+    }
+
+    public void setReporter(Reporter reporter) {
+        this.reporter = reporter;
+    }
+
+    public boolean canWrite() {
+        return false;
+    }
+
+    public File[] get(String bsn, String range) throws Exception {
+        VersionRange r = new VersionRange(range);
+        Map<String, String> instances = index.get(bsn);
+        if (instances == null)
+            return null;
+
+        List<File> result = Create.list();
+
+        for (String version : instances.keySet()) {
+            Version v = new Version(version);
+            if (r.includes(v)) {
+                File f = new File(instances.get(version));
+                if (f.isFile()) {
+                    result.add(f);
+                }
+            }
+        }
+        return result.toArray(new File[result.size()]);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public List<String> list(String regex) {
+        Instruction pattern = null;
+        if (regex != null)
+            pattern = Instruction.getPattern(regex);
+
+        List<String> result = new ArrayList<String>();
+        for (String f : index.keySet()) {
+            if (pattern == null || pattern.matches(f))
+                result.add(f);
+        }
+        return result;
+    }
+
+    public File put(Jar jar) throws Exception {
+        return null;
+    }
+
+    public List<Version> versions(String bsn) {
+        Map<String, String> instances = index.get(bsn);
+        if (instances == null)
+            return null;
+
+        List<Version> versions = Create.list();
+        for (String v : instances.keySet())
+            versions.add(new Version(v));
+        return versions;
+    }
+
+
+	public File get(String bsn, String range, Strategy strategy, Map<String,String> properties) throws Exception {
+		File[] files = get(bsn, range);
+		if (files.length >= 0) {
+			switch (strategy) {
+			case LOWEST:
+				return files[0];
+			case HIGHEST:
+				return files[files.length - 1];
+			}
+		}
+		return null;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/resolver/Resolution.java b/bundleplugin/src/main/java/aQute/bnd/resolver/Resolution.java
new file mode 100644
index 0000000..b703835
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/resolver/Resolution.java
@@ -0,0 +1,12 @@
+package aQute.bnd.resolver;
+
+import java.util.*;
+
+import aQute.bnd.resolver.Resource.Requirement;
+import aQute.lib.collections.*;
+
+public class Resolution {
+	public Set<Requirement>				unresolved;
+	public MultiMap<Requirement, Resource>	multiple;
+	public Map<Requirement, Resource>		unique;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/resolver/Resolver.java b/bundleplugin/src/main/java/aQute/bnd/resolver/Resolver.java
new file mode 100644
index 0000000..4457f16
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/resolver/Resolver.java
@@ -0,0 +1,172 @@
+package aQute.bnd.resolver;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.bnd.build.*;
+import aQute.bnd.resolver.Resource.Requirement;
+import aQute.lib.collections.*;
+import aQute.lib.osgi.*;
+import aQute.libg.generics.*;
+
+public class Resolver extends Processor {
+
+	final Set<Resource>									resources	= new HashSet<Resource>();
+	private Map<Resource.Requirement, Set<Resource>>	cache		= new IdentityHashMap<Resource.Requirement, Set<Resource>>();
+
+	public void add(Container c) throws Exception {
+		List<File> files = new ArrayList<File>();
+		c.contributeFiles(files, this);
+		for (File f : files) {
+			add(f);
+		}
+	}
+
+	public void addAll(Collection<Container> containers) throws Exception {
+		for (Container c : containers) {
+			add(c);
+		}
+	}
+
+	public Resolution resolve() throws Exception {
+		// Split fragments and bundles
+		Set<Resource> active = new HashSet<Resource>();
+		Set<Resource> fragments = new HashSet<Resource>();
+		Set<Resource> singletons = new HashSet<Resource>();
+
+		for (Resource r : resources) {
+			if (r.fragments != null) {
+				active.add(r);
+				if (r.singleton)
+					singletons.add(r);
+			} else
+				fragments.add(r);
+		}
+
+		// Attach fragments
+		for (Resource r : fragments) {
+			Collection<Resource> hosts = find(active, r.requirements, new HashSet<Resource>());
+			for (Resource host : hosts) {
+				host.fragments.add(host);
+			}
+		}
+
+		// Create a list of all the requirements
+		Set<Resource.Requirement> reqs = new HashSet<Resource.Requirement>();
+		for (Resource r : active) {
+			reqs.addAll(r.requirements);
+			// And its attached fragments
+			for (Resource f : r.fragments) {
+				reqs.addAll(f.requirements);
+			}
+		}
+
+		Set<Resource.Requirement> optional = Create.set();
+		Set<Resource.Requirement> unresolved = Create.set();
+		Map<Resource.Requirement, Resource> unique = Create.map();
+		MultiMap<Requirement, Resource> multiple = new MultiMap<Requirement, Resource>();
+
+		for (Resource.Requirement req : reqs) {
+			Collection<Resource> solutions = find(active, req, new HashSet<Resource>());
+			if (solutions.isEmpty()) {
+				if (req.optional)
+					optional.add(req);
+				else
+					unresolved.add(req);
+			} else if (solutions.size() == 1)
+				unique.put(req, solutions.iterator().next());
+			else {
+				multiple.addAll(req, solutions);
+			}
+		}
+
+		// If we have unresolveds, tough shit
+
+		if (!unresolved.isEmpty()) {
+			for (Requirement r : unresolved) {
+				error("Unresolved %s", r);
+			}
+		}
+
+		// Calculate our singleton candidates
+		MultiMap<String, Resource> picked = new MultiMap<String, Resource>();
+		for (Resource r : singletons) {
+			picked.add(r.bsn, r);
+		}
+
+		// Remove any singletons that are alone
+		// and verify that if there are multiple they are not
+		// both in the unique solutions
+		for (Iterator<Map.Entry<String, Set<Resource>>> i = picked.entrySet().iterator(); i
+				.hasNext();) {
+			Map.Entry<String, Set<Resource>> entry = i.next();
+			if (entry.getValue().size() == 1)
+				i.remove();
+			else {
+				Set<Resource> x = new HashSet<Resource>(entry.getValue());
+				boolean changed = x.retainAll(unique.values());
+				if (x.size() > 1) {
+					// We need multiple singleton bundles with the same bsn
+					error("Singleton conflict: %s", x);
+				} else if (changed) {
+					Set<Resource> delta = new HashSet<Resource>(entry.getValue());
+					delta.removeAll(x);
+
+					// We've removed bundles from the possible solutions
+					for (Iterator<Resource> it = multiple.all(); i.hasNext();) {
+						Resource r = it.next();
+						if (delta.contains(r)) {
+							it.remove();
+						}
+					}
+				}
+			}
+		}
+
+		Resolution res = new Resolution();
+		res.multiple = multiple;
+		res.unique = unique;
+		res.unresolved = unresolved;
+		return res;
+	}
+
+	private Collection<Resource> find(Set<Resource> active, Set<Resource.Requirement> requirements,
+			Set<Resource> result) {
+		for (Resource.Requirement req : requirements) {
+			Set<Resource> resources = cache.get(req);
+			if (resources != null) {
+				result.addAll(resources);
+			} else {
+				resources = find(active, req, new HashSet<Resource>());
+				cache.put(req, resources);
+				result.addAll(resources);
+			}
+		}
+		return result;
+	}
+
+	private Set<Resource> find(Set<Resource> active, Requirement req, Set<Resource> result) {
+		for (Resource r : active) {
+			for (Resource.Capability cap : r.capabilities) {
+				if ( cap.name.equals(req.name))
+					System.out.println("Yes");
+				if (req.matches(cap))
+					result.add(r);
+			}
+		}
+		return result;
+	}
+
+	public void add(File file) throws IOException {
+		JarFile jf = new JarFile(file);
+		try {
+			Manifest m = jf.getManifest();
+			Resource r = new Resource(this, m);
+			resources.add(r);
+		} finally {
+			jf.close();
+		}
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/resolver/Resource.java b/bundleplugin/src/main/java/aQute/bnd/resolver/Resource.java
new file mode 100644
index 0000000..54306d3
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/resolver/Resource.java
@@ -0,0 +1,161 @@
+package aQute.bnd.resolver;
+
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.lib.osgi.*;
+import aQute.libg.version.*;
+
+public class Resource {
+	enum Type {
+		PACKAGE,
+		BUNDLE,
+		HOST;
+	}
+	
+	final Set<Requirement>	requirements	= new HashSet<Requirement>();
+	final Set<Capability>	capabilities	= new HashSet<Capability>();
+	final List<Resource>	fragments;
+	final String			bsn;
+	final Version			version;
+	final boolean			singleton;
+	final Resolver			resolver;
+
+	class Requirement {
+		final Type		type;
+		final String		name;
+		final VersionRange	range;
+		final boolean		optional;
+
+		Requirement(Type type, String name, VersionRange range, boolean optional) {
+			this.type = type;
+			this.name = name;
+			this.range = range;
+			this.optional = optional;
+		}
+
+		Resource getDeclaredResource() {
+			return Resource.this;
+		}
+
+		public boolean matches(Capability cap) {
+			boolean a = cap.type == type;
+			boolean b = cap.name.equals(name);
+			boolean c = range.includes(cap.version);
+			return a && b && c;
+		}
+		
+		public String toString() {
+			return "R." +type + ":" + name + "-" + range;
+		}
+
+	}
+
+	class Capability {
+		final Type	type;
+		final String	name;
+		final Version	version;
+
+		Capability(Type type, String name, Version version) {
+			this.type = type;
+			this.name = name;
+			this.version = version;
+		}
+
+		Resource getDeclaredResource() {
+			return Resource.this;
+		}
+		public String toString() {
+			return "C." + type + ":" + name + "-" + version;
+		}
+	}
+
+	Resource(Resolver resolver, Manifest m) {
+		this.resolver= resolver;
+		Attributes main = m.getMainAttributes();
+		Map<String, Map<String, String>> bsns = resolver.parseHeader(main
+				.getValue(Constants.BUNDLE_SYMBOLICNAME));
+		if (bsns.size() > 1)
+			resolver.error("Multiple bsns %s", bsns);
+		if (bsns.size() < 1) {
+			resolver.error("No bsns");
+			bsn = "<not set>";
+			version = new Version("0");
+			singleton = false;
+		} else {
+			Map.Entry<String, Map<String, String>> entry = bsns.entrySet().iterator().next();
+			bsn = entry.getKey();
+			String v = main.getValue(Constants.BUNDLE_VERSION);
+			this.version = version(v);
+			singleton = "true"
+					.equalsIgnoreCase(entry.getValue().get(Constants.SINGLETON_DIRECTIVE));
+
+			String directive = entry.getValue().get(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE);
+			boolean attach = directive == null || "always".equals(directive) || "resolve-time".equals(directive);
+			if (attach) {
+				capabilities.add(new Capability(Type.HOST, bsn, version));
+			}
+		}
+		Map<String, Map<String, String>> hosts = resolver.parseHeader(main.getValue(Constants.FRAGMENT_HOST));
+		if (hosts.size() > 1)
+			resolver.error("Multiple fragment hosts %s", hosts);
+		if (hosts.size() == 1) {
+			Map.Entry<String, Map<String, String>> entry = hosts.entrySet().iterator().next();
+			String host = entry.getKey();
+			VersionRange range = range(entry.getValue().get(Constants.VERSION_ATTRIBUTE));
+			requirements.add(new Requirement(Type.HOST, host, range, false));
+			fragments = null;
+		} else {
+			fragments = new ArrayList<Resource>();
+			capabilities.add(new Capability(Type.BUNDLE, bsn, version));
+		}
+
+		Map<String, Map<String, String>> rbs = resolver.parseHeader(main.getValue(Constants.REQUIRE_BUNDLE));
+		for (Map.Entry<String, Map<String, String>> clause : rbs.entrySet()) {
+			boolean optional = "optional".equals(clause.getValue().get(
+					Constants.RESOLUTION_DIRECTIVE));
+			requirements.add(new Requirement(Type.BUNDLE, clause.getKey(), range(clause
+					.getValue().get(Constants.VERSION_ATTRIBUTE)), optional));
+		}
+		Map<String, Map<String, String>> imports = resolver.parseHeader(main
+				.getValue(Constants.IMPORT_PACKAGE));
+		for (Map.Entry<String, Map<String, String>> clause : imports.entrySet()) {
+			boolean optional = "optional".equals(clause.getValue().get(
+					Constants.RESOLUTION_DIRECTIVE));
+			requirements.add(new Requirement(Type.PACKAGE, clause.getKey(), range(clause
+					.getValue().get(Constants.VERSION_ATTRIBUTE)), optional));
+		}
+		Map<String, Map<String, String>> exports = resolver.parseHeader(main
+				.getValue(Constants.EXPORT_PACKAGE));
+		for (Map.Entry<String, Map<String, String>> clause : exports.entrySet()) {
+			capabilities.add(new Capability(Type.PACKAGE, clause.getKey(), version(clause
+					.getValue().get(Constants.VERSION_ATTRIBUTE))));
+		}
+	}
+
+	private VersionRange range(String string) {
+		try {
+			return new VersionRange(string);
+		} catch (NullPointerException e) {
+			return new VersionRange("0");
+		} catch (Exception e) {
+			resolver.error("Invalid version range: %s in %s-%s", string, bsn, version);
+			return new VersionRange("0");
+		}
+	}
+
+	private Version version(String string) {
+		try {
+			return new Version(string);
+		} catch (NullPointerException e) {
+			return new Version("0");
+		} catch (Exception e) {
+			resolver.error("Invalid version: %s in %s-%s", string, bsn, version);
+			return new Version("0");
+		}
+	}
+	
+	public String toString() {
+		return bsn + "-" + version;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/AnalyzerPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/AnalyzerPlugin.java
new file mode 100644
index 0000000..3efe8ee
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/AnalyzerPlugin.java
@@ -0,0 +1,20 @@
+package aQute.bnd.service;
+
+import aQute.lib.osgi.*;
+
+public interface AnalyzerPlugin {
+
+    /**
+     * This plugin is called after analysis. The plugin is free to modify the
+     * jar and/or change the classpath information (see referred, contained).
+     * This plugin is called after analysis of the JAR but before manifest
+     * generation.
+     * 
+     * @param analyzer
+     * @return true if the classpace has been modified so that the bundle
+     *         classpath must be reanalyzed
+     * @throws Exception
+     */
+
+    boolean analyzeJar(Analyzer analyzer) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/BndListener.java b/bundleplugin/src/main/java/aQute/bnd/service/BndListener.java
new file mode 100644
index 0000000..3ec6ef1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/BndListener.java
@@ -0,0 +1,17 @@
+package aQute.bnd.service;
+
+import java.io.*;
+import java.util.concurrent.atomic.*;
+
+public class BndListener {
+	final AtomicInteger inside = new AtomicInteger();
+	
+    public void changed(File file) {
+    }
+    public void begin() { inside.incrementAndGet();}
+    public void end() { inside.decrementAndGet(); }
+    
+    public boolean isInside() {
+    	return inside.get()!=0;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/CommandPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/CommandPlugin.java
new file mode 100644
index 0000000..34c72c2
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/CommandPlugin.java
@@ -0,0 +1,30 @@
+package aQute.bnd.service;
+
+import aQute.bnd.build.*;
+
+/**
+ * A plugin that makes it possible to 
+ * @author aqute
+ *
+ */
+public interface CommandPlugin {
+    /**
+     * Is run before a command is executed. These plugins are called
+     * in the order of declaration.
+     * 
+     * @param project The project for which the command runs
+     * 
+     * @param command the command name
+     */
+    void before(Project project, String command);
+    
+    /**
+     * Is run after a command is executed. These plugins are
+     * called in the reverse order of declaration.
+     * 
+     * @param project The project for which the command runs
+     *
+     * @param command the command name
+     */
+    void after(Project project, String command, Throwable outcome);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/Compiler.java b/bundleplugin/src/main/java/aQute/bnd/service/Compiler.java
new file mode 100644
index 0000000..626b68c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/Compiler.java
@@ -0,0 +1,11 @@
+package aQute.bnd.service;
+
+import java.io.*;
+import java.util.*;
+
+import aQute.bnd.build.*;
+
+public interface Compiler {
+	boolean compile(Project project, Collection<File> sources, Collection<Container> buildpath,
+			File bin) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/DependencyContributor.java b/bundleplugin/src/main/java/aQute/bnd/service/DependencyContributor.java
new file mode 100644
index 0000000..e6a88ff
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/DependencyContributor.java
@@ -0,0 +1,9 @@
+package aQute.bnd.service;
+
+import java.util.*;
+
+import aQute.bnd.build.*;
+
+public interface DependencyContributor {
+    void addDependencies(Project project, Set<String> dependencies);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/Deploy.java b/bundleplugin/src/main/java/aQute/bnd/service/Deploy.java
new file mode 100644
index 0000000..e1d92e1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/Deploy.java
@@ -0,0 +1,12 @@
+package aQute.bnd.service;
+
+import aQute.bnd.build.*;
+import aQute.lib.osgi.*;
+
+/**
+ * Deploy this artifact to maven.
+ * 
+ */
+public interface Deploy {	
+	boolean deploy(Project project, Jar jar) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/EclipseJUnitTester.java b/bundleplugin/src/main/java/aQute/bnd/service/EclipseJUnitTester.java
new file mode 100644
index 0000000..a2af9b0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/EclipseJUnitTester.java
@@ -0,0 +1,6 @@
+package aQute.bnd.service;
+
+public interface EclipseJUnitTester {
+	void setPort(int port);
+	void setHost( String host);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/LauncherPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/LauncherPlugin.java
new file mode 100644
index 0000000..f858500
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/LauncherPlugin.java
@@ -0,0 +1,9 @@
+package aQute.bnd.service;
+
+import aQute.bnd.build.*;
+
+public interface LauncherPlugin {
+	ProjectLauncher getLauncher(Project project) throws Exception;
+
+	ProjectTester getTester(Project project);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/MakePlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/MakePlugin.java
new file mode 100644
index 0000000..20a1849
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/MakePlugin.java
@@ -0,0 +1,21 @@
+package aQute.bnd.service;
+
+import java.util.*;
+
+import aQute.lib.osgi.*;
+
+public interface MakePlugin {
+
+    /**
+     * This plugin is called when Include-Resource detects a reference to a resource
+     * that it can not find in the file system.
+     * 
+     * @param builder   The current builder
+     * @param source    The source string (i.e. the place where bnd looked)
+     * @param arguments Any arguments on the clause in Include-Resource
+     * @return          A resource or null if no resource could be made
+     * @throws Exception
+     */
+    Resource make(Builder builder, String source, Map<String,String> arguments) throws Exception;
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/OBRIndexProvider.java b/bundleplugin/src/main/java/aQute/bnd/service/OBRIndexProvider.java
new file mode 100644
index 0000000..fe12712
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/OBRIndexProvider.java
@@ -0,0 +1,11 @@
+package aQute.bnd.service;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Set;
+
+public interface OBRIndexProvider {
+	Collection<URL> getOBRIndexes() throws IOException;
+	Set<OBRResolutionMode> getSupportedModes();
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/OBRResolutionMode.java b/bundleplugin/src/main/java/aQute/bnd/service/OBRResolutionMode.java
new file mode 100644
index 0000000..f269d45
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/OBRResolutionMode.java
@@ -0,0 +1,5 @@
+package aQute.bnd.service;
+
+public enum OBRResolutionMode {
+	build, runtime
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/Plugin.java b/bundleplugin/src/main/java/aQute/bnd/service/Plugin.java
new file mode 100644
index 0000000..065fac8
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/Plugin.java
@@ -0,0 +1,31 @@
+package aQute.bnd.service;
+
+import java.util.*;
+
+import aQute.libg.reporter.*;
+
+/**
+ * An optional interface for plugins. If a plugin implements this interface then
+ * it can receive the reminaing attributes and directives given in its clause as
+ * well as the reporter to use.
+ * 
+ */
+public interface Plugin {
+    /**
+     * Give the plugin the remaining properties.
+     * 
+     * When a plugin is declared, the clause can contain extra properties.
+     * All the properties and directives are given to the plugin to use.
+     * 
+     * @param map attributes and directives for this plugin's clause
+     */
+    void setProperties(Map<String,String> map);
+    
+    /**
+     * Set the current reporter. This is called at init time. This plugin
+     * should report all errors and warnings to this reporter.
+     * 
+     * @param processor
+     */
+    void setReporter(Reporter processor);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/Refreshable.java b/bundleplugin/src/main/java/aQute/bnd/service/Refreshable.java
new file mode 100644
index 0000000..e5e62e9
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/Refreshable.java
@@ -0,0 +1,8 @@
+package aQute.bnd.service;
+
+import java.io.*;
+
+public interface Refreshable {
+    boolean refresh();
+    File getRoot();
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/Registry.java b/bundleplugin/src/main/java/aQute/bnd/service/Registry.java
new file mode 100644
index 0000000..90fca36
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/Registry.java
@@ -0,0 +1,11 @@
+package aQute.bnd.service;
+
+import java.util.*;
+
+/**
+ * A registry for objects.
+ */
+public interface Registry {
+	<T> List<T> getPlugins(Class<T> c);
+	<T> T getPlugin(Class<T> c);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/RegistryPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/RegistryPlugin.java
new file mode 100644
index 0000000..7a46849
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/RegistryPlugin.java
@@ -0,0 +1,9 @@
+package aQute.bnd.service;
+
+
+/**
+ * A plugin that wants a registry
+ */
+public interface RegistryPlugin {
+	void setRegistry(Registry registry);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/RemoteRepositoryPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/RemoteRepositoryPlugin.java
new file mode 100644
index 0000000..cbd42b8
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/RemoteRepositoryPlugin.java
@@ -0,0 +1,17 @@
+package aQute.bnd.service;
+
+import java.util.Map;
+
+public interface RemoteRepositoryPlugin extends RepositoryPlugin {
+	/**
+	 * Retrieve a resource handle from the repository. For all implementations of this interface, calling {@code getFile(bsn, range, strategy, props)}
+	 * should always return the same result as {@code getResource(bsn, range, strategy, props).request()}.
+	 * @param bsn
+	 * @param range
+	 * @param strategy
+	 * @param properties
+	 * @return
+	 * @throws Exception
+	 */
+	ResourceHandle getHandle(String bsn, String range, Strategy strategy, Map<String,String> properties) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/RepositoryListenerPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/RepositoryListenerPlugin.java
new file mode 100644
index 0000000..0044da3
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/RepositoryListenerPlugin.java
@@ -0,0 +1,16 @@
+package aQute.bnd.service;
+
+import java.io.File;
+
+import aQute.lib.osgi.Jar;
+
+public interface RepositoryListenerPlugin {
+	
+	/**
+	 * Called when a bundle is added to a repository.
+	 * @param repository
+	 * @param jar
+	 * @param file
+	 */
+	void bundleAdded(RepositoryPlugin repository, Jar jar, File file);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java
new file mode 100644
index 0000000..a01c4b1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java
@@ -0,0 +1,86 @@
+package aQute.bnd.service;
+
+import java.io.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+import aQute.libg.version.*;
+
+public interface RepositoryPlugin {
+	public enum Strategy {
+		LOWEST, HIGHEST, EXACT
+	}
+
+	/**
+	 * Return a URL to a matching version of the given bundle.
+	 * 
+	 * @param bsn
+	 *            Bundle-SymbolicName of the searched bundle
+	 * @param range
+	 *            Version range for this bundle,"latest" if you only want the
+	 *            latest, or null when you want all.
+	 * @return A list of URLs sorted on version, lowest version is at index 0.
+	 *         null is returned when no files with the given bsn ould be found.
+	 * @throws Exception
+	 *             when anything goes wrong
+	 */
+	@Deprecated File[] get(String bsn, String range) throws Exception;
+
+	/**
+	 * Return a URL to a matching version of the given bundle.
+	 * 
+	 * @param bsn
+	 *            Bundle-SymbolicName of the searched bundle
+	 * @param range
+	 *            Version range for this bundle,"latest" if you only want the
+	 *            latest, or null when you want all.
+	 * @param strategy
+	 *            Get the highest or the lowest
+	 * @return A list of URLs sorted on version, lowest version is at index 0.
+	 *         null is returned when no files with the given bsn ould be found.
+	 * @throws Exception
+	 *             when anything goes wrong
+	 */
+	File get(String bsn, String range, Strategy strategy, Map<String,String> properties) throws Exception;
+
+	/**
+	 * Answer if this repository can be used to store files.
+	 * 
+	 * @return true if writable
+	 */
+	boolean canWrite();
+
+	/**
+	 * Put a JAR file in the repository.
+	 * 
+	 * @param jar
+	 * @throws Exception
+	 */
+	File put(Jar jar) throws Exception;
+
+	/**
+	 * Return a list of bsns that are present in the repository.
+	 * 
+	 * @param regex
+	 *            if not null, match against the bsn and if matches, return
+	 *            otherwise skip
+	 * @return A list of bsns that match the regex parameter or all if regex is
+	 *         null
+	 * @throws Exception
+	 */
+	List<String> list(String regex) throws Exception;
+
+	/**
+	 * Return a list of versions.
+	 * 
+	 * @throws Exception
+	 */
+
+	List<Version> versions(String bsn) throws Exception;
+
+	/**
+	 * @return The name of the repository
+	 */
+	String getName();
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/ResourceHandle.java b/bundleplugin/src/main/java/aQute/bnd/service/ResourceHandle.java
new file mode 100644
index 0000000..d08ea2c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/ResourceHandle.java
@@ -0,0 +1,13 @@
+package aQute.bnd.service;
+
+import java.io.File;
+import java.io.IOException;
+
+public interface ResourceHandle {
+	
+	public enum Location { local, remote_cached, remote };
+	
+	String getName();
+	Location getLocation();
+	File request() throws IOException;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/Scripter.java b/bundleplugin/src/main/java/aQute/bnd/service/Scripter.java
new file mode 100644
index 0000000..2e4e1d3
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/Scripter.java
@@ -0,0 +1,10 @@
+package aQute.bnd.service;
+
+import java.io.*;
+import java.util.*;
+
+public interface Scripter {
+
+	void eval(Map<String, Object> x, StringReader stringReader);
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/SignerPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/SignerPlugin.java
new file mode 100644
index 0000000..aaef646
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/SignerPlugin.java
@@ -0,0 +1,15 @@
+package aQute.bnd.service;
+
+import aQute.lib.osgi.*;
+
+public interface SignerPlugin {
+    /**
+     * Sign the current jar. The alias is the given certificate 
+     * keystore.
+     * 
+     * @param builder   The current builder that contains the jar to sign
+     * @param alias     The keystore certificate alias
+     * @throws Exception When anything goes wrong
+     */
+    void sign(Builder builder, String alias) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/action/Action.java b/bundleplugin/src/main/java/aQute/bnd/service/action/Action.java
new file mode 100644
index 0000000..5167827
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/action/Action.java
@@ -0,0 +1,7 @@
+package aQute.bnd.service.action;
+
+import aQute.bnd.build.*;
+
+public interface Action {
+    void execute( Project project, String action) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/action/NamedAction.java b/bundleplugin/src/main/java/aQute/bnd/service/action/NamedAction.java
new file mode 100644
index 0000000..5a1c697
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/action/NamedAction.java
@@ -0,0 +1,6 @@
+package aQute.bnd.service.action;
+
+
+public interface NamedAction extends Action {
+    String getName();
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/action/packageinfo b/bundleplugin/src/main/java/aQute/bnd/service/action/packageinfo
new file mode 100644
index 0000000..ec0efd4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/action/packageinfo
@@ -0,0 +1 @@
+version 1.43.1
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/packageinfo b/bundleplugin/src/main/java/aQute/bnd/service/packageinfo
new file mode 100644
index 0000000..5035fd2
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/packageinfo
@@ -0,0 +1 @@
+version 1.44.0
diff --git a/bundleplugin/src/main/java/aQute/bnd/settings/Settings.java b/bundleplugin/src/main/java/aQute/bnd/settings/Settings.java
new file mode 100644
index 0000000..78ed213
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/settings/Settings.java
@@ -0,0 +1,62 @@
+package aQute.bnd.settings;
+
+import java.security.*;
+import java.security.interfaces.*;
+import java.util.*;
+import java.util.prefs.*;
+
+import aQute.libg.cryptography.*;
+import aQute.libg.tuple.*;
+
+public class Settings {
+	public final static String	EMAIL			= "email";
+	public final static String	NAME			= "name";
+	public final static String	PASSWORD_SHA1	= "password.sha1";
+	final static String			KEY_PRIVATE		= "key.private";
+	final static String			KEY_PUBLIC		= "key.public";
+	final static String			KEY_SET			= "key.set";
+
+	static Preferences			prefs			= Preferences.userNodeForPackage(Settings.class);
+
+	public String globalGet(String key, String def) {
+		return prefs.get(key, def);
+	}
+
+	public void globalSet(String key, String value) throws BackingStoreException {
+		prefs.put(key, value);
+		prefs.sync();
+	}
+
+	public Collection<String> getKeys() throws BackingStoreException {
+		return Arrays.asList(prefs.keys());
+	}
+
+	public void globalRemove(String key) throws BackingStoreException {
+		prefs.remove(key);
+		prefs.sync();
+	}
+
+	private void generate() throws NoSuchAlgorithmException {
+		Pair<? extends PrivateKey, ? extends RSAPublicKey> pair = RSA.generate();
+		prefs.put(KEY_PRIVATE, Crypto.toString(pair.a));
+		prefs.put(KEY_PUBLIC, Crypto.toString(pair.b));
+		prefs.putBoolean(KEY_SET, true);
+	}
+
+	public PrivateKey getPrivateKey() throws Exception {
+		if (prefs.getBoolean(KEY_SET, false))
+			generate();
+
+		String key = prefs.get(KEY_PRIVATE, null);
+		return Crypto.fromString(key, PrivateKey.class);
+	}
+
+	public PublicKey getPublicKey() throws Exception {
+		if (prefs.getBoolean(KEY_SET, false))
+			generate();
+
+		String key = prefs.get(KEY_PUBLIC, null);
+		return Crypto.fromString(key, PublicKey.class);
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/signing/JartoolSigner.java b/bundleplugin/src/main/java/aQute/bnd/signing/JartoolSigner.java
new file mode 100644
index 0000000..13e07cb
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/signing/JartoolSigner.java
@@ -0,0 +1,135 @@
+package aQute.bnd.signing;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.libg.command.*;
+import aQute.libg.reporter.*;
+
+/**
+ * Sign the jar file.
+ * 
+ * -sign : <alias> [ ';' 'password:=' <password> ] [ ';' 'keystore:=' <keystore> ] [
+ * ';' 'sign-password:=' <pw> ] ( ',' ... )*
+ * 
+ * @author aqute
+ * 
+ */
+public class JartoolSigner implements Plugin, SignerPlugin {
+    String keystore;
+    String storetype;
+    String path = "jarsigner";
+    String storepass;
+    String keypass;
+    String sigFile;
+
+    public void setProperties(Map<String, String> map) {
+        if (map.containsKey("keystore"))
+            this.keystore = map.get("keystore");
+        if (map.containsKey("storetype"))
+            this.storetype = map.get("storetype");
+        if (map.containsKey("storepass"))
+            this.storepass = map.get("storepass");
+        if (map.containsKey("keypass"))
+            this.keypass = map.get("keypass");
+        if (map.containsKey("path"))
+            this.path = map.get("path");
+        if (map.containsKey("sigFile"))
+            this.sigFile = map.get("sigFile");
+
+    }
+
+    public void setReporter(Reporter processor) {
+    }
+
+    public void sign(Builder builder, String alias) throws Exception {    	    	
+    	File f = builder.getFile(keystore);
+    	if ( !f.isFile()) {
+    		builder.error("Invalid keystore %s", f.getAbsolutePath() );
+    		return;
+    	}
+    	
+        Jar jar = builder.getJar();
+        File tmp = File.createTempFile("signdjar", ".jar");
+        tmp.deleteOnExit();
+
+        jar.write(tmp);
+
+        Command command = new Command();
+        command.add(path);
+        if (keystore != null) {
+            command.add("-keystore");
+            command.add(f.getAbsolutePath());
+        }
+
+        if (storetype != null) {
+        	command.add("-storetype");
+        	command.add(storetype);
+        }
+
+        if (keypass != null) {
+        	command.add("-keypass");
+        	command.add(keypass);
+        }
+
+        if (storepass != null) {
+        	command.add("-storepass");
+        	command.add(storepass);
+        }
+
+        if (sigFile != null) {
+        	command.add("-sigFile");
+        	command.add(sigFile);
+        }
+
+        command.add(tmp.getAbsolutePath());
+        command.add(alias);
+        builder.trace("Jarsigner command: %s", command);
+        command.setTimeout(20, TimeUnit.SECONDS);
+        StringBuffer out = new StringBuffer();
+        StringBuffer err = new StringBuffer();
+        int exitValue = command.execute(System.in, out, err);
+        if (exitValue != 0) {
+            builder.error("Signing Jar out: %s\nerr: %s", out, err);
+        } else {
+            builder.trace("Signing Jar out: %s \nerr: %s", out, err);
+        }
+
+        Jar signed = new Jar(tmp);
+        builder.addClose(signed);
+
+        Map<String, Resource> dir = signed.getDirectories().get("META-INF");
+        for (String path : dir.keySet()) {
+            if (path.matches(".*\\.(DSA|RSA|SF|MF)$")) {
+                jar.putResource(path, dir.get(path));
+            }
+        }
+        jar.setDoNotTouchManifest();
+    }
+
+    StringBuffer collect(final InputStream in) throws Exception {
+        final StringBuffer sb = new StringBuffer();
+        
+        Thread tin = new Thread() {
+            public void run() {
+                try {
+                    BufferedReader rdr = new BufferedReader(new InputStreamReader(in, Constants.DEFAULT_CHARSET));
+                    String line = rdr.readLine();
+                    while (line != null) {
+                        sb.append(line);
+                        line = rdr.readLine();
+                    }
+                    rdr.close();
+                    in.close();
+                } catch (Exception e) {
+                    // Ignore any exceptions
+                }
+            }
+        };
+        tin.start();
+        return sb;
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/signing/Signer.java b/bundleplugin/src/main/java/aQute/bnd/signing/Signer.java
new file mode 100644
index 0000000..bed91be
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/signing/Signer.java
@@ -0,0 +1,191 @@
+package aQute.bnd.signing;
+
+import java.io.*;
+import java.security.*;
+import java.security.KeyStore.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.lib.base64.*;
+import aQute.lib.osgi.*;
+
+/**
+ * This class is used with the aQute.lib.osgi package, it signs jars with DSA
+ * signature.
+ * 
+ * -sign: md5, sha1
+ */
+public class Signer extends Processor {
+    static Pattern  METAINFDIR   = Pattern.compile("META-INF/[^/]*");
+    String         digestNames[]    = new String[] { "MD5" };
+    File           keystoreFile  = new File("keystore");
+    String         password;
+    String         alias;
+
+    public void signJar(Jar jar) {
+        if (digestNames == null || digestNames.length == 0)
+            error("Need at least one digest algorithm name, none are specified");
+
+        if (keystoreFile == null || !keystoreFile.getAbsoluteFile().exists()) {
+            error("No such keystore file: " + keystoreFile);
+            return;
+        }
+
+        if (alias == null) {
+            error("Private key alias not set for signing");
+            return;
+        }
+
+        MessageDigest digestAlgorithms[] = new MessageDigest[digestNames.length];
+
+        getAlgorithms(digestNames, digestAlgorithms);
+
+        try {
+            Manifest manifest = jar.getManifest();
+            manifest.getMainAttributes().putValue("Signed-By", "Bnd");
+
+            // Create a new manifest that contains the
+            // Name parts with the specified digests
+
+            ByteArrayOutputStream o = new ByteArrayOutputStream();
+            manifest.write(o);
+            doManifest(jar, digestNames, digestAlgorithms, o);
+            o.flush();
+            byte newManifestBytes[] = o.toByteArray();
+            jar.putResource("META-INF/MANIFEST.MF", new EmbeddedResource(
+                    newManifestBytes, 0));
+
+            // Use the bytes from the new manifest to create
+            // a signature file
+
+            byte[] signatureFileBytes = doSignatureFile(digestNames,
+                    digestAlgorithms, newManifestBytes);
+            jar.putResource("META-INF/BND.SF", new EmbeddedResource(
+                    signatureFileBytes, 0));
+
+            // Now we must create an RSA signature
+            // this requires the private key from the keystore
+
+            KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
+
+            KeyStore.PrivateKeyEntry privateKeyEntry = null;
+
+            try {
+                java.io.FileInputStream keystoreInputStream = new java.io.FileInputStream(
+                        keystoreFile);
+                keystore.load(keystoreInputStream, password == null ? null
+                        : password.toCharArray());
+                keystoreInputStream.close();
+                privateKeyEntry =  (PrivateKeyEntry) keystore.getEntry(
+                        alias, new KeyStore.PasswordProtection(password
+                                .toCharArray()));
+            } catch (Exception e) {
+                error("No able to load the private key from the give keystore("+keystoreFile.getAbsolutePath()+") with alias "+alias+" : "
+                        + e);
+                return;
+            }
+            PrivateKey privateKey = privateKeyEntry.getPrivateKey();
+
+            Signature signature = Signature.getInstance("MD5withRSA");
+            signature.initSign(privateKey);
+
+            signature.update(signatureFileBytes);
+
+            signature.sign();
+
+            // TODO, place the SF in a PCKS#7 structure ...
+            // no standard class for this? The following
+            // is an idea but we will to have do ASN.1 BER
+            // encoding ...
+
+         
+            
+            ByteArrayOutputStream tmpStream = new ByteArrayOutputStream();
+            jar.putResource("META-INF/BND.RSA", new EmbeddedResource(tmpStream
+                    .toByteArray(), 0));
+        } catch (Exception e) {
+            error("During signing: " + e);
+        }
+    }
+
+    private byte[] doSignatureFile(String[] digestNames,
+            MessageDigest[] algorithms, byte[] manbytes) {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream(out);
+        ps.print("Signature-Version: 1.0\r\n");
+
+        for (int a = 0; a < algorithms.length; a++) {
+            if (algorithms[a] != null) {
+                byte[] digest = algorithms[a].digest(manbytes);
+                ps.print(digestNames[a] + "-Digest-Manifest: ");
+                ps.print(new Base64(digest));
+                ps.print("\r\n");
+            }
+        }
+        return out.toByteArray();
+    }
+
+    private void doManifest(Jar jar, String[] digestNames,
+            MessageDigest[] algorithms, OutputStream out) throws Exception {
+
+        for (Map.Entry<String,Resource> entry : jar.getResources().entrySet()) {
+            String name = entry.getKey();
+            if (!METAINFDIR.matcher(name).matches()) {
+                out.write("\r\n".getBytes());
+                out.write("Name: ".getBytes());
+                out.write(name.getBytes());
+                out.write("\r\n".getBytes());
+
+                digest(algorithms, entry.getValue());
+                for (int a = 0; a < algorithms.length; a++) {
+                    if (algorithms[a] != null) {
+                        byte[] digest = algorithms[a].digest();
+                        String header = digestNames[a] + "-Digest: "
+                                + new Base64(digest) + "\r\n";
+                        out.write(header.getBytes());
+                    }
+                }
+            }
+        }
+    }
+
+    private void digest(MessageDigest[] algorithms, Resource r)
+            throws Exception {
+        InputStream in = r.openInputStream();
+        byte[] data = new byte[1024];
+        int size = in.read(data);
+        while (size > 0) {
+            for (int a = 0; a < algorithms.length; a++) {
+                if (algorithms[a] != null) {
+                    algorithms[a].update(data, 0, size);
+                }
+            }
+            size = in.read(data);
+        }
+    }
+
+    private void getAlgorithms(String[] digestNames, MessageDigest[] algorithms) {
+        for (int i = 0; i < algorithms.length; i++) {
+            String name = digestNames[i];
+            try {
+                algorithms[i] = MessageDigest.getInstance(name);
+            } catch (NoSuchAlgorithmException e) {
+                error("Specified digest algorithm " + digestNames[i]
+                        + ", but not such algorithm was found: " + e);
+            }
+        }
+    }
+
+    public void setPassword(String string) {
+        password = string;
+    }
+
+    public void setKeystore(File keystore) {
+        this.keystoreFile = keystore;
+    }
+
+    public void setAlias(String string) {
+        this.alias = string;
+    }
+}
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
diff --git a/bundleplugin/src/main/java/aQute/libg/command/Command.java b/bundleplugin/src/main/java/aQute/libg/command/Command.java
new file mode 100644
index 0000000..bae82eb
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/command/Command.java
@@ -0,0 +1,194 @@
+package aQute.libg.command;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import aQute.libg.reporter.*;
+
+public class Command {
+
+	boolean				trace;
+	Reporter			reporter;
+	List<String>		arguments	= new ArrayList<String>();
+	long				timeout		= 0;
+	File				cwd			= new File("").getAbsoluteFile();
+	static Timer		timer		= new Timer();
+	Process				process;
+	volatile boolean	timedout;
+
+	public int execute(Appendable stdout, Appendable stderr) throws Exception {
+		return execute((InputStream) null, stdout, stderr);
+	}
+
+	public int execute(String input, Appendable stdout, Appendable stderr) throws Exception {
+		InputStream in = new ByteArrayInputStream(input.getBytes("UTF-8"));
+		return execute(in, stdout, stderr);
+	}
+
+	public int execute(InputStream in, Appendable stdout, Appendable stderr) throws Exception {
+		int result;
+		if (reporter != null) {
+			reporter.trace("executing cmd: %s", arguments);
+		}
+
+		String args[] = arguments.toArray(new String[arguments.size()]);
+
+		process = Runtime.getRuntime().exec(args, null, cwd);
+
+		// Make sure the command will not linger when we go
+		Runnable r = new Runnable() {
+			public void run() {
+				process.destroy();
+			}
+		};
+		Thread hook = new Thread(r, arguments.toString());
+		Runtime.getRuntime().addShutdownHook(hook);
+		TimerTask timer = null;
+		OutputStream stdin = process.getOutputStream();
+		final InputStreamHandler handler = in != null ? new InputStreamHandler(in, stdin) : null;
+		
+		if (timeout != 0) {
+			timer = new TimerTask() {
+				public void run() {
+					timedout = true;
+					process.destroy();
+					if (handler != null)
+						handler.interrupt();
+				}
+			};
+			Command.timer.schedule(timer, timeout);
+		}
+
+		InputStream out = process.getInputStream();
+		try {
+			InputStream err = process.getErrorStream();
+			try {
+				new Collector(out, stdout).start();
+				new Collector(err, stdout).start();
+				if (handler != null)
+					handler.start();
+
+				result = process.waitFor();
+			} finally {
+				err.close();
+			}
+		} finally {
+			out.close();
+			if (timer != null)
+				timer.cancel();
+			Runtime.getRuntime().removeShutdownHook(hook);
+			if (handler != null)
+				handler.interrupt();
+		}
+		if (reporter != null)
+			reporter.trace("cmd %s executed with result=%d, result: %s/%s", arguments, result,
+					stdout, stderr);
+
+		if( timedout )
+			return Integer.MIN_VALUE;
+		byte exitValue = (byte) process.exitValue();
+		return exitValue;
+	}
+
+	public void add(String... args) {
+		for (String arg : args)
+			arguments.add(arg);
+	}
+
+	public void addAll(Collection<String> args) {
+		arguments.addAll(args);
+	}
+
+	public void setTimeout(long duration, TimeUnit unit) {
+		timeout = unit.toMillis(duration);
+	}
+
+	public void setTrace() {
+		this.trace = true;
+	}
+
+	public void setReporter(Reporter reporter) {
+		this.reporter = reporter;
+	}
+
+	public void setCwd(File dir) {
+		if (!dir.isDirectory())
+			throw new IllegalArgumentException("Working directory must be a directory: " + dir);
+
+		this.cwd = dir;
+	}
+
+	public void cancel() {
+		process.destroy();
+	}
+
+	class Collector extends Thread {
+		final InputStream	in;
+		final Appendable	sb;
+
+		public Collector(InputStream inputStream, Appendable sb) {
+			this.in = inputStream;
+			this.sb = sb;
+		}
+
+		public void run() {
+			try {
+				int c = in.read();
+				while (c >= 0) {
+					if (trace)
+						System.out.print((char) c);
+					sb.append((char) c);
+					c = in.read();
+				}
+			} catch (Exception e) {
+				try {
+					sb.append("\n**************************************\n");
+					sb.append(e.toString());
+					sb.append("\n**************************************\n");
+				} catch (IOException e1) {
+				}
+				if (reporter != null) {
+					reporter.trace("cmd exec: %s", e);
+				}
+			}
+		}
+	}
+
+	class InputStreamHandler extends Thread {
+		final InputStream	in;
+		final OutputStream	stdin;
+
+		public InputStreamHandler(InputStream in, OutputStream stdin) {
+			this.stdin = stdin;
+			this.in = in;
+		}
+
+		public void run() {
+			try {
+				int c = in.read();
+				while (c >= 0) {
+					stdin.write(c);
+					stdin.flush();
+					c = in.read();
+				}
+			} catch (InterruptedIOException e) {
+				// Ignore here
+			} catch (Exception e) {
+				// Who cares?
+			}
+		}
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		String del = "";
+
+		for (String argument : arguments) {
+			sb.append(del);
+			sb.append(argument);
+			del = " ";
+		}
+		return sb.toString();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/command/packageinfo b/bundleplugin/src/main/java/aQute/libg/command/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/command/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Crypto.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Crypto.java
new file mode 100644
index 0000000..630597f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Crypto.java
@@ -0,0 +1,67 @@
+package aQute.libg.cryptography;
+
+import java.math.*;
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+import java.util.regex.*;
+
+public class Crypto {
+	static final Pattern	RSA_PRIVATE	= Pattern
+												.compile("\\s*RSA.Private\\((\\p{xDigit})+:(\\p{xDigit})+\\)\\s*");
+	static final Pattern	RSA_PUBLIC	= Pattern
+												.compile("\\s*RSA.Public\\((\\p{xDigit})+:(\\p{xDigit})+\\)\\s*");
+
+	/**
+	 * 
+	 * @param <T>
+	 * @param spec
+	 * @return
+	 * @throws Exception
+	 */
+	@SuppressWarnings("unchecked") public static <T> T fromString(String spec, Class<T> c) throws Exception {
+		if ( PrivateKey.class.isAssignableFrom(c)) {
+			Matcher m = RSA_PRIVATE.matcher(spec); 
+			if ( m.matches()) {
+				return (T) RSA.createPrivate(  
+						new BigInteger(m.group(1)), new BigInteger(m.group(2)));
+			}
+			throw new IllegalArgumentException("No such private key " + spec );
+		}
+		
+		if ( PublicKey.class.isAssignableFrom(c)) {
+			Matcher m = RSA_PUBLIC.matcher(spec); 
+			if ( m.matches()) {
+				return (T) RSA.create( new RSAPublicKeySpec( 
+						new BigInteger(m.group(1)), new BigInteger(m.group(2))));
+			}
+			throw new IllegalArgumentException("No such public key " + spec );			
+		}
+		return null;
+	}
+
+	public static String toString( Object key ) {
+		if ( key instanceof RSAPrivateKey ) {
+			RSAPrivateKey pk = (RSAPrivateKey) key;
+			return "RSA.Private(" + pk.getModulus() + ":" + pk.getPrivateExponent() + ")";
+		}
+		if ( key instanceof RSAPublicKey ) {
+			RSAPublicKey pk = (RSAPublicKey) key;
+			return "RSA.Private(" + pk.getModulus() + ":" + pk.getPublicExponent() + ")";
+		}
+		return null;
+	}
+
+
+	public static <T extends Digest> Signer<T> signer(PrivateKey key, Digester<T> digester) throws NoSuchAlgorithmException {
+		Signature s = Signature.getInstance(key.getAlgorithm() + "with" + digester.getAlgorithm());
+		return new Signer<T>(s,digester);
+	}
+
+	public static Verifier verifier(PublicKey key, Digest digest) throws NoSuchAlgorithmException {
+		Signature s = Signature.getInstance(key.getAlgorithm() + "with" + digest.getAlgorithm());
+		return new Verifier(s,digest);
+	}
+
+	
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Digest.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Digest.java
new file mode 100644
index 0000000..f70caa0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Digest.java
@@ -0,0 +1,25 @@
+package aQute.libg.cryptography;
+
+import aQute.lib.hex.*;
+
+public abstract class Digest {
+	final byte[]	digest;
+
+	protected Digest(byte[] checksum, int width) {
+		this.digest = checksum;
+		if (digest.length != width)
+			throw new IllegalArgumentException("Invalid width for digest: " + digest.length
+					+ " expected " + width);
+	}
+
+
+	public byte[] digest() {
+		return digest;
+	}
+
+	@Override public String toString() {
+		return String.format("%s(d=%s)", getAlgorithm(), Hex.toHexString(digest));
+	}
+
+	public abstract String getAlgorithm();
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Digester.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Digester.java
new file mode 100644
index 0000000..50b9659
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Digester.java
@@ -0,0 +1,35 @@
+package aQute.libg.cryptography;
+
+import java.io.*;
+import java.security.*;
+
+import aQute.lib.io.*;
+
+public abstract class Digester<T extends Digest> extends OutputStream {
+	protected MessageDigest	md;
+	
+	public Digester(MessageDigest instance){
+		md = instance;
+	}
+	@Override
+	public void write( byte[] buffer, int offset, int length) throws IOException{
+		md.update(buffer,offset,length);
+	}
+	@Override
+	public void write( int b) throws IOException{
+		md.update((byte) b);
+	}
+	
+	public MessageDigest getMessageDigest() throws Exception {
+		return md;
+	}
+	
+	public T from(InputStream in) throws Exception {
+		IO.copy(in,this);
+		return digest();
+	}
+		
+	public abstract T digest() throws Exception;
+	public abstract T digest( byte [] bytes) throws Exception;
+	public abstract String getAlgorithm();
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Key.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Key.java
new file mode 100644
index 0000000..160ec05
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Key.java
@@ -0,0 +1,8 @@
+package aQute.libg.cryptography;
+
+
+public abstract class Key implements java.security.Key {
+	private static final long	serialVersionUID	= 1L;
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/MD5.java b/bundleplugin/src/main/java/aQute/libg/cryptography/MD5.java
new file mode 100644
index 0000000..3fd7158
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/MD5.java
@@ -0,0 +1,33 @@
+package aQute.libg.cryptography;
+
+import java.security.*;
+
+
+
+public class MD5 extends Digest {
+	public final static String ALGORITHM = "MD5";
+	
+	public static Digester<MD5> getDigester() throws Exception {
+		return new Digester<MD5>(MessageDigest.getInstance(ALGORITHM)) {
+			
+			@Override public MD5 digest() throws Exception {
+				return new MD5(md.digest());
+			}
+
+			@Override public MD5 digest(byte[] bytes) {
+				return new MD5(bytes);
+			}
+			@Override public String getAlgorithm() {
+				return ALGORITHM;
+			}
+		};
+	}
+	
+	
+	public MD5(byte[] digest) {
+		super(digest,16);
+	}
+
+	@Override public String getAlgorithm() { return ALGORITHM; }
+
+}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/RSA.java b/bundleplugin/src/main/java/aQute/libg/cryptography/RSA.java
new file mode 100644
index 0000000..61bafb5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/RSA.java
@@ -0,0 +1,43 @@
+package aQute.libg.cryptography;
+
+import java.math.*;
+import java.security.*;
+import java.security.interfaces.*;
+import java.security.spec.*;
+
+import aQute.libg.tuple.*;
+
+public class RSA {
+	final static String		ALGORITHM	= "RSA";
+
+	final static KeyFactory	factory		= getKeyFactory();
+
+	static private KeyFactory getKeyFactory() {
+		try {
+			return KeyFactory.getInstance(ALGORITHM);
+		} catch (Exception e) {
+			// built in
+		}
+		return null;
+	}
+
+	public static RSAPrivateKey create(RSAPrivateKeySpec keyspec) throws InvalidKeySpecException {
+		return (RSAPrivateKey) factory.generatePrivate(keyspec);
+	}
+	public static RSAPublicKey create(RSAPublicKeySpec keyspec) throws InvalidKeySpecException {
+		return (RSAPublicKey) factory.generatePrivate(keyspec);
+	}
+	
+	public static RSAPublicKey createPublic(BigInteger m, BigInteger e) throws InvalidKeySpecException {
+		return create( new RSAPublicKeySpec(m,e));
+	}
+	public static RSAPrivateKey createPrivate(BigInteger m, BigInteger e) throws InvalidKeySpecException {
+		return create( new RSAPrivateKeySpec(m,e));
+	}
+	
+	public static Pair<RSAPrivateKey, RSAPublicKey> generate() throws NoSuchAlgorithmException {
+		KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALGORITHM);
+		KeyPair keypair = kpg.generateKeyPair();
+		return new Pair<RSAPrivateKey,RSAPublicKey>( (RSAPrivateKey) keypair.getPrivate(), (RSAPublicKey) keypair.getPublic());
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/SHA1.java b/bundleplugin/src/main/java/aQute/libg/cryptography/SHA1.java
new file mode 100644
index 0000000..22e725b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/SHA1.java
@@ -0,0 +1,33 @@
+package aQute.libg.cryptography;
+
+import java.security.*;
+
+
+
+public class SHA1 extends Digest {
+	public final static String ALGORITHM = "SHA1";
+	
+	public static Digester<SHA1> getDigester() throws NoSuchAlgorithmException {
+		MessageDigest md = MessageDigest.getInstance(ALGORITHM);
+		return new Digester<SHA1>(md) {
+			@Override public SHA1 digest() throws Exception {
+				return new SHA1(md.digest());
+			}
+
+			@Override public SHA1 digest(byte[] bytes) {
+				return new SHA1(bytes);
+			}
+			@Override public String getAlgorithm() {
+				return ALGORITHM;
+			}
+		};
+	}
+	
+	public SHA1(byte[] b) {
+		super(b, 20);
+	}
+
+
+	@Override public String getAlgorithm() { return ALGORITHM; }
+
+}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Signer.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Signer.java
new file mode 100644
index 0000000..a068677
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Signer.java
@@ -0,0 +1,35 @@
+package aQute.libg.cryptography;
+
+import java.io.*;
+import java.security.*;
+
+public class Signer<D extends Digest> extends OutputStream {
+	Signature	signature;
+	Digester<D> digester;
+	
+	Signer(Signature s, Digester<D> digester) {
+		this.signature = s;
+		this.digester  = digester;
+	}
+
+	@Override public void write(byte[] buffer, int offset, int length) throws IOException {
+		try {
+			signature.update(buffer, offset, length);
+		} catch (SignatureException e) {
+			throw new IOException(e);
+		}
+	}
+
+	@Override public void write(int b) throws IOException {
+		try {
+			signature.update((byte) b);
+		} catch (SignatureException e) {
+			throw new IOException(e);
+		}
+	}
+	
+
+	public D signature() throws Exception {
+		return digester.digest(signature().digest());
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Verifier.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Verifier.java
new file mode 100644
index 0000000..90d6993
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Verifier.java
@@ -0,0 +1,38 @@
+package aQute.libg.cryptography;
+
+import java.io.*;
+import java.security.*;
+
+
+public class Verifier extends OutputStream {
+	final Signature signature;
+	final Digest d;
+	
+	Verifier(Signature s, Digest d) {
+		this.signature = s;
+		this.d = d;
+	}
+	
+	@Override
+	public void write( byte[] buffer, int offset, int length) throws IOException {
+		try {
+			signature.update(buffer, offset, length);
+		} catch (SignatureException e) {
+			throw new IOException(e);
+		}
+	}
+
+	@Override
+	public void write( int b) throws IOException {
+		try {
+			signature.update((byte) b);
+		} catch (SignatureException e) {
+			throw new IOException(e);
+		}
+	}
+
+	public boolean verify() throws Exception {
+		return signature.verify(d.digest());
+	}
+	
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/packageinfo b/bundleplugin/src/main/java/aQute/libg/cryptography/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/fileiterator/FileIterator.java b/bundleplugin/src/main/java/aQute/libg/fileiterator/FileIterator.java
new file mode 100644
index 0000000..c60ed6b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/fileiterator/FileIterator.java
@@ -0,0 +1,45 @@
+package aQute.libg.fileiterator;
+
+import java.io.*;
+import java.util.*;
+
+public class FileIterator implements Iterator<File> {
+    File         dir;
+    int          n = 0;
+    FileIterator next;
+
+    public FileIterator(File nxt) {
+        assert nxt.isDirectory();
+        this.dir = nxt;
+    }
+
+    public boolean hasNext() {
+        if (next != null)
+            return next.hasNext();
+        else
+            return n < dir.list().length;
+    }
+
+    public File next() {
+        if (next != null) {
+            File answer = next.next();
+            if (!next.hasNext())
+                next = null;
+            return answer;
+        } else {
+            File nxt = dir.listFiles()[n++];
+            if (nxt.isDirectory()) {
+                next = new FileIterator(nxt);
+                return nxt;
+            } else if (nxt.isFile()) {
+                return nxt;
+            } else
+                throw new IllegalStateException("File disappeared");
+        }
+    }
+
+    public void remove() {
+        throw new UnsupportedOperationException(
+                "Cannot remove from a file iterator");
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/fileiterator/packageinfo b/bundleplugin/src/main/java/aQute/libg/fileiterator/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/fileiterator/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/filelock/DirectoryLock.java b/bundleplugin/src/main/java/aQute/libg/filelock/DirectoryLock.java
new file mode 100644
index 0000000..6e6b11e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/filelock/DirectoryLock.java
@@ -0,0 +1,32 @@
+package aQute.libg.filelock;
+
+import java.io.*;
+
+public class DirectoryLock {
+	final File						lock;
+	final long						timeout;
+	final public static String LOCKNAME = ".lock";
+
+	public DirectoryLock(File directory, long timeout) {
+		this.lock = new File(directory, LOCKNAME);
+		this.lock.deleteOnExit();
+		this.timeout = timeout;
+	}
+
+	
+	public void release() {
+		lock.delete();
+	}
+
+	public void lock() throws InterruptedException {
+		if (lock.mkdir())
+			return;
+
+		long deadline = System.currentTimeMillis()+ timeout;
+		while ( System.currentTimeMillis() < deadline) {
+			if (lock.mkdir())
+				return;	
+			Thread.sleep(50);
+		}
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/forker/Forker.java b/bundleplugin/src/main/java/aQute/libg/forker/Forker.java
new file mode 100644
index 0000000..530feb0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/forker/Forker.java
@@ -0,0 +1,184 @@
+package aQute.libg.forker;
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+/**
+ * A Forker is good in parallel scheduling tasks with dependencies. You can add
+ * tasks with {@link #doWhen(Collection, Object, Runnable)}. The collection is
+ * the list of dependencies, the object is the target, and the runnable is run
+ * to update the target. The runnable will only run when all its dependencies
+ * have ran their associated runnable.
+ * 
+ * @author aqute
+ * 
+ * @param <T>
+ */
+public class Forker<T> {
+	final Executor		executor;
+	final Set<T>		done		= new HashSet<T>();
+	final List<Job>		waiting		= new ArrayList<Job>();
+	final Semaphore		semaphore	= new Semaphore(0);
+	final AtomicInteger	outstanding	= new AtomicInteger();
+	final AtomicBoolean	canceled	= new AtomicBoolean();
+
+	/**
+	 * Helper class to model a Job
+	 */
+	class Job implements Runnable {
+		T						target;
+		Set<T>					dependencies;
+		Runnable				runnable;
+		Throwable				exception;
+		volatile Thread			t;
+		volatile AtomicBoolean	canceled	= new AtomicBoolean(false);
+
+		/**
+		 * Run when the job's dependencies are done.
+		 */
+		public void run() {
+			Thread.interrupted(); // clear the interrupt flag
+
+			try {
+				synchronized (this) {
+					// Check if we got canceled
+					if (canceled.get())
+						return;
+
+					t = Thread.currentThread();
+				}
+				runnable.run();
+			} catch (Exception e) {
+				exception = e;
+			} finally {
+				synchronized (this) {
+					t = null;
+				}
+				Thread.interrupted(); // clear the interrupt flag
+				done(target);
+			}
+		}
+
+		/**
+		 * Cancel this job
+		 */
+		private void cancel() {
+			if (!canceled.getAndSet(true)) {
+				synchronized (this) {
+					if (t != null)
+						t.interrupt();
+				}
+			}
+		}
+	}
+
+	/**
+	 * Constructor
+	 * 
+	 * @param executor
+	 */
+	public Forker(Executor executor) {
+		this.executor = executor;
+	}
+
+	/**
+	 * Constructor
+	 * 
+	 */
+	public Forker() {
+		this.executor = Executors.newFixedThreadPool(4);
+	}
+
+	/**
+	 * Schedule a job for execution when the dependencies are done of target are
+	 * done.
+	 * 
+	 * @param dependencies the dependencies that must have run
+	 * @param target the target, is removed from all the dependencies when it ran
+	 * @param runnable the runnable to run
+	 */
+	public synchronized void doWhen(Collection<? extends T> dependencies, T target,
+			Runnable runnable) {
+		System.out.println("doWhen " + dependencies);
+		outstanding.incrementAndGet();
+		Job job = new Job();
+		job.dependencies = new HashSet<T>(dependencies);
+		job.dependencies.removeAll(done);
+		job.target = target;
+
+		job.runnable = runnable;
+		if (job.dependencies.isEmpty()) {
+			executor.execute(job);
+		} else {
+			waiting.add(job);
+		}
+	}
+
+	/**
+	 * Called when the target has ran by the Job.
+	 * 
+	 * @param done
+	 */
+	private void done(T done) {
+		List<Runnable> torun = new ArrayList<Runnable>();
+		synchronized (this) {
+			System.out.println("done " + done);
+			semaphore.release();
+
+			for (Iterator<Job> e = waiting.iterator(); e.hasNext();) {
+				Job job = e.next();
+				if (job.dependencies.remove(done) && job.dependencies.isEmpty()) {
+					System.out.println("scheduling " + job.target);
+					torun.add(job);
+					e.remove();
+				}
+			}
+		}
+		for (Runnable r : torun)
+			executor.execute(r);
+	}
+
+	/**
+	 * Wait until all jobs have run.
+	 * 
+	 * @throws InterruptedException
+	 */
+	public void join() throws InterruptedException {
+		System.out.println("join " + outstanding + " " + semaphore);
+		check();
+		semaphore.acquire(outstanding.getAndSet(0));
+	}
+
+	/**
+	 * Check that we have no jobs that can never be satisfied. I.e. if 
+	 * the dependencies contain a target that is not listed.
+	 */
+	private void check() {
+		// TODO
+	}
+
+	/**
+	 * Return the number of outstanding jobs
+	 * @return outstanding jobs
+	 */
+	public int getOutstanding() {
+		return semaphore.availablePermits();
+	}
+
+	/**
+	 * Cancel the forker.
+	 * 
+	 * @throws InterruptedException
+	 */
+	public void cancel() throws InterruptedException {
+		System.out.println("canceled " + outstanding + " " + semaphore);
+
+		if (!canceled.getAndSet(true)) {
+			for (Job job : waiting) {
+				job.cancel();
+			}
+		}
+		join();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/forker/packageinfo b/bundleplugin/src/main/java/aQute/libg/forker/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/forker/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/generics/Create.java b/bundleplugin/src/main/java/aQute/libg/generics/Create.java
new file mode 100644
index 0000000..6edc687
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/generics/Create.java
@@ -0,0 +1,42 @@
+package aQute.libg.generics;
+
+import java.util.*;
+
+public class Create {
+    
+    public static <K,V>  Map<K, V> map() {
+        return new LinkedHashMap<K,V>();
+    }
+
+    public static <T>  List<T> list() {
+        return new ArrayList<T>();
+    }
+
+    public static <T>  Set<T> set() {
+        return new HashSet<T>();
+    }
+
+    public static <T>  List<T> list(T[] source) {
+        return new ArrayList<T>(Arrays.asList(source));
+    }
+
+    public static <T>  Set<T> set(T[]source) {
+        return new HashSet<T>(Arrays.asList(source));
+    }
+
+    public static <K,V>  Map<K, V> copy(Map<K,V> source) {
+        return new LinkedHashMap<K,V>(source);
+    }
+
+    public static <T>  List<T> copy(List<T> source) {
+        return new ArrayList<T>(source);
+    }
+
+    public static <T>  Set<T> copy(Collection<T> source) {
+        if ( source == null )
+            return set();
+        return new HashSet<T>(source);
+    }
+
+    
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/generics/packageinfo b/bundleplugin/src/main/java/aQute/libg/generics/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/generics/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/header/OSGiHeader.java b/bundleplugin/src/main/java/aQute/libg/header/OSGiHeader.java
new file mode 100644
index 0000000..5632034
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/header/OSGiHeader.java
@@ -0,0 +1,145 @@
+package aQute.libg.header;
+
+import java.util.*;
+
+import aQute.libg.generics.*;
+import aQute.libg.qtokens.*;
+import aQute.libg.reporter.*;
+
+public class OSGiHeader {
+
+    static public Map<String, Map<String, String>> parseHeader(String value) {
+        return parseHeader(value, null);
+    }
+
+    /**
+     * Standard OSGi header parser. This parser can handle the format clauses
+     * ::= clause ( ',' clause ) + clause ::= name ( ';' name ) (';' key '='
+     * value )
+     * 
+     * This is mapped to a Map { name => Map { attr|directive => value } }
+     * 
+     * @param value
+     *            A string
+     * @return a Map<String,Map<String,String>>
+     */
+    static public Map<String, Map<String, String>> parseHeader(String value,
+            Reporter logger) {
+        if (value == null || value.trim().length() == 0)
+            return Create.map();
+
+        Map<String, Map<String, String>> result = Create.map();
+        QuotedTokenizer qt = new QuotedTokenizer(value, ";=,");
+        char del = 0;
+        do {
+            boolean hadAttribute = false;
+            Map<String, String> clause = Create.map();
+            List<String> aliases = Create.list();
+            String name = qt.nextToken(",;");
+
+            del = qt.getSeparator();
+            if (name == null || name.length() == 0) {
+                if (logger != null && logger.isPedantic()) {
+                    logger
+                            .warning("Empty clause, usually caused by repeating a comma without any name field or by having spaces after the backslash of a property file: "
+                                    + value);
+                }
+                if (name == null)
+                    break;
+            } else {
+                name = name.trim();
+
+                aliases.add(name);
+                while (del == ';') {
+                    String adname = qt.nextToken();
+                    if ((del = qt.getSeparator()) != '=') {
+                        if (hadAttribute)
+                            if (logger != null) {
+                                logger
+                                        .error("Header contains name field after attribute or directive: "
+                                                + adname
+                                                + " from "
+                                                + value
+                                                + ". Name fields must be consecutive, separated by a ';' like a;b;c;x=3;y=4");
+                            }
+                        if (adname != null && adname.length() > 0)
+                            aliases.add(adname.trim());
+                    } else {
+                        String advalue = qt.nextToken();
+                        if (clause.containsKey(adname)) {
+                            if (logger != null && logger.isPedantic())
+                                logger
+                                        .warning("Duplicate attribute/directive name "
+                                                + adname
+                                                + " in "
+                                                + value
+                                                + ". This attribute/directive will be ignored");
+                        }
+                        if (advalue == null) {
+                            if (logger != null)
+                                logger
+                                        .error("No value after '=' sign for attribute "
+                                                + adname);
+                            advalue = "";
+                        }
+                        clause.put(adname.trim(), advalue.trim());
+                        del = qt.getSeparator();
+                        hadAttribute = true;
+                    }
+                }
+
+                // Check for duplicate names. The aliases list contains
+                // the list of nams, for each check if it exists. If so,
+                // add a number of "~" to make it unique.
+                for (String clauseName : aliases) {
+                    if (result.containsKey(clauseName)) {
+                        if (logger != null && logger.isPedantic())
+                            logger
+                                    .warning("Duplicate name "
+                                            + clauseName
+                                            + " used in header: '"
+                                            + clauseName
+                                            + "'. Duplicate names are specially marked in Bnd with a ~ at the end (which is stripped at printing time).");
+                        while (result.containsKey(clauseName))
+                            clauseName += "~";
+                    }
+                    result.put(clauseName, clause);
+                }
+            }
+        } while (del == ',');
+        return result;
+    }
+
+    public static Map<String, String> parseProperties(String input) {
+        return parseProperties(input, null);
+    }
+
+    public static Map<String, String> parseProperties(String input, Reporter logger) {
+        if (input == null || input.trim().length() == 0)
+            return Create.map();
+
+        Map<String, String> result = Create.map();
+        QuotedTokenizer qt = new QuotedTokenizer(input, "=,");
+        char del = ',';
+
+        while (del == ',') {
+            String key = qt.nextToken(",=");
+            String value = "";
+            del = qt.getSeparator();
+            if (del == '=') {
+                value = qt.nextToken(",=");
+                del = qt.getSeparator();
+            }
+            result.put(key, value);
+        }
+        if (del != 0)
+            if ( logger == null )
+            throw new IllegalArgumentException(
+                    "Invalid syntax for properties: " + input);
+            else
+                logger.error("Invalid syntax for properties: " + input);
+
+        return result;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/header/packageinfo b/bundleplugin/src/main/java/aQute/libg/header/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/header/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/qtokens/QuotedTokenizer.java b/bundleplugin/src/main/java/aQute/libg/qtokens/QuotedTokenizer.java
new file mode 100644
index 0000000..43ef7c4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/qtokens/QuotedTokenizer.java
@@ -0,0 +1,118 @@
+package aQute.libg.qtokens;
+
+import java.util.*;
+
+import aQute.libg.generics.*;
+
+public class QuotedTokenizer {
+	String	string;
+	int		index				= 0;
+	String	separators;
+	boolean	returnTokens;
+	boolean	ignoreWhiteSpace	= true;
+	String	peek;
+	char	separator;
+
+	public QuotedTokenizer(String string, String separators, boolean returnTokens ) {
+		if ( string == null )
+			throw new IllegalArgumentException("string argument must be not null");
+		this.string = string;
+		this.separators = separators;
+		this.returnTokens = returnTokens;
+	}
+	public QuotedTokenizer(String string, String separators) {
+		this(string,separators,false);
+	}
+
+	public String nextToken(String separators) {
+		separator = 0;
+		if ( peek != null ) {
+			String tmp = peek;
+			peek = null;
+			return tmp;
+		}
+		
+		if ( index == string.length())
+			return null;
+		
+		StringBuffer sb = new StringBuffer();
+
+		while (index < string.length()) {
+			char c = string.charAt(index++);
+
+			if ( Character.isWhitespace(c)) {
+				if ( index == string.length())
+					break;
+				else {
+				    sb.append(c);
+					continue;
+				}
+			}
+			
+			if (separators.indexOf(c) >= 0) {
+				if (returnTokens)
+					peek = Character.toString(c);
+				else
+					separator = c;
+				break;
+			}
+
+			switch (c) {
+				case '"' :
+				case '\'' :
+					quotedString(sb, c);
+					break;
+
+				default :
+					sb.append(c);
+			}
+		}
+		String result = sb.toString().trim();
+		if ( result.length()==0 && index==string.length())
+			return null;
+		return result;
+	}
+
+	public String nextToken() {
+		return nextToken(separators);
+	}
+
+	private void quotedString(StringBuffer sb, char c) {
+		char quote = c;
+		while (index < string.length()) {
+			c = string.charAt(index++);
+			if (c == quote)
+				break;
+			if (c == '\\' && index < string.length()
+					&& string.charAt(index + 1) == quote)
+				c = string.charAt(index++);
+			sb.append(c);
+		}
+	}
+
+	public String[] getTokens() {
+		return getTokens(0);
+	}
+
+	private String [] getTokens(int cnt){
+		String token = nextToken();
+		if ( token == null ) 
+			return new String[cnt];
+		
+		String result[] = getTokens(cnt+1);
+		result[cnt]=token;
+		return result;
+	}
+
+	public char getSeparator() { return separator; }
+	
+	public List<String> getTokenSet() {
+		List<String> list = Create.list();
+		String token = nextToken();
+		while ( token != null ) {
+			list.add(token);
+			token = nextToken();
+		}
+		return list;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/qtokens/packageinfo b/bundleplugin/src/main/java/aQute/libg/qtokens/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/qtokens/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/reporter/Reporter.java b/bundleplugin/src/main/java/aQute/libg/reporter/Reporter.java
new file mode 100644
index 0000000..c6179af
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/reporter/Reporter.java
@@ -0,0 +1,15 @@
+package aQute.libg.reporter;
+
+import java.util.*;
+
+
+public interface Reporter {
+	void error(String s, Object ... args);
+	void warning(String s, Object ... args);
+	void progress(String s, Object ... args);
+	void trace(String s, Object ... args);
+	List<String> getWarnings();
+	List<String> getErrors();
+	
+	boolean isPedantic();
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/reporter/packageinfo b/bundleplugin/src/main/java/aQute/libg/reporter/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/reporter/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/sax/ContentFilter.java b/bundleplugin/src/main/java/aQute/libg/sax/ContentFilter.java
new file mode 100644
index 0000000..62ca259
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sax/ContentFilter.java
@@ -0,0 +1,8 @@
+package aQute.libg.sax;
+
+import org.xml.sax.ContentHandler;
+
+public interface ContentFilter extends ContentHandler {
+	void setParent(ContentHandler parent);
+	ContentHandler getParent();
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/sax/ContentFilterImpl.java b/bundleplugin/src/main/java/aQute/libg/sax/ContentFilterImpl.java
new file mode 100644
index 0000000..7f71568
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sax/ContentFilterImpl.java
@@ -0,0 +1,71 @@
+package aQute.libg.sax;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+public class ContentFilterImpl implements ContentFilter {
+
+	private ContentHandler parent;
+
+	public void setParent(ContentHandler parent) {
+		this.parent = parent;
+		
+	}
+
+	public ContentHandler getParent() {
+		return parent;
+	}
+
+	public void setDocumentLocator(Locator locator) {
+		parent.setDocumentLocator(locator);
+	}
+
+	public void startDocument() throws SAXException {
+		parent.startDocument();
+	}
+
+	public void endDocument() throws SAXException {
+		parent.endDocument();
+	}
+
+	public void startPrefixMapping(String prefix, String uri)
+			throws SAXException {
+		parent.startPrefixMapping(prefix, uri);
+	}
+
+	public void endPrefixMapping(String prefix) throws SAXException {
+		parent.endPrefixMapping(prefix);
+	}
+
+	public void startElement(String uri, String localName, String qName,
+			Attributes atts) throws SAXException {
+		parent.startElement(uri, localName, qName, atts);
+	}
+
+	public void endElement(String uri, String localName, String qName)
+			throws SAXException {
+		parent.endElement(uri, localName, qName);
+	}
+
+	public void characters(char[] ch, int start, int length)
+			throws SAXException {
+		parent.characters(ch, start, length);
+	}
+
+	public void ignorableWhitespace(char[] ch, int start, int length)
+			throws SAXException {
+		parent.ignorableWhitespace(ch, start, length);
+	}
+
+	public void processingInstruction(String target, String data)
+			throws SAXException {
+		parent.processingInstruction(target, data);
+	}
+
+	public void skippedEntity(String name) throws SAXException {
+		parent.skippedEntity(name);
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/sax/SAXElement.java b/bundleplugin/src/main/java/aQute/libg/sax/SAXElement.java
new file mode 100644
index 0000000..b7ce35e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sax/SAXElement.java
@@ -0,0 +1,36 @@
+package aQute.libg.sax;
+
+import org.xml.sax.Attributes;
+
+public class SAXElement {
+
+	private final String uri;
+	private final String localName;
+	private final String qName;
+	private final Attributes atts;
+
+	public SAXElement(String uri, String localName, String qName,
+			Attributes atts) {
+		this.uri = uri;
+		this.localName = localName;
+		this.qName = qName;
+		this.atts = atts;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public String getLocalName() {
+		return localName;
+	}
+
+	public String getqName() {
+		return qName;
+	}
+
+	public Attributes getAtts() {
+		return atts;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/sax/SAXUtil.java b/bundleplugin/src/main/java/aQute/libg/sax/SAXUtil.java
new file mode 100644
index 0000000..87b058e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sax/SAXUtil.java
@@ -0,0 +1,29 @@
+package aQute.libg.sax;
+
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Result;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.XMLReader;
+
+public class SAXUtil {
+	
+	public static XMLReader buildPipeline(Result output, ContentFilter... filters) throws Exception {
+		SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
+		TransformerHandler handler = factory.newTransformerHandler();
+		handler.setResult(output);
+		
+		ContentHandler last = handler;
+		if (filters != null) for (ContentFilter filter : filters) {
+			filter.setParent(last);
+			last = filter;
+		}
+		XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
+		reader.setContentHandler(last);
+		
+		return reader;
+	}
+	
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/sax/filters/ElementSelectionFilter.java b/bundleplugin/src/main/java/aQute/libg/sax/filters/ElementSelectionFilter.java
new file mode 100644
index 0000000..4411db9
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sax/filters/ElementSelectionFilter.java
@@ -0,0 +1,49 @@
+package aQute.libg.sax.filters;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import aQute.libg.sax.ContentFilterImpl;
+
+public abstract class ElementSelectionFilter extends ContentFilterImpl{
+	
+	int depth = 0;
+	int hiddenDepth = -1;
+	
+	protected abstract boolean select(int depth, String uri, String localName, String qName, Attributes attribs);
+	
+	@Override
+	public final void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+		if (hiddenDepth < 0) {
+			boolean allow = select(depth, uri, localName, qName, atts);
+			if (allow)
+				super.startElement(uri, localName, qName, atts);
+			else
+				hiddenDepth = 0;
+		} else {
+			hiddenDepth ++;
+		}
+		depth++;
+	}
+	
+	@Override
+	public final void endElement(String uri, String localName, String qName) throws SAXException {
+		if (hiddenDepth < 0) {
+			super.endElement(uri, localName, qName);
+		} else {
+			hiddenDepth --;
+		}
+		depth --;
+	}
+	
+	@Override
+	public void characters(char[] ch, int start, int length) throws SAXException {
+		if (hiddenDepth < 0) super.characters(ch, start, length);
+	}
+	
+	@Override
+	public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+		if (hiddenDepth < 0) super.ignorableWhitespace(ch, start, length);
+	}
+	
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/sax/filters/MergeContentFilter.java b/bundleplugin/src/main/java/aQute/libg/sax/filters/MergeContentFilter.java
new file mode 100644
index 0000000..acf5d12
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sax/filters/MergeContentFilter.java
@@ -0,0 +1,57 @@
+package aQute.libg.sax.filters;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
+import aQute.libg.sax.ContentFilterImpl;
+import aQute.libg.sax.SAXElement;
+
+public class MergeContentFilter extends ContentFilterImpl {
+
+	private int elementDepth = 0;
+	
+	private final List<SAXElement> rootElements = new LinkedList<SAXElement>();
+	
+	@Override
+	public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+		if (elementDepth++ == 0) {
+			if (rootElements.isEmpty())
+				super.startElement(uri, localName, qName, atts);
+			else if (!rootElements.get(0).getqName().equals(qName))
+				throw new SAXException(String.format("Documents have inconsistent root element names: first was %s, current is %s.", rootElements.get(0).getqName(), qName));
+			rootElements.add(new SAXElement(uri, localName, qName, atts));
+		} else {
+			super.startElement(uri, localName, qName, atts);
+		}
+	}
+
+	@Override
+	public void endElement(String uri, String localName, String qName) throws SAXException {
+		if (--elementDepth > 0) {
+			super.endElement(uri, localName, qName);
+		}
+	}
+	
+	@Override
+	public void processingInstruction(String target, String data) throws SAXException {
+		if (rootElements.isEmpty())
+			super.processingInstruction(target, data);
+	}
+	
+	public void closeRootAndDocument() throws SAXException {
+		if (!rootElements.isEmpty()) {
+			SAXElement root = rootElements.get(0);
+			super.endElement(root.getUri(), root.getLocalName(), root.getqName());
+		}
+		super.endDocument();
+	}
+	
+	public List<SAXElement> getRootElements() {
+		return Collections.unmodifiableList(rootElements);
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/sax/filters/packageinfo b/bundleplugin/src/main/java/aQute/libg/sax/filters/packageinfo
new file mode 100644
index 0000000..a4f1546
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sax/filters/packageinfo
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/sax/packageinfo b/bundleplugin/src/main/java/aQute/libg/sax/packageinfo
new file mode 100644
index 0000000..a4f1546
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sax/packageinfo
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/sed/Replacer.java b/bundleplugin/src/main/java/aQute/libg/sed/Replacer.java
new file mode 100644
index 0000000..fa181f4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sed/Replacer.java
@@ -0,0 +1,5 @@
+package aQute.libg.sed;
+
+public interface Replacer {
+    String process(String line);
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/sed/Sed.java b/bundleplugin/src/main/java/aQute/libg/sed/Sed.java
new file mode 100644
index 0000000..86971bb
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sed/Sed.java
@@ -0,0 +1,82 @@
+package aQute.libg.sed;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+public class Sed {
+    final File                 file;
+    final Replacer             macro;
+    File                       output;
+
+    final Map<Pattern, String> replacements = new LinkedHashMap<Pattern, String>();
+
+    public Sed(Replacer macro, File file) {
+        assert file.isFile();
+        this.file = file;
+        this.macro = macro;
+    }
+
+    public void setOutput(File f) {
+        output = f;
+    }
+
+    public void replace(String pattern, String replacement) {
+        replacements.put(Pattern.compile(pattern), replacement);
+    }
+
+    public void doIt() throws IOException {
+        BufferedReader brdr = new BufferedReader(new FileReader(file));
+        File out;
+        if (output != null)
+            out = output;
+        else
+            out = new File(file.getAbsolutePath() + ".tmp");
+        File bak = new File(file.getAbsolutePath() + ".bak");
+        PrintWriter pw = new PrintWriter(new FileWriter(out));
+        try {
+            String line;
+            while ((line = brdr.readLine()) != null) {
+                for (Pattern p : replacements.keySet()) {
+                    String replace = replacements.get(p);
+                    Matcher m = p.matcher(line);
+
+                    StringBuffer sb = new StringBuffer();
+                    while (m.find()) {
+                        String tmp = setReferences(m, replace);
+                        tmp = macro.process(tmp);
+                        m.appendReplacement(sb, Matcher.quoteReplacement(tmp));
+                    }
+                    m.appendTail(sb);
+
+                    line = sb.toString();
+                }
+                pw.println(line);
+            }
+            pw.close();
+            if (output == null) {
+                file.renameTo(bak);
+                out.renameTo(file);
+            }
+        } finally {
+            brdr.close();
+            pw.close();
+        }
+    }
+
+    private String setReferences(Matcher m, String replace) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < replace.length(); i++) {
+            char c = replace.charAt(i);
+            if (c == '$' && i < replace.length() - 1
+                    && Character.isDigit(replace.charAt(i + 1))) {
+                int n = replace.charAt(i + 1) - '0';
+                if ( n <= m.groupCount() )
+                    sb.append(m.group(n));
+                i++;
+            } else
+                sb.append(c);
+        }
+        return sb.toString();
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/sed/packageinfo b/bundleplugin/src/main/java/aQute/libg/sed/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sed/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/tarjan/Tarjan.java b/bundleplugin/src/main/java/aQute/libg/tarjan/Tarjan.java
new file mode 100644
index 0000000..063006e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/tarjan/Tarjan.java
@@ -0,0 +1,108 @@
+package aQute.libg.tarjan;
+
+import static java.lang.Math.*;
+
+import java.util.*;
+
+public class Tarjan<T> {
+
+	public class Node {
+		final T				name;
+		final List<Node>	adjacent	= new ArrayList<Node>();
+		int					low			= -1;
+		int					index		= -1;
+
+		public Node(T name) {
+			this.name = name;
+		}
+		
+		public String toString() {
+			return name + "{" + index + "," + low + "}";
+		}
+	}
+
+	private int				index	= 0;
+	private List<Node>		stack	= new ArrayList<Node>();
+	private Set<Set<T>>	scc		= new HashSet<Set<T>>();
+	private Node			root	= new Node(null);
+
+	
+//	   public ArrayList<ArrayList<Node>> tarjan(Node v, AdjacencyList list){
+//	       v.index = index;
+//	       v.lowlink = index;
+//	       index++;
+//	       stack.add(0, v);
+//	       for(Edge e : list.getAdjacent(v)){
+//	           Node n = e.to;
+//	           if(n.index == -1){
+//	               tarjan(n, list);
+//	               v.lowlink = Math.min(v.lowlink, n.lowlink);
+//	           }else if(stack.contains(n)){
+//	               v.lowlink = Math.min(v.lowlink, n.index);
+//	           }
+//	       }
+//	       if(v.lowlink == v.index){
+//	           Node n;
+//	           ArrayList<Node> component = new ArrayList<Node>();
+//	           do{
+//	               n = stack.remove(0);
+//	               component.add(n);
+//	           }while(n != v);
+//	           SCC.add(component);
+//	       }
+//	       return SCC;
+//	   }
+
+	void tarjan(Node v) {
+		v.index = index;
+		v.low = index;
+		index++;
+		stack.add(0, v);
+		for (Node n : v.adjacent) {
+			if (n.index == -1) {
+				// first time visit
+				tarjan(n);
+				v.low = min(v.low, n.low);
+			} else if (stack.contains(n)) {
+				v.low = min(v.low, n.index);
+			}
+		}
+
+		if (v!=root && v.low == v.index) {
+			Set<T> component = new HashSet<T>();
+			Node n;
+			do {
+				n = stack.remove(0);
+				component.add(n.name);
+			} while (n != v);
+			scc.add(component);
+		}
+	}
+
+	Set<Set<T>> getResult(Map<T, ? extends Collection<T>> graph) {
+		Map<T, Node> index = new HashMap<T, Node>();
+
+		for (Map.Entry<T, ? extends Collection<T>> entry : graph.entrySet()) {
+			Node node = getNode(index, entry.getKey());
+			root.adjacent.add(node);
+			for (T adj : entry.getValue())
+				node.adjacent.add(getNode(index, adj));
+		}
+		tarjan(root);
+		return scc;
+	}
+
+	private Node getNode(Map<T, Node> index, T key) {
+		Node node = index.get(key);
+		if (node == null) {
+			node = new Node(key);
+			index.put(key, node);
+		}
+		return node;
+	}
+
+	public static <T> Set<Set<T>> tarjan(Map<T, Set<T>> graph) {
+		Tarjan<T> tarjan = new Tarjan<T>();
+		return tarjan.getResult(graph);
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/tarjan/packageinfo b/bundleplugin/src/main/java/aQute/libg/tarjan/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/tarjan/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/tuple/Pair.java b/bundleplugin/src/main/java/aQute/libg/tuple/Pair.java
new file mode 100644
index 0000000..efb2298
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/tuple/Pair.java
@@ -0,0 +1,11 @@
+package aQute.libg.tuple;
+
+public class Pair<A,B> {
+	final public A a;
+	final public B b;
+	
+	public Pair(A a, B b) {
+		this.a = a;
+		this.b = b;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/tuple/packageinfo b/bundleplugin/src/main/java/aQute/libg/tuple/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/tuple/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/version/Version.java b/bundleplugin/src/main/java/aQute/libg/version/Version.java
new file mode 100644
index 0000000..4f087a0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/version/Version.java
@@ -0,0 +1,148 @@
+package aQute.libg.version;
+
+import java.util.regex.*;
+
+public class Version implements Comparable<Version> {
+    final int                   major;
+    final int                   minor;
+    final int                   micro;
+    final String                qualifier;
+    public final static String  VERSION_STRING = "(\\d+)(\\.(\\d+)(\\.(\\d+)(\\.([-_\\da-zA-Z]+))?)?)?";
+    public final static Pattern VERSION        = Pattern
+                                                       .compile(VERSION_STRING);
+    public final static Version LOWEST         = new Version();
+    public final static Version HIGHEST        = new Version(Integer.MAX_VALUE,
+                                                       Integer.MAX_VALUE,
+                                                       Integer.MAX_VALUE,
+                                                       "\uFFFF");
+
+    public Version() {
+        this(0);
+    }
+
+    public Version(int major, int minor, int micro, String qualifier) {
+        this.major = major;
+        this.minor = minor;
+        this.micro = micro;
+        this.qualifier = qualifier;
+    }
+
+    public Version(int major, int minor, int micro) {
+        this(major, minor, micro, null);
+    }
+
+    public Version(int major, int minor) {
+        this(major, minor, 0, null);
+    }
+
+    public Version(int major) {
+        this(major, 0, 0, null);
+    }
+
+    public Version(String version) {
+        Matcher m = VERSION.matcher(version);
+        if (!m.matches())
+            throw new IllegalArgumentException("Invalid syntax for version: "
+                    + version);
+
+        major = Integer.parseInt(m.group(1));
+        if (m.group(3) != null)
+            minor = Integer.parseInt(m.group(3));
+        else
+            minor = 0;
+
+        if (m.group(5) != null)
+            micro = Integer.parseInt(m.group(5));
+        else
+            micro = 0;
+
+        qualifier = m.group(7);
+    }
+
+    public int getMajor() {
+        return major;
+    }
+
+    public int getMinor() {
+        return minor;
+    }
+
+    public int getMicro() {
+        return micro;
+    }
+
+    public String getQualifier() {
+        return qualifier;
+    }
+
+    public int compareTo(Version other) {
+        if (other == this)
+            return 0;
+
+        if (!(other instanceof Version))
+            throw new IllegalArgumentException(
+                    "Can only compare versions to versions");
+
+        Version o = (Version) other;
+        if (major != o.major)
+            return major - o.major;
+
+        if (minor != o.minor)
+            return minor - o.minor;
+
+        if (micro != o.micro)
+            return micro - o.micro;
+
+        int c = 0;
+        if (qualifier != null)
+            c = 1;
+        if (o.qualifier != null)
+            c += 2;
+
+        switch (c) {
+        case 0:
+            return 0;
+        case 1:
+            return 1;
+        case 2:
+            return -1;
+        }
+        return qualifier.compareTo(o.qualifier);
+    }
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(major);
+        sb.append(".");
+        sb.append(minor);
+        sb.append(".");
+        sb.append(micro);
+        if (qualifier != null) {
+            sb.append(".");
+            sb.append(qualifier);
+        }
+        return sb.toString();
+    }
+
+    public boolean equals(Object ot) {
+        if ( ! (ot instanceof Version))
+            return false;
+        
+        return compareTo((Version)ot) == 0;
+    }
+
+    public int hashCode() {
+        return major * 97 ^ minor * 13 ^ micro
+                + (qualifier == null ? 97 : qualifier.hashCode());
+    }
+
+    public int get(int i) {
+        switch(i) {
+        case 0 : return major;
+        case 1 : return minor;
+        case 2 : return micro;
+        default:
+            throw new IllegalArgumentException("Version can only get 0 (major), 1 (minor), or 2 (micro)");
+        }
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/version/VersionRange.java b/bundleplugin/src/main/java/aQute/libg/version/VersionRange.java
new file mode 100644
index 0000000..47e7447
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/version/VersionRange.java
@@ -0,0 +1,85 @@
+package aQute.libg.version;
+
+import java.util.regex.*;
+
+public class VersionRange {
+	Version			high;
+	Version			low;
+	char			start	= '[';
+	char			end		= ']';
+
+	static Pattern	RANGE	= Pattern.compile("(\\(|\\[)\\s*(" +
+									Version.VERSION_STRING + ")\\s*,\\s*(" +
+									Version.VERSION_STRING + ")\\s*(\\)|\\])");
+
+	public VersionRange(String string) {
+		string = string.trim();
+		Matcher m = RANGE.matcher(string);
+		if (m.matches()) {
+			start = m.group(1).charAt(0);
+			String v1 = m.group(2);
+			String v2 = m.group(10);
+			low = new Version(v1);
+			high = new Version(v2);
+			end = m.group(18).charAt(0);
+			if (low.compareTo(high) > 0)
+				throw new IllegalArgumentException(
+						"Low Range is higher than High Range: " + low + "-" +
+								high);
+
+		} else
+			high = low = new Version(string);
+	}
+
+	public boolean isRange() {
+		return high != low;
+	}
+
+	public boolean includeLow() {
+		return start == '[';
+	}
+
+	public boolean includeHigh() {
+		return end == ']';
+	}
+
+	public String toString() {
+		if (high == low)
+			return high.toString();
+
+		StringBuffer sb = new StringBuffer();
+		sb.append(start);
+		sb.append(low);
+		sb.append(',');
+		sb.append(high);
+		sb.append(end);
+		return sb.toString();
+	}
+
+	public Version getLow() {
+		return low;
+	}
+
+	public Version getHigh() {
+		return high;
+	}
+
+	public boolean includes(Version v) {
+		if ( !isRange() ) {
+			return low.compareTo(v) <=0;
+		}
+		if (includeLow()) {
+			if (v.compareTo(low) < 0)
+				return false;
+		} else if (v.compareTo(low) <= 0)
+			return false;
+
+		if (includeHigh()) {
+			if (v.compareTo(high) > 0)
+				return false;
+		} else if (v.compareTo(high) >= 0)
+			return false;
+		
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/version/packageinfo b/bundleplugin/src/main/java/aQute/libg/version/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/version/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
index 7fde234..69d0fab 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
@@ -699,7 +699,7 @@
                         options.put( "resolution:", "optional" );
                     }
                 }
-                String result = Processor.printClauses( values, "resolution:" );
+                String result = Processor.printClauses( values );
                 bundleManifest.getMainAttributes().putValue( "Import-Package", result );
             }
 
diff --git a/bundleplugin/src/main/java/org/osgi/service/bindex/BundleIndexer.java b/bundleplugin/src/main/java/org/osgi/service/bindex/BundleIndexer.java
new file mode 100644
index 0000000..01772ac
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/bindex/BundleIndexer.java
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ * 
+ * Copyright (c) OSGi Alliance (2002, 2006, 2007). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.bindex;
+
+import java.util.Set;
+import java.util.Map;
+import java.io.File;
+import java.io.OutputStream;
+
+/**
+ * The BundleIndexer is an OSGi service for indexing bundle capabiilities 
+ * and requirements and create an OBR XML representation.
+ * 
+ * @version $Revision$
+ */
+public interface BundleIndexer {
+  static final String REPOSITORY_NAME = "repository.name";
+  static final String STYLESHEET = "stylesheet";
+  static final String URL_TEMPLATE = "url.template";
+  static final String ROOT_URL = "root.url";
+  static final String LICENSE_URL = "license.url";
+
+  /**
+   * Index the input files and write the result to the given OutputStream
+   * @param jarFiles a set of input jar files or directories
+   * @param out the OutputStream to write to
+   * @param config a set of optional parameters (use constants of this interface as keys)
+   */
+  void index(Set<File> jarFiles, OutputStream out, Map<String, String> config) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/org/osgi/service/bindex/packageinfo b/bundleplugin/src/main/java/org/osgi/service/bindex/packageinfo
new file mode 100644
index 0000000..a4f1546
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/bindex/packageinfo
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/org/osgi/service/component/annotations/Activate.java b/bundleplugin/src/main/java/org/osgi/service/component/annotations/Activate.java
new file mode 100644
index 0000000..b61a8ae
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/component/annotations/Activate.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.component.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Identify the annotated method as the {@code activate} method of a Service
+ * Component.
+ * 
+ * <p>
+ * The annotated method is the activate method of the Component.
+ * 
+ * <p>
+ * This annotation is not processed at runtime by a Service Component Runtime
+ * implementation. It must be processed by tools and used to add a Component
+ * Description to the bundle.
+ * 
+ * @see "The activate attribute of the component element of a Component Description."
+ * @version $Id$
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Activate {
+	// marker annotation
+}
diff --git a/bundleplugin/src/main/java/org/osgi/service/component/annotations/Component.java b/bundleplugin/src/main/java/org/osgi/service/component/annotations/Component.java
new file mode 100644
index 0000000..6d6332d
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/component/annotations/Component.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.component.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Identify the annotated class as a Service Component.
+ * 
+ * <p>
+ * The annotated class is the implementation class of the Component.
+ * 
+ * <p>
+ * This annotation is not processed at runtime by a Service Component Runtime
+ * implementation. It must be processed by tools and used to add a Component
+ * Description to the bundle.
+ * 
+ * @see "The component element of a Component Description."
+ * @version $Id$
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+public @interface Component {
+	/**
+	 * The name of this Component.
+	 * 
+	 * <p>
+	 * If not specified, the name of this Component is the fully qualified type
+	 * name of the class being annotated.
+	 * 
+	 * @see "The name attribute of the component element of a Component Description."
+	 */
+	String name() default "";
+
+	/**
+	 * The types under which to register this Component as a service.
+	 * 
+	 * <p>
+	 * If no service should be registered, the empty value
+	 * <code>&#x7B;&#x7D;</code> must be specified.
+	 * 
+	 * <p>
+	 * If not specified, the service types for this Component are all the
+	 * <i>directly</i> implemented interfaces of the class being annotated.
+	 * 
+	 * @see "The service element of a Component Description."
+	 */
+	Class< ? >[] service() default {};
+
+	/**
+	 * The factory identifier of this Component. Specifying a factory identifier
+	 * makes this Component a Factory Component.
+	 * 
+	 * <p>
+	 * If not specified, the default is that this Component is not a Factory
+	 * Component.
+	 * 
+	 * @see "The factory attribute of the component element of a Component Description."
+	 */
+	String factory() default "";
+
+	/**
+	 * Declares whether this Component uses the OSGi ServiceFactory concept and
+	 * each bundle using this Component's service will receive a different
+	 * component instance.
+	 * 
+	 * <p>
+	 * If {@code true}, this Component uses the OSGi ServiceFactory concept. If
+	 * {@code false} or not specified, this Component does not use the OSGi
+	 * ServiceFactory concept.
+	 * 
+	 * @see "The servicefactory attribute of the service element of a Component Description."
+	 */
+	boolean servicefactory() default false;
+
+	/**
+	 * Declares whether this Component is enabled when the bundle containing it
+	 * is started.
+	 * 
+	 * <p>
+	 * If {@code true}, this Component is enabled. If {@code false} or not
+	 * specified, this Component is disabled.
+	 * 
+	 * @see "The enabled attribute of the component element of a Component Description."
+	 */
+	boolean enabled() default true;
+
+	/**
+	 * Declares whether this Component must be immediately activated upon
+	 * becoming satisfied or whether activation should be delayed.
+	 * 
+	 * <p>
+	 * If {@code true}, this Component must be immediately activated upon
+	 * becoming satisfied. If {@code false}, activation of this Component is
+	 * delayed. If this property is specified, its value must be {@code false}
+	 * if the {@link #factory} property is also specified or must be
+	 * {@code true} if the {@link #service} property is specified with an empty
+	 * value.
+	 * 
+	 * <p>
+	 * If not specified, the default is {@code false} if the {@link #factory}
+	 * property is specified or the {@link #service} property is not specified
+	 * or specified with a non-empty value and {@code true} otherwise.
+	 * 
+	 * @see "The immediate attribute of the component element of a Component Description."
+	 */
+	boolean immediate() default false;
+
+	/**
+	 * The configuration policy of this Component.
+	 * 
+	 * <p>
+	 * Controls whether component configurations must be satisfied depending on
+	 * the presence of a corresponding Configuration object in the OSGi
+	 * Configuration Admin service. A corresponding configuration is a
+	 * Configuration object where the PID equals the name of the component.
+	 * 
+	 * <p>
+	 * If not specified, the {@link ConfigurationPolicy#OPTIONAL OPTIONAL}
+	 * configuration policy is used.
+	 * 
+	 * @see "The configuration-policy attribute of the component element of a Component Description."
+	 */
+	ConfigurationPolicy configurationPolicy() default ConfigurationPolicy.OPTIONAL;
+
+	/**
+	 * Properties for this Component.
+	 * 
+	 * <p>
+	 * Each property string is specified as {@code "key=value"}. The type of the
+	 * property value can be specified in the key as {@code key:type=value}. The
+	 * type must be one of the property types supported by the type attribute of
+	 * the property element of a Component Description.
+	 * 
+	 * <p>
+	 * To specify a property with multiple values, use multiple key, value
+	 * pairs. For example, {@code "foo=bar", "foo=baz"}.
+	 * 
+	 * @see "The property element of a Component Description."
+	 */
+	String[] property() default {};
+
+	/**
+	 * Property entries for this Component.
+	 * 
+	 * <p>
+	 * Specifies the name of an entry in the bundle whose contents conform to a
+	 * standard Java Properties File. The entry is read and processed to obtain
+	 * the properties and their values.
+	 * 
+	 * @see "The properties element of a Component Description."
+	 */
+	String[] properties() default {};
+}
diff --git a/bundleplugin/src/main/java/org/osgi/service/component/annotations/ConfigurationPolicy.java b/bundleplugin/src/main/java/org/osgi/service/component/annotations/ConfigurationPolicy.java
new file mode 100644
index 0000000..333d73c
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/component/annotations/ConfigurationPolicy.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.component.annotations;
+
+/**
+ * Configuration Policy for the {@link Component} annotation.
+ * 
+ * <p>
+ * Controls whether component configurations must be satisfied depending on the
+ * presence of a corresponding Configuration object in the OSGi Configuration
+ * Admin service. A corresponding configuration is a Configuration object where
+ * the PID is the name of the component.
+ * 
+ * @version $Id$
+ */
+public enum ConfigurationPolicy {
+	/**
+	 * Use the corresponding Configuration object if present but allow the
+	 * component to be satisfied even if the corresponding Configuration object
+	 * is not present.
+	 */
+	OPTIONAL,
+	/**
+	 * There must be a corresponding Configuration object for the component
+	 * configuration to become satisfied.
+	 */
+	REQUIRE,
+	/**
+	 * Always allow the component configuration to be satisfied and do not use
+	 * the corresponding Configuration object even if it is present.
+	 */
+	IGNORE;
+}
diff --git a/bundleplugin/src/main/java/org/osgi/service/component/annotations/Deactivate.java b/bundleplugin/src/main/java/org/osgi/service/component/annotations/Deactivate.java
new file mode 100644
index 0000000..397f319
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/component/annotations/Deactivate.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.component.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Identify the annotated method as the {@code deactivate} method of a Service
+ * Component.
+ * 
+ * <p>
+ * The annotated method is the deactivate method of the Component.
+ * 
+ * <p>
+ * This annotation is not processed at runtime by a Service Component Runtime
+ * implementation. It must be processed by tools and used to add a Component
+ * Description to the bundle.
+ * 
+ * @see "The deactivate attribute of the component element of a Component Description."
+ * @version $Id$
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Deactivate {
+	// marker annotation
+}
diff --git a/bundleplugin/src/main/java/org/osgi/service/component/annotations/Modified.java b/bundleplugin/src/main/java/org/osgi/service/component/annotations/Modified.java
new file mode 100644
index 0000000..2a93eb9
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/component/annotations/Modified.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.component.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Identify the annotated method as the {@code modified} method of a Service
+ * Component.
+ * 
+ * <p>
+ * The annotated method is the modified method of the Component.
+ * 
+ * <p>
+ * This annotation is not processed at runtime by a Service Component Runtime
+ * implementation. It must be processed by tools and used to add a Component
+ * Description to the bundle.
+ * 
+ * @see "The modified attribute of the component element of a Component Description."
+ * @version $Id$
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Modified {
+	// marker annotation
+}
diff --git a/bundleplugin/src/main/java/org/osgi/service/component/annotations/Reference.java b/bundleplugin/src/main/java/org/osgi/service/component/annotations/Reference.java
new file mode 100644
index 0000000..4fffce5
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/component/annotations/Reference.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.component.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Identify the annotated method as a {@code bind} method of a Service
+ * Component.
+ * 
+ * <p>
+ * The annotated method is a bind method of the Component.
+ * 
+ * <p>
+ * This annotation is not processed at runtime by a Service Component Runtime
+ * implementation. It must be processed by tools and used to add a Component
+ * Description to the bundle.
+ * 
+ * @see "The reference element of a Component Description."
+ * @version $Id$
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.METHOD)
+public @interface Reference {
+	/**
+	 * The name of this reference.
+	 * 
+	 * <p>
+	 * If not specified, the name of this reference is based upon the name of
+	 * the method being annotated. If the method name begins with {@code set} or
+	 * {@code add}, that is removed.
+	 * 
+	 * @see "The name attribute of the reference element of a Component Description."
+	 */
+	String name() default "";
+
+	/**
+	 * The type of the service to bind to this reference.
+	 * 
+	 * <p>
+	 * If not specified, the type of the service to bind is based upon the type
+	 * of the first argument of the method being annotated.
+	 * 
+	 * @see "The interface attribute of the reference element of a Component Description."
+	 */
+	Class< ? > service() default Object.class;
+
+	/**
+	 * The cardinality of the reference.
+	 * 
+	 * <p>
+	 * If not specified, the reference has a
+	 * {@link ReferenceCardinality#MANDATORY 1..1} cardinality.
+	 * 
+	 * @see "The cardinality attribute of the reference element of a Component Description."
+	 */
+	ReferenceCardinality cardinality() default ReferenceCardinality.MANDATORY;
+
+	/**
+	 * The policy for the reference.
+	 * 
+	 * <p>
+	 * If not specified, the {@link ReferencePolicy#STATIC STATIC} reference
+	 * policy is used.
+	 * 
+	 * @see "The policy attribute of the reference element of a Component Description."
+	 */
+	ReferencePolicy policy() default ReferencePolicy.STATIC;
+
+	/**
+	 * The target filter for the reference.
+	 * 
+	 * @see "The target attribute of the reference element of a Component Description."
+	 */
+	String target() default "";
+
+	/**
+	 * The name of the unbind method which pairs with the annotated bind method.
+	 * 
+	 * <p>
+	 * To declare no unbind method, the value {@code "-"} must be used.
+	 * 
+	 * <p>
+	 * If not specified, the name of the unbind method is derived from the name
+	 * of the annotated bind method. If the annotated method name begins with
+	 * {@code set}, that is replaced with {@code unset} to derive the unbind
+	 * method name. If the annotated method name begins with {@code add}, that
+	 * is replaced with {@code remove} to derive the unbind method name.
+	 * Otherwise, {@code un} is prefixed to the annotated method name to derive
+	 * the unbind method name.
+	 * 
+	 * @see "The unbind attribute of the reference element of a Component Description."
+	 */
+	String unbind() default "";
+}
diff --git a/bundleplugin/src/main/java/org/osgi/service/component/annotations/ReferenceCardinality.java b/bundleplugin/src/main/java/org/osgi/service/component/annotations/ReferenceCardinality.java
new file mode 100644
index 0000000..a86f2f2
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/component/annotations/ReferenceCardinality.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.component.annotations;
+
+/**
+ * Cardinality for the {@link Reference} annotation.
+ * 
+ * <p>
+ * Specifies if the reference is optional and if the component implementation
+ * support a single bound service or multiple bound services.
+ * 
+ * @version $Id$
+ */
+public enum ReferenceCardinality {
+	/**
+	 * The reference is optional and unary. That is, the reference has a
+	 * cardinality of {@code 0..1}.
+	 */
+	OPTIONAL, // 0..1
+	/**
+	 * The reference is mandatory and unary. That is, the reference has a
+	 * cardinality of {@code 1..1}.
+	 */
+	MANDATORY, // 1..1
+	/**
+	 * The reference is optional and multiple. That is, the reference has a
+	 * cardinality of {@code 0..n}.
+	 */
+	MULTIPLE, // 0..n
+	/**
+	 * The reference is mandatory and multiple. That is, the reference has a
+	 * cardinality of {@code 1..n}.
+	 */
+	AT_LEAST_ONE; // 1..n
+}
diff --git a/bundleplugin/src/main/java/org/osgi/service/component/annotations/ReferencePolicy.java b/bundleplugin/src/main/java/org/osgi/service/component/annotations/ReferencePolicy.java
new file mode 100644
index 0000000..698f862
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/component/annotations/ReferencePolicy.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.service.component.annotations;
+
+/**
+ * Policy for the {@link Reference} annotation.
+ * 
+ * @version $Id$
+ */
+public enum ReferencePolicy {
+	/**
+	 * The static policy is the most simple policy and is the default policy. A
+	 * component instance never sees any of the dynamics. Component
+	 * configurations are deactivated before any bound service for a reference
+	 * having a static policy becomes unavailable. If a target service is
+	 * available to replace the bound service which became unavailable, the
+	 * component configuration must be reactivated and bound to the replacement
+	 * service.
+	 */
+	STATIC,
+	/**
+	 * The dynamic policy is slightly more complex since the component
+	 * implementation must properly handle changes in the set of bound services.
+	 * With the dynamic policy, SCR can change the set of bound services without
+	 * deactivating a component configuration. If the component uses the event
+	 * strategy to access services, then the component instance will be notified
+	 * of changes in the set of bound services by calls to the bind and unbind
+	 * methods.
+	 */
+	DYNAMIC;
+}
diff --git a/bundleplugin/src/main/java/org/osgi/service/component/annotations/package-info.java b/bundleplugin/src/main/java/org/osgi/service/component/annotations/package-info.java
new file mode 100644
index 0000000..2d28d03
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/component/annotations/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Service Component Annotations Package Version 1.0.
+ * 
+ * <p>
+ * This package is not used at runtime. Annotated classes are processed by
+ * tools to generate Component Descriptions which are used at runtime.
+ * 
+ * @version $Id$
+ */
+
+package org.osgi.service.component.annotations;
+
diff --git a/bundleplugin/src/main/java/org/osgi/service/component/annotations/packageinfo b/bundleplugin/src/main/java/org/osgi/service/component/annotations/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/org/osgi/service/component/annotations/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/resources/aQute/bnd/help/changed.txt b/bundleplugin/src/main/resources/aQute/bnd/help/changed.txt
new file mode 100644
index 0000000..14d0bd2
--- /dev/null
+++ b/bundleplugin/src/main/resources/aQute/bnd/help/changed.txt
@@ -0,0 +1,9 @@
+0.0.325
+  - No longer flattening properties starting with - because for version policy, the 
+    context macro ${@} is not valid. I think this is true for more things. So they are now
+    unexpanded.
+  - toclasspath can now take a suffix parameter, possibly empty
+  - Include-Resource can now take optional parameters:
+      flatten:= (true|false). Default is false. Create recursive directories in the output or not.
+      recursive:= (true|false) Default is true. Will descend any directories or not
+      
diff --git a/bundleplugin/src/main/resources/aQute/bnd/help/syntax.properties b/bundleplugin/src/main/resources/aQute/bnd/help/syntax.properties
new file mode 100644
index 0000000..14ec642
--- /dev/null
+++ b/bundleplugin/src/main/resources/aQute/bnd/help/syntax.properties
@@ -0,0 +1,342 @@
+Add=Holders of DmtPermission with the Add action present can create new nodes in the DMT, that is they are authorized to execute the createInteriorNode() and createLeafNode() methods of the DmtSession.
+Delete=Holders of DmtPermission with the Delete action present can delete nodes from the DMT, that is they are authorized to execute the deleteNode() method of the DmtSession.
+Exec=Holders of DmtPermission with the Exec action present can execute nodes in the DMT, that is they are authorized to call the execute() method of the DmtSession.
+Get=Holders of DmtPermission with the Get action present can query DMT node value or properties, that is they are authorized to execute the isLeafNode(), getNodeAcl(), getEffectiveNodeAcl(), getMetaNode(), getNodeValue(), getChildNodeNames(), getNodeTitle(), getNodeVersion(), getNodeTimeStamp(), getNodeSize() and getNodeType() methods of the DmtSession.
+Replace=Holders of DmtPermission with the Replace action present can update DMT node value or properties, that is they are authorized to execute the setNodeAcl(), setNodeTitle(), setNodeValue(), setNodeType() and renameNode() methods of the DmtSession.
+get=The action string get.
+register=The action string register.
+export=The action string export.
+exportonly=The action string exportonly.
+import=The action string import.
+System Bundle=Location identifier of the OSGi system bundle , which is defined to be "System Bundle".
+system.bundle=Alias for the symbolic name of the OSGi system bundle .
+Bundle-Category=Manifest header identifying the bundle's category.
+Bundle-ClassPath=Manifest header identifying a list of directories and embedded JAR files, which are bundle resources used to extend the bundle's classpath.
+Bundle-Copyright=Manifest header identifying the bundle's copyright information.
+Bundle-Description=Manifest header containing a brief description of the bundle's functionality.
+Bundle-Name=Manifest header identifying the bundle's name.
+Bundle-NativeCode=Manifest header identifying a number of hardware environments and the native language code libraries that the bundle is carrying for each of these environments.
+Export-Package=Manifest header identifying the packages that the bundle offers to the Framework for export.
+Export-Service=Manifest header identifying the fully qualified class names of the services that the bundle may register (used for informational purposes only).
+Import-Package=Manifest header identifying the packages on which the bundle depends.
+DynamicImport-Package=Manifest header identifying the packages that the bundle may dynamically import during execution.
+Import-Service=Manifest header identifying the fully qualified class names of the services that the bundle requires (used for informational purposes only).
+Bundle-Vendor=Manifest header identifying the bundle's vendor.
+Bundle-Version=Manifest header identifying the bundle's version.
+Bundle-DocURL=Manifest header identifying the bundle's documentation URL, from which further information about the bundle may be obtained.
+Bundle-ContactAddress=Manifest header identifying the contact address where problems with the bundle may be reported; for example, an email address.
+Bundle-Activator=Manifest header attribute identifying the bundle's activator class.
+Bundle-UpdateLocation=Manifest header identifying the location from which a new bundle version is obtained during a bundle update operation.
+specification-version=Manifest header attribute identifying the version of a package specified in the Export-Package or Import-Package manifest header.
+processor=Manifest header attribute identifying the processor required to run native bundle code specified in the Bundle-NativeCode manifest header).
+osname=Manifest header attribute identifying the operating system required to run native bundle code specified in the Bundle-NativeCode manifest header).
+osversion=Manifest header attribute identifying the operating system version required to run native bundle code specified in the Bundle-NativeCode manifest header).
+language=Manifest header attribute identifying the language in which the native bundle code is written specified in the Bundle-NativeCode manifest header.
+Bundle-RequiredExecutionEnvironment=Manifest header identifying the required execution environment for the bundle.
+Bundle-SymbolicName=Manifest header identifying the bundle's symbolic name.
+singleton=Manifest header directive identifying whether a bundle is a singleton.
+fragment-attachment=Manifest header directive identifying if and when a fragment may attach to a host bundle.
+always=Manifest header directive value identifying a fragment attachment type of always.
+resolve-time=Manifest header directive value identifying a fragment attachment type of resolve-time.
+never=Manifest header directive value identifying a fragment attachment type of never.
+Bundle-Localization=Manifest header identifying the base name of the bundle's localization entries.
+OSGI-INF/l10n/bundle=Default value for the Bundle-Localization manifest header.
+Require-Bundle=Manifest header identifying the symbolic names of other bundles required by the bundle.
+bundle-version=Manifest header attribute identifying a range of versions for a bundle specified in the Require-Bundle or Fragment-Host manifest headers.
+Fragment-Host=Manifest header identifying the symbolic name of another bundle for which that the bundle is a fragment.
+selection-filter=Manifest header attribute is used for selection by filtering based upon system properties.
+Bundle-ManifestVersion=Manifest header identifying the bundle manifest version.
+version=Manifest header attribute identifying the version of a package specified in the Export-Package or Import-Package manifest header.
+bundle-symbolic-name=Manifest header attribute identifying the symbolic name of a bundle that exports a package specified in the Import-Package manifest header.
+resolution=Manifest header directive identifying the resolution type in the Import-Package or Require-Bundle manifest header.
+mandatory=Manifest header directive value identifying a mandatory resolution type.
+optional=Manifest header directive value identifying an optional resolution type.
+uses=Manifest header directive identifying a list of packages that an exported package uses.
+include=Manifest header directive identifying a list of classes to include in the exported package.
+exclude=Manifest header directive identifying a list of classes to exclude in the exported package..
+mandatory=Manifest header directive identifying names of matching attributes which must be specified by matching Import-Package statements in the Export-Package manifest header.
+visibility=Manifest header directive identifying the visibility of a required bundle in the Require-Bundle manifest header.
+private=Manifest header directive value identifying a private visibility type.
+reexport=Manifest header directive value identifying a reexport visibility type.
+extension=Manifest header directive identifying the type of the extension fragment.
+framework=Manifest header directive value identifying the type of extension fragment.
+bootclasspath=Manifest header directive value identifying the type of extension fragment.
+Bundle-ActivationPolicy=Manifest header identifying the bundle's activation policy.
+lazy=Bundle activation policy declaring the bundle must be activated when the first class load is made from the bundle.
+org.osgi.framework.version=Framework environment property identifying the Framework version.
+org.osgi.framework.vendor=Framework environment property identifying the Framework implementation vendor.
+org.osgi.framework.language=Framework environment property identifying the Framework implementation language (see ISO 639 for possible values).
+org.osgi.framework.os.name=Framework environment property identifying the Framework host-computer's operating system.
+org.osgi.framework.os.version=Framework environment property identifying the Framework host-computer's operating system version number.
+org.osgi.framework.processor=Framework environment property identifying the Framework host-computer's processor name.
+org.osgi.framework.executionenvironment=Framework environment property identifying execution environments provided by the Framework.
+org.osgi.framework.bootdelegation=Framework environment property identifying packages for which the Framework must delegate class loading to the parent class loader of the bundle.
+org.osgi.framework.system.packages=Framework environment property identifying packages which the system bundle must export.
+org.osgi.framework.system.packages.extra=Framework environment property identifying extra packages which the system bundle must export from the current execution environment.
+org.osgi.supports.framework.extension=Framework environment property identifying whether the Framework supports framework extension bundles.
+org.osgi.supports.bootclasspath.extension=Framework environment property identifying whether the Framework supports bootclasspath extension bundles.
+org.osgi.supports.framework.fragment=Framework environment property identifying whether the Framework supports fragment bundles.
+org.osgi.supports.framework.requirebundle=Framework environment property identifying whether the Framework supports the Require-Bundle manifest header.
+org.osgi.framework.security=Specifies the type of security manager the framework must use.
+osgi=Specifies that a security manager that supports all security aspects of the OSGi core specification including postponed conditions must be installed.
+org.osgi.framework.storage=Specified the persistent storage area used by the framework.
+org.osgi.framework.storage.clean=Specifies if and when the persistent storage area for the framework should be cleaned.
+onFirstInit=Specifies that the framework storage area must be cleaned before the framework is initialized for the first time.
+org.osgi.framework.library.extensions=Specifies a comma separated list of additional library file extensions that must be used when a bundle's class loader is searching for native libraries.
+org.osgi.framework.command.execpermission=Specifies an optional OS specific command to set file permissions on extracted native code.
+org.osgi.framework.trust.repositories=Specifies the trust repositories used by the framework.
+org.osgi.framework.windowsystem=Specifies the current windowing system.
+org.osgi.framework.startlevel.beginning=Specifies the beginning start level of the framework.
+org.osgi.framework.bundle.parent=Specifies the parent class loader type for all bundle class loaders.
+boot=Specifies to use of the boot class loader as the parent class loader for all bundle class loaders.
+app=Specifies to use the application class loader as the parent class loader for all bundle class loaders.
+ext=Specifies to use the extension class loader as the parent class loader for all bundle class loaders.
+framework=Specifies to use the framework class loader as the parent class loader for all bundle class loaders.
+objectClass=Service property identifying all of the class names under which a service was registered in the Framework.
+service.id=Service property identifying a service's registration number.
+service.pid=Service property identifying a service's persistent identifier.
+service.ranking=Service property identifying a service's ranking number.
+service.vendor=Service property identifying a service's vendor.
+service.description=Service property identifying a service's description.
+provide=The action string provide.
+require=The action string require.
+host=The action string host.
+fragment=The action string fragment.
+class=The action string class.
+execute=The action string execute.
+extensionLifecycle=The action string extensionLifecycle.
+lifecycle=The action string lifecycle.
+listener=The action string listener.
+metadata=The action string metadata.
+resolve=The action string resolve.
+resource=The action string resource.
+startlevel=The action string startlevel.
+context=The action string context.
+service.pid=The property key for the identifier of the application being scheduled.
+schedule.id=The property key for the schedule identifier.
+org.osgi.triggeringevent=The key for the startup argument used to pass the event object that triggered the schedule to launch the application instance.
+org/osgi/application/timer=The topic name for the virtual timer topic.
+year=The name of the year attribute of a virtual timer event.
+month=The name of the month attribute of a virtual timer event.
+day_of_month=The name of the day of month attribute of a virtual timer event.
+day_of_week=The name of the day of week attribute of a virtual timer event.
+hour_of_day=The name of the hour of day attribute of a virtual timer event.
+minute=The name of the minute attribute of a virtual timer event.
+service.pid=The property key for the unique identifier (PID) of the application instance.
+application.descriptor=The property key for the pid of the corresponding application descriptor.
+application.state=The property key for the state of this application instance.
+application.supports.exitvalue=The property key for the supports exit value property of this application instance.
+RUNNING=The application instance is running.
+STOPPING=The application instance is being stopped.
+application.name=The property key for the localized name of the application.
+application.icon=The property key for the localized icon of the application.
+service.pid=The property key for the unique identifier (PID) of the application.
+application.version=The property key for the version of the application.
+service.vendor=The property key for the name of the application vendor.
+application.visible=The property key for the visibility property of the application.
+application.launchable=The property key for the launchable property of the application.
+application.locked=The property key for the locked property of the application.
+application.description=The property key for the localized description of the application.
+application.documentation=The property key for the localized documentation of the application.
+application.copyright=The property key for the localized copyright notice of the application.
+application.license=The property key for the localized license of the application.
+application.container=The property key for the application container of the application.
+application.location=The property key for the location of the application.
+lifecycle=Allows the lifecycle management of the target applications.
+schedule=Allows scheduling of the target applications.
+lock=Allows setting/unsetting the locking state of the target applications.
+bundle.version=The version property defining the bundle on whose behalf a module context event has been issued.
+extender.bundle=The extender bundle property defining the extender bundle processing the module context for which an event has been issued.
+extender.bundle.id=The extender bundle id property defining the id of the extender bundle processing the module context for which an event has been issued.
+extender.bundle.symbolicName=The extender bundle symbolic name property defining the symbolic name of the extender bundle processing the module context for which an event has been issued.
+org/osgi/service/blueprint=Topic prefix for all events issued by the Blueprint Service
+org/osgi/service/blueprint/context/CREATING=Topic for Blueprint Service CREATING events
+org/osgi/service/blueprint/context/CREATED=Topic for Blueprint Service CREATED events
+org/osgi/service/blueprint/context/DESTROYING=Topic for Blueprint Service DESTROYING events
+org/osgi/service/blueprint/context/DESTROYED=Topic for Blueprint Service DESTROYED events
+org/osgi/service/blueprint/context/WAITING=Topic for Blueprint Service WAITING events
+org/osgi/service/blueprint/context/FAILURE=Topic for Blueprint Service FAILURE events
+singleton=
+prototype=
+bundle=
+cm.target=A service property to limit the Managed Service or Managed Service Factory configuration dictionaries a Configuration Plugin service receives.
+service.cmRanking=A service property to specify the order in which plugins are invoked.
+configure=The action string configure.
+service.factoryPid=Service property naming the Factory PID in the configuration dictionary.
+service.bundleLocation=Service property naming the location of the bundle that is associated with a a Configuration object.
+osgi.converter.classes=This property is a string, or array of strings, and defines the classes or interfaces that this converter recognizes.
+osgi.command.scope=The scope of commands provided by this service.
+osgi.command.function=A String, array, or list of method names that may be called for this command provider.
+Service-Component=Manifest header specifying the XML documents within a bundle that contain the bundle's Service Component descriptions.
+component.name=A component property for a component configuration that contains the name of the component as specified in the name attribute of the component element.
+component.id=A component property that contains the generated id for a component configuration.
+component.factory=A service registration property for a Component Factory that contains the value of the factory attribute.
+.target=The suffix for reference target properties.
+allow=This string is used to indicate that a row in the Conditional Permission Table should return an access decision of "allow" if the conditions are all satisfied and at least one of the permissions is implied.
+deny=This string is used to indicate that a row in the Conditional Permission Table should return an access decision of "deny" if the conditions are all satisfied and at least one of the permissions is implied.
+deploymentpackage.name=The name of the Deployment Package.
+deploymentpackage.readablename=The human readable name of the DP localized to the default locale.
+deploymentpackage.currentversion=The currently installed version of the Deployment Package.
+deploymentpackage.nextversion=The version of DP after the successful completion of the install operation (used in INSTALL event only).
+install=Constant String to the "install" action.
+list=Constant String to the "list" action.
+uninstall=Constant String to the "uninstall" action.
+uninstall_forced=Constant String to the "uninstall_forced" action.
+cancel=Constant String to the "cancel" action.
+metadata=Constant String to the "metadata" action.
+privatearea=Constant String to the "privatearea" action.
+-1=Return value from DriverSelector.select, if no Driver service should be attached to the Device service.
+DRIVER_ID=Property (named "DRIVER_ID") identifying a driver.
+DEVICE_CATEGORY=Property (named "DEVICE_CATEGORY") containing a human readable description of the device categories implemented by a device.
+DEVICE_SERIAL=Property (named "DEVICE_SERIAL") specifying a device's serial number.
+DEVICE_DESCRIPTION=Property (named "DEVICE_DESCRIPTION") containing a human readable string describing the actual hardware device.
+service.interface=Mandatory ServiceRegistration property which contains a collection of full qualified interface names offered by the advertised service endpoint.
+service.interface.version=Optional ServiceRegistration property which contains a collection of interface names with their associated version attributes separated by SEPARATOR e.g.
+osgi.remote.endpoint.interface=Optional ServiceRegistration property which contains a collection of interface names with their associated (non-Java) endpoint interface names separated by SEPARATOR e.g.: 'my.company.foo|MyWebService my.company.zoo|MyWebService'. This (non-Java) endpoint interface name is usually a communication protocol specific interface, for instance a web service interface name.
+service.properties=Optional ServiceRegistration property which contains a map of properties of the published service.
+osgi.remote.endpoint.location=Optional property of the published service identifying its location.
+osgi.remote.endpoint.id=Optional property of the published service uniquely identifying its endpoint.
+|=Separator constant for association of interface-specific values with the particular interface name.
+osgi.remote.discovery.product=Service Registration property for the name of the Discovery product.
+osgi.remote.discovery.product.version=Service Registration property for the version of the Discovery product.
+osgi.remote.discovery.vendor=Service Registration property for the Discovery product vendor name.
+osgi.remote.discovery.supported_protocols=Service Registration property that lists the discovery protocols used by this Discovery service.
+osgi.discovery.interest.interfaces=Optional ServiceRegistration property which contains service interfaces this tracker is interested in.
+osgi.discovery.interest.filters=Optional ServiceRegistration property which contains filters for services this tracker is interested in.
+osgi.remote.distribution.product=Service Registration property for the name of the Distribution Provider product.
+osgi.remote.distribution.product.version=Service Registration property for the version of the Distribution Provider product.
+osgi.remote.distribution.vendor=Service Registration property for the Distribution Provider product vendor name.
+osgi.remote.distribition.supported_intents=Service Registration property that lists the intents supported by this DistributionProvider.
+publish=The action string publish.
+subscribe=The action string subscribe.
+event.topics=Service registration property (named event.topics) specifying the Event topics of interest to a Event Handler service.
+event.filter=Service Registration property (named event.filter) specifying a filter to further select Event s of interest to a Event Handler service.
+bundle.signer=The Distinguished Names of the signers of the bundle relevant to the event.
+bundle.symbolicName=The Bundle Symbolic Name of the bundle relevant to the event.
+bundle.id=The Bundle id of the bundle relevant to the event.
+bundle=The Bundle object of the bundle relevant to the event.
+bundle.version=The version of the bundle relevant to the event.
+event=The forwarded event object.
+exception=An exception or error.
+exception.class=The name of the exception type.
+exception.message=The exception message.
+message=A human-readable message that is usually not localized.
+service=A service reference.
+service.id=A service's id.
+service.objectClass=A service's objectClass.
+service.pid=A service's persistent identity.
+timestamp=The time when the event occurred, as reported by System.currentTimeMillis().
+exception.class=This constant was released with an incorrectly spelled name.
+CompositeServiceFilter-Import=Manifest header (named "CompositeServiceFilter-Import") identifying the service filters that are used by a composite bundle to select services that will be registered into a child framework by its associated surrogate bundle.
+CompositeServiceFilter-Export=Manifest header (named "CompositeServiceFilter-Export") identifying the service filters that are used by a surrogate bundle to select services that will be registered into a parent framework by its associated composite bundle.
+org.osgi.service.http.authentication.remote.user=HttpServletRequest attribute specifying the name of the authenticated user.
+org.osgi.service.http.authentication.type=HttpServletRequest attribute specifying the scheme used in authentication.
+org.osgi.service.useradmin.authorization=HttpServletRequest attribute specifying the Authorization object obtained from the org.osgi.service.useradmin.UserAdmin service.
+io.scheme=Service property containing the scheme(s) for which this Connection Factory can create Connection objects.
+-1=Argument for getAttributeDefinitions(int).
+OSGI-INF/metatype=Location of meta type documents.
+read=Holders of MonitorPermission with the read action present are allowed to read the value of the StatusVariables specified in the permission's target field.
+reset=Holders of MonitorPermission with the reset action present are allowed to reset the value of the StatusVariables specified in the permission's target field.
+publish=Holders of MonitorPermission with the publish action present are Monitorable services that are allowed to publish the StatusVariables specified in the permission's target field.
+startjob=Holders of MonitorPermission with the startjob action present are allowed to initiate monitoring jobs involving the StatusVariables specified in the permission's target field.
+switchevents=Holders of MonitorPermission with the switchevents action present are allowed to switch event sending on or off for the value of the StatusVariables specified in the permission's target field.
+license=
+description=
+documentation=
+copyright=
+source=
+symbolicname=
+presentationname=
+id=
+version=
+url=
+size=
+provisioning.spid=The key to the provisioning information that uniquely identifies the Service Platform.
+provisioning.reference=The key to the provisioning information that contains the location of the provision data provider.
+provisioning.agent.config=The key to the provisioning information that contains the initial configuration information of the initial Management Agent.
+provisioning.update.count=The key to the provisioning information that contains the update count of the info data.
+provisioning.start.bundle=The key to the provisioning information that contains the location of the bundle to start with AllPermission.
+provisioning.rootx509=The key to the provisioning information that contains the root X509 certificate used to establish trust with operator when using HTTPS.
+provisioning.rsh.secret=The key to the provisioning information that contains the shared secret used in conjunction with the RSH protocol.
+text/plain;charset=utf-8=MIME type to be used in the InitialProvisioning-Entries header or stored in the extra field of a ZipEntry object for String data.
+application/octet-stream=MIME type to be used in the InitialProvisioning-Entries header or stored stored in the extra field of a ZipEntry object for byte[] data.
+application/vnd.osgi.bundle=MIME type to be used in the InitialProvisioning-Entries header or stored stored in the extra field of a ZipEntry object for an installable bundle file.
+application/x-osgi-bundle=Alternative MIME type to be used in the InitialProvisioning-Entries header or stored stored in the extra field of a ZipEntry object for an installable bundle file.
+text/x-osgi-bundle-url=MIME type to be stored in the extra field of a ZipEntry for a String that represents a URL for a bundle.
+InitialProvisioning-Entries=Name of the header that specifies the (MIME) type information for the ZIP file entries.
+ui1=Unsigned 1 Byte int.
+ui2=Unsigned 2 Byte int.
+ui4=Unsigned 4 Byte int.
+i1=1 Byte int.
+i2=2 Byte int.
+i4=4 Byte int.
+int=Integer number.
+r4=4 Byte float.
+r8=8 Byte float.
+number=Same as r8.
+fixed.14.4=Same as r8 but no more than 14 digits to the left of the decimal point and no more than 4 to the right.
+float=Floating-point number.
+char=Unicode string.
+string=Unicode string.
+date=A calendar date.
+dateTime=A specific instant of time.
+dateTime.tz=A specific instant of time.
+time=An instant of time that recurs every day.
+time.tz=An instant of time that recurs every day.
+boolean=True or false.
+bin.base64=MIME-style Base64 encoded binary BLOB.
+bin.hex=Hexadecimal digits representing octets.
+uri=Universal Resource Identifier.
+uuid=Universally Unique ID.
+UPnP.service.type=Property key for the optional service type uri.
+UPnP.service.id=Property key for the optional service id.
+upnp.filter=Key for a service property having a value that is an object of type org.osgi.framework.Filter and that is used to limit received events.
+UPnP=Constant for the value of the service property DEVICE_CATEGORY used for all UPnP devices.
+UPnP.export=The UPnP.export service property is a hint that marks a device to be picked up and exported by the UPnP Service.
+UPnP.device.UDN=Property key for the Unique Device Name (UDN) property.
+UPnP.device.UDN=Property key for the Unique Device ID property.
+UPnP.device.type=Property key for the UPnP Device Type property.
+UPnP.device.manufacturer=Mandatory property key for the device manufacturer's property.
+UPnP.device.modelName=Mandatory property key for the device model name.
+UPnP.device.friendlyName=Mandatory property key for a short user friendly version of the device name.
+UPnP.device.manufacturerURL=Optional property key for a URL to the device manufacturers Web site.
+UPnP.device.modelDescription=Optional (but recommended) property key for a String object with a long description of the device for the end user.
+UPnP.device.modelNumber=Optional (but recommended) property key for a String class typed property holding the model number of the device.
+UPnP.device.modelURL=Optional property key for a String typed property holding a string representing the URL to the Web site for this model.
+UPnP.device.serialNumber=Optional (but recommended) property key for a String typed property holding the serial number of the device.
+UPnP.device.UPC=Optional property key for a String typed property holding the Universal Product Code (UPC) of the device.
+UPnP.presentationURL=Optional (but recommended) property key for a String typed property holding a string representing the URL to a device representation Web page.
+UPnP.device.parentUDN=The property key that must be set for all embedded devices.
+UPnP.device.childrenUDN=The property key that must be set for all devices containing other embedded devices.
+url.handler.protocol=Service property naming the protocols serviced by a URLStreamHandlerService.
+url.content.mimetype=Service property naming the MIME types serviced by a java.net.ContentHandler.
+admin=The permission name "admin".
+changeProperty=The action string "changeProperty".
+changeCredential=The action string "changeCredential".
+getCredential=The action string "getCredential".
+user.anyone=The name of the predefined role, user.anyone, that all users and groups belong to.
+produce=The action string for the produce action.
+consume=The action string for the consume action.
+wireadmin.pid=Wire property key (named wireadmin.pid) specifying the persistent identity (PID) of this Wire object.
+wireadmin.producer.composite=A service registration property for a Producer service that is composite.
+wireadmin.consumer.composite=A service registration property for a Consumer service that is composite.
+wireadmin.producer.scope=Service registration property key (named wireadmin.producer.scope) specifying a list of names that may be used to define the scope of this Wire object.
+wireadmin.consumer.scope=Service registration property key (named wireadmin.consumer.scope) specifying a list of names that may be used to define the scope of this Wire object.
+wireadmin.producer.pid=Wire property key (named wireadmin.producer.pid) specifying the service.pid of the associated Producer service.
+wireadmin.consumer.pid=Wire property key (named wireadmin.consumer.pid) specifying the service.pid of the associated Consumer service.
+wireadmin.filter=Wire property key (named wireadmin.filter) specifying a filter used to control the delivery rate of data between the Producer and the Consumer service.
+wirevalue.current=Wire object's filter attribute (named wirevalue.current) representing the current value.
+wirevalue.previous=Wire object's filter attribute (named wirevalue.previous) representing the previous value.
+wirevalue.delta.absolute=Wire object's filter attribute (named wirevalue.delta.absolute) representing the absolute delta.
+wirevalue.delta.relative=Wire object's filter attribute (named wirevalue.delta.relative) representing the relative delta.
+wirevalue.elapsed=Wire object's filter attribute (named wirevalue.elapsed) representing the elapsed time, in ms, between this filter evaluation and the last update of the Consumer service.
+wireadmin.producer.filters=Service Registration property (named wireadmin.producer.filters).
+wireadmin.consumer.flavors=Service Registration property (named wireadmin.consumer.flavors) specifying the list of data types understood by this Consumer service.
+wireadmin.producer.flavors=Service Registration property (named wireadmin.producer.flavors) specifying the list of data types available from this Producer service.
+wireadmin.events=Service Registration property (named wireadmin.events) specifying the WireAdminEvent type of interest to a Wire Admin Listener service.
+javax.xml.parsers.SAXParserFactory=Filename containing the SAX Parser Factory Class name.
+javax.xml.parsers.DocumentBuilderFactory=Filename containing the DOM Parser Factory Class name.
+/META-INF/services/javax.xml.parsers.SAXParserFactory=Fully qualified path name of SAX Parser Factory Class Name file
+/META-INF/services/javax.xml.parsers.DocumentBuilderFactory=Fully qualified path name of DOM Parser Factory Class Name file
+parser.validating=Service property specifying if factory is configured to support validating parsers.
+parser.namespaceAware=Service property specifying if factory is configured to support namespace aware parsers.
diff --git a/bundleplugin/src/main/resources/aQute/bnd/help/syntax.xml b/bundleplugin/src/main/resources/aQute/bnd/help/syntax.xml
new file mode 100644
index 0000000..e81df31
--- /dev/null
+++ b/bundleplugin/src/main/resources/aQute/bnd/help/syntax.xml
@@ -0,0 +1,2 @@
+
+Bundle-Name\\s*(:|=)\\s*
\ No newline at end of file
diff --git a/bundleplugin/src/main/resources/aQute/lib/osgi/bnd.info b/bundleplugin/src/main/resources/aQute/lib/osgi/bnd.info
new file mode 100644
index 0000000..61961b8
--- /dev/null
+++ b/bundleplugin/src/main/resources/aQute/lib/osgi/bnd.info
@@ -0,0 +1,2 @@
+modified=1318539668324
+version=1.47.0
diff --git a/bundleplugin/src/main/resources/aQute/lib/spring/extract.xsl b/bundleplugin/src/main/resources/aQute/lib/spring/extract.xsl
new file mode 100644
index 0000000..efad6cd
--- /dev/null
+++ b/bundleplugin/src/main/resources/aQute/lib/spring/extract.xsl
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium" xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:tool="http://www.springframework.org/schema/tool" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:webflow-config="http://www.springframework.org/schema/webflow-config">
+	<xsl:output method="text" />
+
+	<xsl:template match="/">
+
+		<!-- Match all attributes that holds a class or a comma delimited 
+		     list of classes and print them -->
+
+		<xsl:for-each select="
+				//beans:bean/@class 
+			|	//beans:*/@value-type 
+ 			|	//aop:*/@implement-interface
+			|	//aop:*/@default-impl
+			|	//context:load-time-weaver/@weaver-class
+			|	//jee:jndi-lookup/@expected-type
+			|	//jee:jndi-lookup/@proxy-interface
+			| 	//jee:remote-slsb/@ejbType
+			|	//jee:*/@business-interface
+			|	//lang:*/@script-interfaces
+			|	//osgi:*/@interface
+			|	//util:list/@list-class
+			|	//util:set/@set-class
+			|	//util:map/@map-class
+			|	//webflow-config:*/@class
+		">
+			<xsl:value-of select="." />
+			<xsl:text>
+			</xsl:text>
+		</xsl:for-each>
+
+		<!-- This seems some magic to get extra imports? -->
+
+		<xsl:for-each select="//beans:bean[@class='org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean'
+				or @class='org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean']">
+			<xsl:for-each select="beans:property[@name='interfaces']">
+				<xsl:value-of select="@value" />
+				<xsl:text>
+				</xsl:text>
+			</xsl:for-each>
+		</xsl:for-each>
+
+	</xsl:template>
+
+
+</xsl:stylesheet>
+
diff --git a/bundleplugin/src/main/resources/aQute/lib/spring/hibernate.xsl b/bundleplugin/src/main/resources/aQute/lib/spring/hibernate.xsl
new file mode 100644
index 0000000..1f0a1c6
--- /dev/null
+++ b/bundleplugin/src/main/resources/aQute/lib/spring/hibernate.xsl
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium" xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:tool="http://www.springframework.org/schema/tool" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:webflow-config="http://www.springframework.org/schema/webflow-config">
+	<xsl:output method="text" />
+
+	<xsl:template match="/">
+
+		<!-- Match all attributes that holds a class or a comma delimited 
+		     list of classes and print them -->
+
+		<xsl:for-each select="//provider|//class">
+			<xsl:value-of select="." />
+			<xsl:text>
+			</xsl:text>
+		</xsl:for-each>
+	</xsl:template>
+
+
+</xsl:stylesheet>
+
diff --git a/bundleplugin/src/main/resources/aQute/lib/spring/jpa.xsl b/bundleplugin/src/main/resources/aQute/lib/spring/jpa.xsl
new file mode 100644
index 0000000..43bba60
--- /dev/null
+++ b/bundleplugin/src/main/resources/aQute/lib/spring/jpa.xsl
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium" xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:tool="http://www.springframework.org/schema/tool" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:webflow-config="http://www.springframework.org/schema/webflow-config">
+	<xsl:output method="text" />
+
+	<xsl:template match="/">
+
+		<!-- Match all attributes that holds a class or a comma delimited 
+		     list of classes and print them -->
+
+		<xsl:for-each select="
+     	//class/@name
+    | 	//composite-id/@class
+    | 	//component/@class
+    | 	//discriminator/@type
+    | 	//dynamic-component/@class
+    | 	//generator/@class
+    | 	//id/@type
+    | 	//import/@class
+    | 	//joined-subclass/@name
+    | 	//many-to-many/@class
+    | 	//many-to-one/@class
+    | 	//one-to-many/@class
+    | 	//one-to-one/@class
+    | 	//property/@type
+    | 	//subclass/@name
+    | 	//union-subclass/@name
+    | 	//version/@type
+ 		">
+			<xsl:value-of select="." />
+			<xsl:text>
+			</xsl:text>
+		</xsl:for-each>
+	</xsl:template>
+
+
+</xsl:stylesheet>
+
