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/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..ecaaa7b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Configurable.java
@@ -0,0 +1,294 @@
+package aQute.bnd.annotation.metatype;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+@SuppressWarnings( { "unchecked", "rawtypes" }) 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) {
+				Class<?> rt = method.getReturnType();
+				if ( rt == boolean.class || rt==Boolean.class)
+					return false;
+				
+				if (method.getReturnType().isPrimitive()) {
+
+					o = "0";
+				} else
+					return null;
+			}
+
+			return convert(method.getGenericReturnType(), o);
+		}
+
+		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);
+				}
+				
+				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());
+			}
+			if (Map.class.isAssignableFrom(resultType)){
+				Map<?,?> input = toMap(o);
+				if (resultType.isInterface()) {
+					if (resultType == SortedMap.class)
+						resultType = TreeMap.class;
+					else if (resultType == Map.class)
+						resultType = LinkedHashMap.class;
+					else
+						throw new IllegalArgumentException(
+								"Unknown interface for a collection, no concrete class found: "
+										+ resultType);
+				}
+				Map<Object,Object> result = (Map<Object,Object>) resultType
+						.newInstance();
+				Type keyType = pType.getActualTypeArguments()[0];
+				Type valueType = pType.getActualTypeArguments()[1];
+
+				for ( Map.Entry<?, ?> entry : input.entrySet()) {
+					result.put(convert(keyType,entry.getKey()), convert(valueType,entry.getValue()));
+				}
+				return result;
+			}
+			throw new IllegalArgumentException("cannot convert to " + pType
+					+ " because it uses generics and is not a Collection or a map");
+		}
+
+
+		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);
+		}
+		
+		private Map<?, ?> toMap(Object o) {
+			if ( o instanceof Map) 
+				return (Map<?, ?>) o;
+			
+			throw new IllegalArgumentException(
+					"Cannot convert " + o + " to a map as requested");
+		}
+
+
+	}
+	
+	
+	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..2fb38d9
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Container.java
@@ -0,0 +1,210 @@
+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, PROJECT_BUNDLE, 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 = null;
+			BufferedReader rd = null;
+			String line;
+			try {
+				in = new FileInputStream(file);
+				rd = new BufferedReader(new InputStreamReader(in,
+						Constants.DEFAULT_CHARSET));
+				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 {
+				if (rd != null) {
+					rd.close();
+				}
+				if (in != null) {
+					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..034a364
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
@@ -0,0 +1,2092 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
+import java.util.jar.*;
+
+import aQute.bnd.help.*;
+import aQute.bnd.maven.support.*;
+import aQute.bnd.service.*;
+import aQute.bnd.service.RepositoryPlugin.Strategy;
+import aQute.bnd.service.action.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.eclipse.*;
+import aQute.libg.generics.*;
+import aQute.libg.header.*;
+import aQute.libg.sed.*;
+import aQute.libg.version.*;
+
+/**
+ * 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>	classpath				= new LinkedHashSet<Container>();
+	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[];
+	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 {
+						Container c = new Container(this, output);
+						if (!buildpath.contains(c))
+							buildpath.add(c);
+					}
+
+					// 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 = new Parameters(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 " + p + " 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>();
+		Parameters bundles = new Parameters(spec);
+
+		try {
+			for (Iterator<Entry<String, Attrs>> i = bundles.entrySet().iterator(); i.hasNext();) {
+				Entry<String, Attrs> entry = i.next();
+				String bsn = entry.getKey();
+				Map<String, String> attrs = entry.getValue();
+
+				Container found = null;
+
+				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, versionRange,
+									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;
+	}
+
+	/**
+	 * Just calls a new method with a default parm.
+	 * 
+	 * @throws Exception
+	 * 
+	 */
+	Collection<Container> getBundles(Strategy strategy, String spec) throws Exception {
+		return getBundles(strategy, spec, null);
+	}
+
+	/**
+	 * 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, Attrs>> queue = new LinkedList<Map.Entry<String, Attrs>>();
+		queue.addAll(new Parameters(spec).entrySet());
+
+		while (!queue.isEmpty()) {
+			Entry<String, Attrs> 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, new Parameters(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 {
+		trace("release %s", name);
+		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 {
+				File file = rp.put(jar);
+				trace("Released %s to file %s in repository %s", jar.getName(), file, rp);
+			} catch (Exception e) {
+				error("Deploying " + jar.getName() + " on " + rp.getName(), e);
+			} finally {
+				jar.close();
+			}
+		} else if (name == null)
+			error("There is no writable repository (no repo name specified)");
+		else
+			error("Cannot find a writeable repository with the name %s from the repositiories %s",
+					name, plugins);
+
+		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 {
+		trace("release");
+		File[] jars = build(test);
+		// If build fails jars will be null
+		if (jars == null) {
+			trace("no jars being build");
+			return;
+		}
+		trace("build ", Arrays.toString(jars));
+		for (File jar : jars) {
+			Jar j = new Jar(jar);
+			try {
+				release(name, j);
+			} finally {
+				j.close();
+			}
+		}
+
+	}
+
+	/**
+	 * Get a bundle from one of the plugin repositories. If an exact version is
+	 * required we just return the first repository found (in declaration order
+	 * in the build.bnd file).
+	 * 
+	 * @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 strategy,
+			Map<String, String> attrs) throws Exception {
+
+		if (range == null)
+			range = "0";
+
+		if ("snapshot".equals(range)) {
+			return getBundleFromProject(bsn, attrs);
+		}
+
+		Strategy useStrategy = strategy;
+
+		if ("latest".equals(range)) {
+			Container c = getBundleFromProject(bsn, attrs);
+			if (c != null)
+				return c;
+
+			useStrategy = Strategy.HIGHEST;
+		}
+
+		useStrategy = overrideStrategy(attrs, useStrategy);
+
+		List<RepositoryPlugin> plugins = workspace.getRepositories();
+
+		if (useStrategy == Strategy.EXACT) {
+
+			// For an exact range we just iterate over the repos
+			// and return the first we find.
+
+			for (RepositoryPlugin plugin : plugins) {
+				File result = plugin.get(bsn, range, Strategy.EXACT, attrs);
+				if (result != null)
+					return toContainer(bsn, range, attrs, result);
+			}
+		} else {
+			VersionRange versionRange = "latest".equals(range) ? new VersionRange("0")
+					: new VersionRange(range);
+
+			// We have a range search. Gather all the versions in all the repos
+			// and make a decision on that choice. If the same version is found
+			// in
+			// multiple repos we take the first
+
+			SortedMap<Version, RepositoryPlugin> versions = new TreeMap<Version, RepositoryPlugin>();
+			for (RepositoryPlugin plugin : plugins) {
+				try {
+					List<Version> vs = plugin.versions(bsn);
+					if (vs != null) {
+						for (Version v : vs) {
+							if (!versions.containsKey(v) && versionRange.includes(v))
+								versions.put(v, plugin);
+						}
+					}
+				} catch (UnsupportedOperationException ose) {
+					// We have a plugin that cannot list versions, try
+					// if it has this specific version
+					// The main reaosn for this code was the Maven Remote
+					// Repository
+					// To query, we must have a real version
+					if (!versions.isEmpty() && Verifier.isVersion(range)) {
+						File file = plugin.get(bsn, range, useStrategy, attrs);
+						// and the entry must exist
+						// if it does, return this as a result
+						if (file != null)
+							return toContainer(bsn, range, attrs, file);
+					}
+				}
+			}
+
+			// Verify if we found any, if so, we use the strategy to pick
+			// the first or last
+
+			if (!versions.isEmpty()) {
+				Version provider = null;
+
+				switch (useStrategy) {
+				case HIGHEST:
+					provider = versions.lastKey();
+					break;
+
+				case LOWEST:
+					provider = versions.firstKey();
+					break;
+				}
+				if (provider != null) {
+					RepositoryPlugin repo = versions.get(provider);
+					String version = provider.toString();
+					File result = repo.get(bsn, version, Strategy.EXACT, attrs);
+					if (result != null)
+						return toContainer(bsn, version, attrs, result);
+				} else
+					error("Unexpected, found versions %s but then not provider for startegy %s?",
+							versions, useStrategy);
+			}
+		}
+
+		//
+		// If we get this far we ran into an error somewhere
+
+		return new Container(this, bsn, range, Container.TYPE.ERROR, null, bsn + ";version="
+				+ range + " Not found in " + plugins, null);
+
+	}
+
+	/**
+	 * @param attrs
+	 * @param useStrategy
+	 * @return
+	 */
+	protected Strategy overrideStrategy(Map<String, String> attrs, Strategy useStrategy) {
+		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;
+			}
+		}
+		return useStrategy;
+	}
+
+	/**
+	 * @param bsn
+	 * @param range
+	 * @param attrs
+	 * @param result
+	 * @return
+	 */
+	protected Container toContainer(String bsn, String range, Map<String, String> attrs, File result) {
+		File f = result;
+		if (f == null) {
+			error("Result file for toContainer is unexpectedly null, not sure what to do");
+			f = new File("was null");
+		}
+		if (f.getName().endsWith("lib"))
+			return new Container(this, bsn, range, Container.TYPE.LIBRARY, f, null, attrs);
+		else
+			return new Container(this, bsn, range, Container.TYPE.REPO, f, null, attrs);
+	}
+
+	/**
+	 * 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 {
+		Parameters deploy = new Parameters(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 (isNoBundles())
+			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. This is defined as:
+	 * 
+	 */
+	public boolean isStale() throws Exception {
+		// When we do not generate anything ...
+		if (isNoBundles())
+			return false;
+
+		long buildTime = 0;
+
+		files = getBuildFiles(false);
+		if (files == null)
+			return true;
+
+		for (File f : files) {
+			if (f.lastModified() < lastModified())
+				return true;
+
+			if (buildTime < f.lastModified())
+				buildTime = f.lastModified();
+		}
+
+		for (Project dependency : getDependson()) {
+			if (dependency.isStale())
+				return true;
+
+			if (dependency.isNoBundles())
+				continue;
+
+			File[] deps = dependency.getBuildFiles();
+			for (File f : deps) {
+				if (f.lastModified() >= buildTime)
+					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.
+	 * 
+	 * This method remembers the files in the appropriate instance vars.
+	 * 
+	 * @return
+	 */
+
+	public File[] getBuildFiles() throws Exception {
+		return getBuildFiles(true);
+	}
+
+	public File[] getBuildFiles(boolean buildIfAbsent) throws Exception {
+		if (files != null)
+			return files;
+
+		File f = new File(getTarget(), BUILDFILES);
+		if (f.isFile()) {
+			BufferedReader rdr = IO.reader(f);
+			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()) {
+						// Originally we warned the user
+						// but lets just rebuild. That way
+						// the error is not noticed but 
+						// it seems better to correct,
+						// See #154
+						rdr.close();
+						f.delete();
+						break;
+					} else
+						files.add(ff);
+				}
+				return this.files = files.toArray(new File[files.size()]);
+			} finally {
+				rdr.close();
+			}
+		}
+		if (buildIfAbsent)
+			return files = buildLocal(false);
+		else
+			return files = 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 (isNoBundles())
+			return null;
+
+		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
+			Writer fw = IO.writer(bfs);
+			try {
+				for (File f : files) {
+					fw.append(f.getAbsolutePath());
+					fw.append("\n");
+				}
+			} finally {
+				fw.close();
+			}
+			getWorkspace().changedFile(bfs);
+			return files;
+		} else
+			return null;
+	}
+
+	/**
+	 * Answer if this project does not have any output
+	 * 
+	 * @return
+	 */
+	public boolean isNoBundles() {
+		return getProperty(NOBUNDLES) != 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();
+		}
+	}
+
+	public 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);
+
+		Parameters actions = new Parameters(getProperty("-actions", DEFAULT_ACTIONS));
+		for (Entry<String, Attrs> 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);
+			target.mkdirs();
+		}
+		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.err.println("No Errors");
+		} else {
+			if (errors > 0) {
+				System.err.println(errors + " Error(s)");
+
+			} else
+				System.err.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();
+	}
+
+	/**
+	 * Bump the version of this project. First check the main bnd file. If this
+	 * does not contain a version, check the include files. If they still do not
+	 * contain a version, then check ALL the sub builders. If not, add a version
+	 * to the main bnd file.
+	 * 
+	 * @param mask
+	 *            the mask for bumping, see {@link Macro#_version(String[])}
+	 * @throws Exception
+	 */
+	public void bump(String mask) throws Exception {
+		String pattern = "(Bundle-Version\\s*(:|=)\\s*)(([0-9]+(\\.[0-9]+(\\.[0-9]+)?)?))";
+		String replace = "$1${version;" + mask + ";$3}";
+		try {
+			// First try our main bnd file
+			if (replace(getPropertiesFile(), pattern, replace))
+				return;
+
+			trace("no version in bnd.bnd");
+
+			// Try the included filed in reverse order (last has highest
+			// priority)
+			List<File> included = getIncluded();
+			if (included != null) {
+				List<File> copy = new ArrayList<File>(included);
+				Collections.reverse(copy);
+
+				for (File file : copy) {
+					if (replace(file, pattern, replace)) {
+						trace("replaced version in file %s", file);
+						return;
+					}
+				}
+			}
+			trace("no version in included files");
+
+			boolean found = false;
+
+			// Replace in all sub builders.
+			for (Builder sub : getSubBuilders()) {
+				found |= replace(sub.getPropertiesFile(), pattern, replace);
+			}
+
+			if (!found) {
+				trace("no version in sub builders, add it to bnd.bnd");
+				String bndfile = IO.collect(getPropertiesFile());
+				bndfile += "\n# Added by by bump\nBundle-Version: 0.0.0\n";
+				IO.store(bndfile, getPropertiesFile());
+			}
+		} finally {
+			forceRefresh();
+		}
+	}
+
+	boolean replace(File f, String pattern, String replacement) throws IOException {
+		Sed sed = new Sed(getReplacer(), f);
+		sed.replace(pattern, replacement);
+		return sed.doIt() > 0;
+	}
+
+	public void bump() throws Exception {
+		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, "", new Instruction(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() {
+		Parameters hdr = getParameters(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));
+		trace("candidates for tester %s", withDefault);
+
+		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.err.printf("Could not acquire lock for %s, was locked by %s for %s%n", reason,
+					lockingThread, lockingReason);
+			System.err.flush();
+			return false;
+		}
+		this.lockingReason = reason;
+		this.lockingThread = Thread.currentThread();
+		return true;
+	}
+
+	public void unlock() {
+		lockingReason = null;
+		lock.unlock();
+	}
+
+	/**
+	 * 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;
+	}
+
+	/**
+	 * Sets the package version on an exported package
+	 * 
+	 * @param packageName
+	 *            The package name
+	 * @param version
+	 *            The new package version
+	 */
+	public void setPackageInfo(String packageName, Version version) {
+		try {
+			updatePackageInfoFile(packageName, version);
+		} catch (Exception e) {
+			error(e.getMessage(), e);
+		}
+	}
+
+	void updatePackageInfoFile(String packageName, Version newVersion) throws Exception {
+
+		File file = getPackageInfoFile(packageName);
+
+		// If package/classes are copied into the bundle through Private-Package
+		// etc, there will be no source
+		if (!file.getParentFile().exists()) {
+			return;
+		}
+
+		Version oldVersion = getPackageInfo(packageName);
+
+		if (newVersion.compareTo(oldVersion) == 0) {
+			return;
+		} else {
+			PrintWriter pw = IO.writer(file);
+			pw.println("version " + newVersion);
+			pw.flush();
+			pw.close();
+
+			String path = packageName.replace('.', '/') + "/packageinfo";
+			File binary = IO.getFile(getOutput(), path);
+			binary.getParentFile().mkdirs();
+			IO.copy(file, binary);
+
+			refresh();
+		}
+	}
+
+	File getPackageInfoFile(String packageName) throws IOException {
+		String path = packageName.replace('.', '/') + "/packageinfo";
+		return IO.getFile(getSrc(), path);
+
+	}
+
+	public Version getPackageInfo(String packageName) throws IOException {
+		File packageInfoFile = getPackageInfoFile(packageName);
+		if (!packageInfoFile.exists()) {
+			return Version.emptyVersion;
+		}
+		BufferedReader reader = null;
+		try {
+			reader = IO.reader(packageInfoFile);
+			String line;
+			while ((line = reader.readLine()) != null) {
+				line = line.trim();
+				if (line.startsWith("version ")) {
+					return Version.parseVersion(line.substring(8));
+				}
+			}
+		} finally {
+			if (reader != null) {
+				IO.close(reader);
+			}
+		}
+		return Version.emptyVersion;
+	}
+
+	/**
+	 * bnd maintains a class path that is set by the environment, i.e. bnd is
+	 * not in charge of it.
+	 */
+	
+	public void addClasspath( File f) {
+		if ( !f.isFile()) {
+			error("Adding non existent file to the classpath %s", f);
+		}
+		Container container = new Container(f);
+		classpath.add(container);
+	}
+	
+	public void clearClasspath() {
+		classpath.clear();
+	}
+	
+	public Collection<Container> getClasspath() {
+		return classpath;
+	}
+}
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..d00b71b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ProjectBuilder.java
@@ -0,0 +1,77 @@
+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.getClasspath()) {
+                    addClasspath(file.getFile());
+                }
+                
+                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..1b7bac0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ProjectLauncher.java
@@ -0,0 +1,371 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+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.*;
+import aQute.libg.header.*;
+
+/**
+ * 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 List<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 Parameters					runsystempackages;
+	private final List<String>			activators			= Create.list();
+	private File						storageDir;
+	private final List<String>			warnings			= Create.list();
+	private final List<String>			errors				= Create.list();
+
+	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());
+			} else {
+				warning("Bundle file \"%s\" does not exist", file);
+			}
+		}
+
+		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.getParameters(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) {
+						Parameters exports = project.parseHeader(manifest.getMainAttributes()
+								.getValue(Constants.EXPORT_PACKAGE));
+						for (Entry<String, Attrs> 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 List<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);
+
+		try {
+			int result = java.execute((InputStream)null, System.err, System.err);
+			if (result == Integer.MIN_VALUE)
+				return TIMEDOUT;
+			reportResult(result);
+			return result;
+		} finally {
+			cleanup();
+		}
+	}
+
+	/**
+	 * Is called after the process exists. Can you be used to cleanup
+	 * the properties file.
+	 */
+	
+	public void cleanup() {
+		// do nothing by default
+	}
+
+	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.error("Exit code remote process %d: %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, ? extends Map<String, String>> getSystemPackages() {
+		return runsystempackages.asMapMap();
+	}
+
+	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();
+	}
+
+	public void clear() {
+		errors.clear();
+		warnings.clear();
+	}
+
+	public List<String> getErrors() {
+		return Collections.unmodifiableList(errors);
+	}
+
+	public List<String> getWarnings() {
+		return Collections.unmodifiableList(warnings);
+	}
+
+	protected void error(String message, Object... args) {
+		String formatted = String.format(message, args);
+		errors.add(formatted);
+	}
+
+	protected void warning(String message, Object... args) {
+		String formatted = String.format(message, args);
+		warnings.add(formatted);
+	}
+}
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..44a24de
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Workspace.java
@@ -0,0 +1,354 @@
+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.*;
+import aQute.libg.reporter.*;
+
+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 File									buildDir;
+	final Maven									maven		= new Maven(Processor.getExecutor());
+
+	/**
+	 * 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();
+
+	}
+
+	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) {
+				String extensionName = extension.getName();
+				if (extensionName.endsWith(".bnd")) {
+					extensionName = extensionName.substring(0, extensionName.length() - ".bnd".length());
+					try {
+						doIncludeFile(extension, false, getProperties(), "ext." + extensionName);
+					} 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?
+			}
+	}
+
+	
+	/**
+	 * Signal a BndListener plugin.
+	 * We ran an infinite bug loop :-( 
+	 */
+	final ThreadLocal<Reporter> signalBusy = new ThreadLocal<Reporter>();
+	public void signal(Reporter reporter) {
+		if ( signalBusy.get() != null)
+			return;
+		
+		signalBusy.set(reporter);
+		try {
+			List<BndListener> listeners = getPlugins(BndListener.class);
+			for (BndListener l : listeners)
+				try {
+					l.signal(this);
+				} catch (Exception e) {
+					// who cares?
+				}
+		} catch (Exception e) {
+			// Ignore
+		} finally {
+			signalBusy.set(null);
+		}
+	}
+
+	@Override public void signal() {
+		signal(this);
+	}
+
+	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);
+		}
+		
+		public String toString() {
+			return "bnd-cache";
+		}
+
+		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.err.println("!!!! Couldn't find embedded-repo.jar in bundle ");
+						error("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 Collection<Project> getBuildOrder() throws Exception {
+		List<Project> result = new ArrayList<Project>();
+		for (Project project : getAllProjects()) {
+			Collection<Project> dependsOn = project.getDependson();
+			getBuildOrder(dependsOn, result);
+			if (!result.contains(project)) {
+				result.add(project);
+			}
+		}
+		return result;
+	}
+
+	private void getBuildOrder(Collection<Project> dependsOn, List<Project> result) throws Exception {
+		for (Project project : dependsOn) {
+			Collection<Project> subProjects = project.getDependson();
+			for (Project subProject : subProjects) {
+				if (!result.contains(subProject)) {
+					result.add(subProject);
+				}
+			}
+			if (!result.contains(project)) {
+				result.add(project);
+			}
+		}
+	}
+
+	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(new CachedFileRepo());
+	}
+
+}
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..5035fd2
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/packageinfo
@@ -0,0 +1 @@
+version 1.44.0
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..e187f3c
--- /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)
+			this.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..f1f91d1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/compatibility/ParseSignatureBuilder.java
@@ -0,0 +1,119 @@
+package aQute.bnd.compatibility;
+
+import java.io.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Descriptors.TypeRef;
+
+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 Exception {
+		Analyzer analyzer = new Analyzer();
+		Clazz clazz = new Clazz(analyzer, "", null);
+		
+		clazz.parseClassFile(in, new ClassDataCollector() {
+			Scope	s;
+			Scope	enclosing;
+			Scope	declaring;
+
+			@Override
+			public void classBegin(int access, TypeRef name) {
+				s = root.getScope(name.getBinary());
+				s.access = Access.modifier(access);
+				s.kind = Kind.CLASS;
+			}
+
+			@Override
+			public void extendsClass(TypeRef name) {
+//				s.setBase(new GenericType(name));
+			}
+
+			@Override
+			public void implementsInterfaces(TypeRef names[]) {
+				s.setParameterTypes(convert(names));
+			}
+
+			GenericType[] convert(TypeRef names[]) {
+				GenericType tss[] = new GenericType[names.length];
+				for (int i = 0; i < names.length; i++) {
+//					tss[i] = new GenericType(names[i]);
+				}
+				return tss;
+			}
+
+			@Override
+			public void method(Clazz.MethodDef defined) {
+				String descriptor;
+				Kind kind;
+				if (defined.isConstructor()) {
+					descriptor = ":" + defined.getDescriptor();
+					kind = Kind.CONSTRUCTOR;
+				} else {
+					descriptor = defined.getName() + ":" + defined.getDescriptor();
+					kind = Kind.METHOD;
+				}
+				Scope m = s.getScope(descriptor);
+				m.access = Access.modifier(defined.getAccess());
+				m.kind = kind;
+				m.declaring = s;
+				s.add(m);
+			}
+
+			@Override
+			public void field(Clazz.FieldDef defined) {
+				String descriptor = defined.getName() + ":" + defined.getDescriptor();
+				Kind kind = Kind.FIELD;
+				Scope m = s.getScope(descriptor);
+				m.access = Access.modifier(defined.getAccess());
+				m.kind = kind;
+				m.declaring = s;
+				s.add(m);
+			}
+
+			@Override
+			public void classEnd() {
+				if (enclosing != null)
+					s.setEnclosing( enclosing );
+				if (declaring != null)
+					s.setDeclaring( declaring );				
+			}
+
+			@Override
+			public void enclosingMethod(TypeRef cName, String mName, String mDescriptor) {
+				enclosing = root.getScope(cName.getBinary());
+				if (mName != null) {
+					enclosing = enclosing.getScope(Scope.methodIdentity(mName, mDescriptor));
+				}
+			}
+
+			@Override
+			public void innerClass(TypeRef innerClass, TypeRef outerClass, String innerName,
+					int innerClassAccessFlags) {
+				if (outerClass != null && innerClass != null && innerClass.getBinary().equals(s.name))
+					declaring = root.getScope(outerClass.getBinary());
+			}
+		});
+		
+		
+	}
+}
+
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..32ae94f
--- /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..7f22f35
--- /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 name2) {
+		return name2.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..9b31f7f
--- /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.err;
+//
+//		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..2b9ce53
--- /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.
+	 */
+	static 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 {
+		StringBuilder sb = new StringBuilder();
+		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 {
+		StringBuilder sb = new StringBuilder();
+		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 {
+		StringBuilder sb = new StringBuilder();
+		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 {
+		StringBuilder sb = new StringBuilder();
+		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(StringBuilder 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(StringBuilder 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(StringBuilder 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) {
+		StringBuilder sb = new StringBuilder();
+		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(StringBuilder 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(StringBuilder 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(StringBuilder 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..35cec3f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java
@@ -0,0 +1,353 @@
+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.lib.osgi.Clazz.MethodDef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.libg.version.*;
+
+/**
+ * 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
+ */
+public class AnnotationReader extends ClassDataCollector {
+	final static TypeRef[]		EMPTY					= new TypeRef[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				BINDNAME				= Pattern.compile("(set|add|bind)?(.*)");
+	static Pattern				BINDDESCRIPTOR			= Pattern
+																.compile("\\(((L([^;]+);)(Ljava/util/Map;)?|Lorg/osgi/framework/ServiceReference;)\\)V");
+
+	static Pattern				LIFECYCLEDESCRIPTOR		= 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;
+	TypeRef						interfaces[];
+	MethodDef					method;
+	TypeRef						className;
+	Analyzer					analyzer;
+	MultiMap<String, String>	methods					= new MultiMap<String, String>();
+	TypeRef						extendsClass;
+	boolean						inherit;
+	boolean						baseclass				= true;
+
+	AnnotationReader(Analyzer analyzer, Clazz clazz, boolean inherit) {
+		this.analyzer = analyzer;
+		this.clazz = clazz;
+		this.inherit = inherit;
+	}
+
+	public static ComponentDef getDefinition(Clazz c, Analyzer analyzer) throws Exception {
+		boolean inherit = Processor.isTrue(analyzer.getProperty("-dsannotations-inherit"));
+		AnnotationReader r = new AnnotationReader(analyzer, c, inherit);
+		return r.getDef();
+	}
+
+	private ComponentDef getDef() throws Exception {
+		clazz.parseClassFileWithCollector(this);
+		if (component.implementation == null)
+			return null;
+
+		if (inherit) {
+			baseclass = false;
+			while (extendsClass != null) {
+				if (extendsClass.isJava())
+					break;
+
+				Clazz ec = analyzer.findClass(extendsClass);
+				if (ec == null) {
+					analyzer.error("Missing super class for DS annotations: " + extendsClass
+							+ " from " + clazz.getClassName());
+				} else {
+					ec.parseClassFileWithCollector(this);
+				}
+			}
+		}
+		for (ReferenceDef rdef : component.references.values()) {
+			rdef.unbind = referredMethod(analyzer, rdef, rdef.unbind, "add(.*)", "remove$1",
+					"(.*)", "un$1");
+			rdef.updated = referredMethod(analyzer, rdef, rdef.updated, "(add|set|bind)(.*)",
+					"updated$2", "(.*)", "updated$1");
+		}
+		return component;
+	}
+
+	/**
+	 * 
+	 * @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.service.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.service);
+		}
+		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 (!LIFECYCLEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
+			analyzer.error(
+					"Deactivate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+					clazz, method.getDescriptor());
+		else {
+			component.deactivate = method.getName();
+		}
+	}
+
+	/**
+	 * 
+	 */
+	protected void doModified() {
+		if (!LIFECYCLEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
+			analyzer.error(
+					"Modified method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+					clazz, method.getDescriptor());
+		else {
+			component.modified = method.getName();
+		}
+	}
+
+	/**
+	 * @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 = BINDNAME.matcher(method.getName());
+			if ( m.matches() )
+				def.name = m.group(2);
+			else
+				analyzer.error("Invalid name for bind method %s", method.getName());
+		}
+
+		def.unbind = reference.unbind();
+		def.updated = reference.updated();
+		def.bind = method.getName();
+
+		def.service = raw.get("service");
+		if (def.service != null) {
+			def.service = Clazz.objectDescriptorToFQN(def.service);
+		} else {
+			// We have to find the type of the current method to
+			// link it to the referenced service.
+			Matcher m = BINDDESCRIPTOR.matcher(method.getDescriptor().toString());
+			if (m.matches()) {
+				def.service = Descriptors.binaryToFQN(m.group(3));
+			} else
+				throw new IllegalArgumentException(
+						"Cannot detect the type of a Component Reference from the descriptor: "
+								+ method.getDescriptor());
+		}
+
+		// Check if we have a target, this must be a filter
+		def.target = reference.target();
+
+		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.service, "");
+		else
+			component.references.put(def.name, def);
+
+		def.cardinality = reference.cardinality();
+		def.policy = reference.policy();
+		def.policyOption = reference.policyOption();
+	}
+
+	/**
+	 * 
+	 */
+	protected void doActivate() {
+		if (!LIFECYCLEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
+			analyzer.error(
+					"Activate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+					clazz, method.getDescriptor());
+		else {
+			component.activate = method.getName();
+		}
+	}
+
+	/**
+	 * @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.getClassName();
+		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();
+
+		if (annotation.get("configurationPid") != null)
+			component.configurationPid = comp.configurationPid();
+
+		if (annotation.get("xmlns") != null)
+			component.xmlns = comp.xmlns();
+
+		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<TypeRef> result = new ArrayList<TypeRef>();
+				for (int i = 0; i < interfaces.length; i++) {
+					if (!interfaces[i].equals(analyzer.getTypeRef("scala/ScalaObject")))
+						result.add(interfaces[i]);
+				}
+				component.service = result.toArray(EMPTY);
+			}
+		} else {
+			// We have explicit interfaces set
+			component.service = new TypeRef[x.length];
+			for (int i = 0; i < x.length; i++) {
+				String s = (String) x[i];
+				TypeRef ref = analyzer.getTypeRefFromFQN(s);
+				component.service[i] = ref;
+			}
+		}
+
+	}
+
+	/**
+	 * 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, TypeRef name) {
+		className = name;
+	}
+
+	@Override public void implementsInterfaces(TypeRef[] interfaces) {
+		this.interfaces = interfaces;
+	}
+
+	@Override public void method(Clazz.MethodDef method) {
+		int access = method.getAccess();
+
+		if (Modifier.isAbstract(access) || Modifier.isStatic(access))
+			return;
+
+		if (!baseclass && Modifier.isPrivate(access))
+			return;
+
+		this.method = method;
+		methods.add(method.getName(), method.getDescriptor().toString());
+	}
+
+	@Override public void extendsClass(TypeRef 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..75b7b73
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/component/ComponentDef.java
@@ -0,0 +1,208 @@
+package aQute.bnd.component;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.osgi.service.component.annotations.*;
+
+import aQute.lib.collections.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.lib.tag.*;
+import aQute.libg.version.*;
+
+/**
+ * This class just holds the information for the component, implementation, and
+ * service/provide elements. The {@link #prepare(Analyzer)} method will check if
+ * things are ok and the {@link #getTag()} method returns a tag if the prepare
+ * method returns without any errors. The class uses {@link ReferenceDef} to
+ * hold the references.
+ */
+class ComponentDef {
+	final static String				NAMESPACE_STEM	= "http://www.osgi.org/xmlns/scr";
+	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>();
+
+	Version							version			= AnnotationReader.V1_1;
+	String							name;
+	String							factory;
+	Boolean							immediate;
+	Boolean							servicefactory;
+	ConfigurationPolicy				configurationPolicy;
+	TypeRef							implementation;
+	TypeRef							service[];
+	String							activate;
+	String							deactivate;
+	String							modified;
+	Boolean							enabled;
+	String							xmlns;
+	String							configurationPid;
+	List<Tag>						propertyTags	= new ArrayList<Tag>();
+
+	/**
+	 * Called to prepare. If will look for any errors or inconsistencies in the
+	 * setup.
+	 * 
+	 * @param analyzer
+	 *            the analyzer to report errors and create references
+	 * @throws Exception
+	 */
+	void prepare(Analyzer analyzer) throws Exception {
+
+		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);
+			return;
+		}
+
+		analyzer.referTo(implementation);
+
+		if (name == null)
+			name = implementation.getFQN();
+
+		if (service != null && service.length > 0) {
+			for (TypeRef 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");
+
+		if (configurationPid != null)
+			version = ReferenceDef.max(version, AnnotationReader.V1_2);
+
+		for (Map.Entry<String, List<String>> kvs : property.entrySet()) {
+			Tag property = new Tag("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);
+			}
+			if (kvs.getValue().size() == 1) {
+				String value = kvs.getValue().get(0);
+				value = check(type, value, analyzer);
+				property.addAttribute("value", value);
+			} else {
+				StringBuilder sb = new StringBuilder();
+
+				String del = "";
+				for (String v : kvs.getValue()) {
+					sb.append(del);
+					v = check(type, v, analyzer);
+					sb.append(v);
+					del = "\n";
+				}
+				property.addContent(sb.toString());
+			}
+			propertyTags.add(property);
+		}
+	}
+
+	/**
+	 * Returns a tag describing the component element.
+	 * 
+	 * @return a component element
+	 */
+	Tag getTag() {
+		Tag component = new Tag("scr:component");
+		if (xmlns != null)
+			component.addAttribute("xmlns:scr", xmlns);
+		else
+			component.addAttribute("xmlns:scr", NAMESPACE_STEM + "/v" + 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);
+
+		if (configurationPid != null)
+			component.addAttribute("configuration-pid", configurationPid);
+
+		Tag impl = new Tag(component, "implementation");
+		impl.addAttribute("class", implementation.getFQN());
+
+		if (service != null && service.length != 0) {
+			Tag s = new Tag(component, "service");
+			if (servicefactory != null && servicefactory)
+				s.addAttribute("servicefactory", true);
+
+			for (TypeRef ss : service) {
+				Tag provide = new Tag(s, "provide");
+				provide.addAttribute("interface", ss.getFQN());
+			}
+		}
+
+		for (ReferenceDef ref : references.values()) {
+			Tag refTag = ref.getTag();
+			component.addContent(refTag);
+		}
+
+		for (Tag tag : propertyTags)
+			component.addContent(tag);
+
+		for (String entry : properties) {
+			Tag properties = new Tag(component, "properties");
+			properties.addAttribute("entry", entry);
+		}
+		return component;
+	}
+
+	private String check(String type, String v, Analyzer analyzer) {
+		if (type == null)
+			return v;
+
+		try {
+			Class<?> c = Class.forName("java.lang." + type);
+			if (c == String.class)
+				return v;
+
+			v = v.trim();
+			if (c == Character.class)
+				c = Integer.class;
+			Method m = c.getMethod("valueOf", String.class);
+			m.invoke(null, v);
+		} catch (ClassNotFoundException e) {
+			analyzer.error("Invalid data type %s", type);
+		} catch (NoSuchMethodException e) {
+			analyzer.error("Cannot convert data %s to type %s", v, type);
+		} catch (NumberFormatException e) {
+			analyzer.error("Not a valid number %s for %s, %s", v, type, e.getMessage());
+		} catch (Exception e) {
+			analyzer.error("Cannot convert data %s to type %s", v, type);
+		}
+		return v;
+	}
+}
\ 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..e451eb0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/component/DSAnnotations.java
@@ -0,0 +1,52 @@
+package aQute.bnd.component;
+
+import java.util.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.libg.header.*;
+
+/**
+ * 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 {
+		Parameters header = OSGiHeader.parseHeader(analyzer
+				.getProperty("-dsannotations"));
+		if ( header.size()==0)
+			return false;
+		
+		Instructions instructions = new Instructions(header);
+		Set<Clazz> list = new HashSet<Clazz>(analyzer.getClassspace().values());
+		String sc = analyzer.getProperty(Constants.SERVICE_COMPONENT);
+		List<String> names = new ArrayList<String>();
+		if ( sc != null && sc.trim().length() > 0)
+			names.add(sc);
+		
+		for (Iterator<Clazz> i = list.iterator(); i.hasNext();) {
+			for (Instruction instruction : instructions.keySet()) {
+				Clazz c = i.next();
+
+				if (instruction.matches(c.getFQN())) {
+					if (instruction.isNegated())
+						i.remove();
+					else {
+						ComponentDef definition = AnnotationReader.getDefinition(c, analyzer);
+						if (definition != null) {
+							definition.prepare(analyzer);
+							String name = "OSGI-INF/" + definition.name + ".xml";
+							names.add(name);
+							analyzer.getJar().putResource(name,
+									new TagResource(definition.getTag()));
+						}
+					}
+				}
+			}
+		}
+		sc = Processor.append(names.toArray(new String[names.size()]));
+		analyzer.setProperty(Constants.SERVICE_COMPONENT, sc);
+		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..162bdb4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java
@@ -0,0 +1,95 @@
+package aQute.bnd.component;
+
+import org.osgi.service.component.annotations.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.tag.*;
+import aQute.libg.version.*;
+
+/**
+ * Holds the information in the reference element.
+ */
+
+class ReferenceDef {
+	Version					version = AnnotationReader.V1_1;
+	String					name;
+	String					service;
+	ReferenceCardinality	cardinality;
+	ReferencePolicy			policy;
+	ReferencePolicyOption	policyOption;
+	String					target;
+	String					bind;
+	String					unbind;
+	String					updated;
+
+	/**
+	 * Prepare the reference, will check for any errors.
+	 * 
+	 * @param analyzer the analyzer to report errors to.
+	 * @throws Exception 
+	 */
+	public void prepare(Analyzer analyzer) throws Exception {
+		if (name == null)
+			analyzer.error("No name for a reference");
+		
+		if ((updated != null && !updated.equals("-")) || policyOption!= null)
+			version = max(version, AnnotationReader.V1_2);
+
+		if (target != null) {
+			String error = Verifier.validateFilter(target);
+			if ( error != null)
+				analyzer.error("Invalid target filter %s for %s", target, name);
+		}
+
+		if ( service == null)
+			analyzer.error("No interface specified on %s", name);
+		
+	}
+
+	/**
+	 * Calculate the tag.
+	 * 
+	 * @return a tag for the reference element.
+	 */
+	public Tag getTag() {
+		Tag ref = new Tag("reference");
+		ref.addAttribute("name", name);
+		if (cardinality != null)
+			ref.addAttribute("cardinality", cardinality.toString());
+
+		if (policy != null)
+			ref.addAttribute("policy", policy.toString());
+
+		ref.addAttribute("interface", service);
+
+		if (target != null)
+			ref.addAttribute("target", target);
+
+		if (bind != null && !"-".equals(bind))
+			ref.addAttribute("bind", bind);
+
+		if (unbind != null && !"-".equals(unbind))
+			ref.addAttribute("unbind", unbind);
+
+		if (updated != null && !"-".equals(updated)) 
+			ref.addAttribute("updated", updated);
+
+		if ( policyOption != null)
+			ref.addAttribute("policy-option", policyOption.toString());
+		
+		return ref;
+	}
+
+	static <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/differ/Baseline.java b/bundleplugin/src/main/java/aQute/bnd/differ/Baseline.java
new file mode 100644
index 0000000..eee3e27
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/differ/Baseline.java
@@ -0,0 +1,174 @@
+package aQute.bnd.differ;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.bnd.service.diff.*;
+import aQute.bnd.service.diff.Diff.Ignore;
+import aQute.lib.osgi.*;
+import aQute.libg.generics.*;
+import aQute.libg.header.*;
+import aQute.libg.reporter.*;
+import aQute.libg.version.*;
+
+/**
+ * This class maintains
+ * 
+ */
+public class Baseline {
+
+	public static class Info {
+		public String				packageName;
+		public Diff					packageDiff;
+		public Collection<String>	providers;
+		public Map<String, String>	attributes;
+		public Version				newerVersion;
+		public Version				olderVersion;
+		public Version				suggestedVersion;
+		public Version				suggestedIfProviders;
+		public boolean				mismatch;
+		public String				warning="";
+
+	}
+
+	final Differ	differ;
+	final Reporter	bnd;
+
+	public Baseline(Reporter bnd, Differ differ) throws IOException {
+		this.differ = differ;
+		this.bnd = bnd;
+	}
+
+	/**
+	 * This method compares a jar to a baseline jar and returns version
+	 * suggestions if the baseline does not agree with the newer jar. The
+	 * returned set contains all the exported packages.
+	 * 
+	 * @param newer
+	 * @param older
+	 * @return null if ok, otherwise a set of suggested versions for all
+	 *         packages (also the ones that were ok).
+	 * @throws Exception
+	 */
+	public Set<Info> baseline(Jar newer, Jar older, Instructions packageFilters)
+			throws Exception {
+		Tree n = differ.tree(newer);
+		Parameters nExports = getExports(newer);
+		Tree o = differ.tree(older);
+		Parameters oExports = getExports(older);
+		if ( packageFilters == null)
+			packageFilters = new Instructions();
+		
+		return baseline(n, nExports, o, oExports, packageFilters);
+	}
+
+	public Set<Info> baseline(Tree n, Parameters nExports, Tree o,
+			Parameters oExports, Instructions packageFilters)
+			throws Exception {
+		Diff diff = n.diff(o).get("<api>");
+		Set<Info> infos = Create.set();
+
+		for (Diff pdiff : diff.getChildren()) {
+			if (pdiff.getType() != Type.PACKAGE) // Just packages
+				continue;
+
+			if (pdiff.getName().startsWith("java."))
+				continue;
+
+			if (!packageFilters.matches(pdiff.getName()))
+				continue;
+
+			final Info info = new Info();
+			infos.add(info);
+
+			info.packageDiff = pdiff;
+			info.packageName = pdiff.getName();
+			info.attributes = nExports.get(info.packageName);
+			bnd.trace("attrs for %s %s", info.packageName,info.attributes);
+
+			info.newerVersion = getVersion(info.attributes);
+			info.olderVersion = getVersion(oExports.get(info.packageName));
+			if (pdiff.getDelta() == Delta.UNCHANGED) {
+				info.suggestedVersion = info.olderVersion;
+				if( !info.newerVersion.equals(info.olderVersion)) {
+					info.warning += "No difference but versions are equal";
+				}
+			} else if (pdiff.getDelta() == Delta.REMOVED) {
+				info.suggestedVersion = null;
+			} else if (pdiff.getDelta() == Delta.ADDED) {
+				info.suggestedVersion = Version.ONE;
+			} else {
+				// We have an API change
+				info.suggestedVersion = bump(pdiff.getDelta(), info.olderVersion, 1, 0);
+
+				if (info.newerVersion.compareTo(info.suggestedVersion) < 0) {
+					info.mismatch = true; // our suggested version is smaller
+											// than
+											// the
+											// old version!
+
+					// We can fix some major problems by assuming
+					// that an interface is a provider interface
+					if (pdiff.getDelta() == Delta.MAJOR) {
+
+						info.providers = Create.set();
+						if (info.attributes != null)
+							info.providers.addAll(Processor.split(info.attributes
+									.get(Constants.PROVIDER_TYPE_DIRECTIVE)));
+
+						// Calculate the new delta assuming we fix all the major
+						// interfaces
+						// by making them providers
+						Delta tryDelta = pdiff.getDelta(new Ignore() {
+							public boolean contains(Diff diff) {
+								if (diff.getType() == Type.INTERFACE
+										&& diff.getDelta() == Delta.MAJOR) {
+									info.providers.add(Descriptors.getShortName(diff.getName()));
+									return true;
+								}
+								return false;
+							}
+						});
+
+						if (tryDelta != Delta.MAJOR) {
+							info.suggestedIfProviders = bump(tryDelta, info.olderVersion, 1, 0);
+						}
+					}
+				}
+			}
+		}
+		return infos;
+	}
+
+	private Version bump(Delta delta, Version last, int offset, int base) {
+		switch (delta) {
+		case UNCHANGED:
+			return last;
+		case MINOR:
+			return new Version(last.getMajor(), last.getMinor() + offset, base);
+		case MAJOR:
+			return new Version(last.getMajor() + 1, base, base);
+		case ADDED:
+			return last;
+		default:
+			return new Version(last.getMajor(), last.getMinor(), last.getMicro() + offset);
+		}
+	}
+
+	private Version getVersion(Map<String, String> map) {
+		if (map == null)
+			return Version.LOWEST;
+
+		return Version.parseVersion(map.get(Constants.VERSION_ATTRIBUTE));
+	}
+
+	private Parameters getExports(Jar jar) throws Exception {
+		Manifest m = jar.getManifest();
+		if (m == null)
+			return new Parameters();
+
+		return OSGiHeader.parseHeader(m.getMainAttributes().getValue(Constants.EXPORT_PACKAGE));
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/DiffImpl.java b/bundleplugin/src/main/java/aQute/bnd/differ/DiffImpl.java
new file mode 100644
index 0000000..7b675c2
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/differ/DiffImpl.java
@@ -0,0 +1,210 @@
+package aQute.bnd.differ;
+
+import static aQute.bnd.service.diff.Delta.*;
+
+import java.util.*;
+
+import aQute.bnd.service.diff.*;
+
+/**
+ * A DiffImpl class compares a newer Element to an older Element. The Element
+ * classes hide all the low level details. A Element class is either either
+ * Structured (has children) or it is a Leaf, it only has a value. The
+ * constructor will first build its children (if any) and then calculate the
+ * delta. Each comparable element is translated to an Element. If necessary the
+ * Element can be sub classed to provide special behavior.
+ */
+
+public class DiffImpl implements Diff, Comparable<DiffImpl> {
+
+	final Element				older;
+	final Element				newer;
+	final Collection<DiffImpl>	children;
+	final Delta					delta;
+
+	/**
+	 * The transitions table defines how the state is escalated depending on the
+	 * children. horizontally is the current delta and this is indexed with the
+	 * child delta for each child. This escalates deltas from below up.
+	 */
+	final static Delta[][]		TRANSITIONS	= {
+			{ IGNORED, UNCHANGED, CHANGED, MICRO, MINOR, MAJOR }, // IGNORED
+			{ IGNORED, UNCHANGED, CHANGED, MICRO, MINOR, MAJOR }, // UNCHANGED
+			{ IGNORED, CHANGED, CHANGED, MICRO, MINOR, MAJOR }, // CHANGED
+			{ IGNORED, MICRO, MICRO, MICRO, MINOR, MAJOR }, // MICRO
+			{ IGNORED, MINOR, MINOR, MINOR, MINOR, MAJOR }, // MINOR
+			{ IGNORED, MAJOR, MAJOR, MAJOR, MAJOR, MAJOR }, // MAJOR
+			{ IGNORED, MAJOR, MAJOR, MAJOR, MAJOR, MAJOR }, // REMOVED
+			{ IGNORED, MINOR, MINOR, MINOR, MINOR, MAJOR }, // ADDED
+											};
+
+	/**
+	 * Compares the newer against the older, traversing the children if
+	 * necessary.
+	 * 
+	 * @param newer
+	 *            The newer Element
+	 * @param older
+	 *            The older Element
+	 * @param types
+	 */
+	DiffImpl(Element newer, Element older) {
+		assert newer != null || older != null;
+		this.older = older;
+		this.newer = newer;
+
+		// Either newer or older can be null, indicating remove or add
+		// so we have to be very careful.
+		Element[] newerChildren = newer == null ? Element.EMPTY : newer.children;
+		Element[] olderChildren = older == null ? Element.EMPTY : older.children;
+
+		int o = 0;
+		int n = 0;
+		List<DiffImpl> children = new ArrayList<DiffImpl>();
+		while (true) {
+			Element nw = n < newerChildren.length ? newerChildren[n] : null;
+			Element ol = o < olderChildren.length ? olderChildren[o] : null;
+			DiffImpl diff;
+
+			if (nw == null && ol == null)
+				break;
+
+			if (nw != null && ol != null) {
+				// we have both sides
+				int result = nw.compareTo(ol);
+				if (result == 0) {
+					// we have two equal named elements
+					// use normal diff
+					diff = new DiffImpl(nw, ol);
+					n++;
+					o++;
+				} else if (result > 0) {
+					// we newer > older, so there is no newer == removed
+					diff = new DiffImpl(null, ol);
+					o++;
+				} else {
+					// we newer < older, so there is no older == added
+					diff = new DiffImpl(nw, null);
+					n++;
+				}
+			} else {
+				// we reached the end of one of the list
+				diff = new DiffImpl(nw, ol);
+				n++;
+				o++;
+			}
+			children.add(diff);
+		}
+
+		// make sure they're read only
+		this.children = Collections.unmodifiableCollection(children);
+		delta = getDelta(null);
+	}
+
+	/**
+	 * Return the absolute delta. Also see
+	 * {@link #getDelta(aQute.bnd.service.diff.Diff.Ignore)} that allows you to
+	 * ignore Diff objects on the fly (and calculate their parents accordingly).
+	 */
+	public Delta getDelta() {
+		return delta;
+	}
+
+	/**
+	 * This getDelta calculates the delta but allows the caller to ignore
+	 * certain Diff objects by calling back the ignore call back parameter. This
+	 * can be useful to ignore warnings/errors.
+	 */
+
+	public Delta getDelta(Ignore ignore) {
+
+		// If ignored, we just return ignore.
+		if (ignore != null && ignore.contains(this))
+			return IGNORED;
+
+		if (newer == null) {
+			return REMOVED;
+		} else if (older == null) {
+			return ADDED;
+		} else {
+			// now we're sure newer and older are both not null
+			assert newer != null && older != null;
+			assert newer.getClass() == older.getClass();
+
+			Delta local = Delta.UNCHANGED;
+
+			for (DiffImpl child : children) {
+				Delta sub = child.getDelta(ignore);
+				if (sub == REMOVED)
+					sub = child.older.remove;
+				else if (sub == ADDED)
+					sub = child.newer.add;
+
+				// The escalate method is used to calculate the default
+				// transition in the
+				// delta based on the children. In general the delta can
+				// only escalate, i.e.
+				// move up in the chain.
+
+				local = TRANSITIONS[sub.ordinal()][local.ordinal()];
+			}
+			return local;
+		}
+	}
+
+	public Type getType() {
+		return (newer == null ? older : newer).getType();
+	}
+
+	public String getName() {
+		return (newer == null ? older : newer).getName();
+	}
+
+	public Collection<? extends Diff> getChildren() {
+		return children;
+	}
+
+	public String toString() {
+		return String.format("%-10s %-10s %s", getDelta(), getType(), getName());
+	}
+
+	public boolean equals(Object other) {
+		if (other instanceof DiffImpl) {
+			DiffImpl o = (DiffImpl) other;
+			return getDelta() == o.getDelta() && getType() == o.getType()
+					&& getName().equals(o.getName());
+		}
+		return false;
+	}
+
+	public int hashCode() {
+		return getDelta().hashCode() ^ getType().hashCode() ^ getName().hashCode();
+	}
+
+	public int compareTo(DiffImpl other) {
+		if (getDelta() == other.getDelta()) {
+			if (getType() == other.getType()) {
+				return getName().compareTo(other.getName());
+			} else
+				return getType().compareTo(other.getType());
+		} else
+			return getDelta().compareTo(other.getDelta());
+	}
+
+	public Diff get(String name) {
+		for (DiffImpl child : children) {
+			if (child.getName().equals(name))
+				return child;
+		}
+		return null;
+	}
+
+	public Tree getOlder() {
+		return older;
+	}
+
+	public Tree getNewer() {
+		return newer;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/DiffPluginImpl.java b/bundleplugin/src/main/java/aQute/bnd/differ/DiffPluginImpl.java
new file mode 100644
index 0000000..e3a1308
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/differ/DiffPluginImpl.java
@@ -0,0 +1,181 @@
+package aQute.bnd.differ;
+
+import static aQute.bnd.service.diff.Delta.*;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.bnd.service.diff.*;
+import aQute.bnd.service.diff.Tree.Data;
+import aQute.lib.hex.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+import aQute.libg.cryptography.*;
+import aQute.libg.header.*;
+
+
+/**
+ * This Diff Plugin Implementation will compare JARs for their API (based on the
+ * Bundle Class Path and exported packages), the Manifest, and the resources.
+ * The Differences are represented in a {@link Diff} tree.
+ */
+public class DiffPluginImpl implements Differ {
+	
+	/**
+	 * Headers that are considered major enough to parse according to spec and
+	 * compare their constituents
+	 */
+	final static Set<String>				MAJOR_HEADERS	= new TreeSet<String>(
+																	String.CASE_INSENSITIVE_ORDER);
+
+	/**
+	 * Headers that are considered not major enough to be considered
+	 */
+	final static Set<String>				IGNORE_HEADERS	= new TreeSet<String>(
+																	String.CASE_INSENSITIVE_ORDER);
+
+	static {
+		MAJOR_HEADERS.add(Constants.EXPORT_PACKAGE);
+		MAJOR_HEADERS.add(Constants.IMPORT_PACKAGE);
+		MAJOR_HEADERS.add(Constants.REQUIRE_BUNDLE);
+		MAJOR_HEADERS.add(Constants.FRAGMENT_HOST);
+		MAJOR_HEADERS.add(Constants.BUNDLE_SYMBOLICNAME);
+		MAJOR_HEADERS.add(Constants.BUNDLE_LICENSE);
+		MAJOR_HEADERS.add(Constants.BUNDLE_NATIVECODE);
+		MAJOR_HEADERS.add(Constants.BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
+		MAJOR_HEADERS.add(Constants.DYNAMICIMPORT_PACKAGE);
+
+		IGNORE_HEADERS.add(Constants.TOOL);
+		IGNORE_HEADERS.add(Constants.BND_LASTMODIFIED);
+		IGNORE_HEADERS.add(Constants.CREATED_BY);
+	}
+
+	/**
+	 * 
+	 * @see aQute.bnd.service.diff.Differ#diff(aQute.lib.resource.Jar,
+	 *      aQute.lib.resource.Jar)
+	 */
+	public Tree tree(File newer) throws Exception {
+		Jar jnewer = new Jar(newer);
+		try {
+			return tree(jnewer);
+		} finally {
+			jnewer.close();
+		}
+	}
+
+	/**
+	 * 
+	 * @see aQute.bnd.service.diff.Differ#diff(aQute.lib.resource.Jar,
+	 *      aQute.lib.resource.Jar)
+	 */
+	public Tree tree(Jar newer) throws Exception {
+		Analyzer anewer = new Analyzer();
+		try {
+				anewer.setJar(newer);
+				return tree(anewer);
+		} finally {
+			anewer.setJar((Jar) null);
+			anewer.close();
+		}
+	}
+
+	public Tree tree(Analyzer newer) throws Exception {
+		return bundleElement(newer);
+	}
+
+	/**
+	 * Create an element representing a bundle from the Jar.
+	 * 
+	 * @param infos 
+	 * @param jar
+	 *            The Jar to be analyzed
+	 * @return the elements that should be compared
+	 * @throws Exception
+	 */
+	private Element bundleElement(Analyzer analyzer) throws Exception {
+		List<Element> result = new ArrayList<Element>();
+
+		Manifest manifest = analyzer.getJar().getManifest();
+
+		if (manifest != null) {
+			result.add(JavaElement.getAPI(analyzer));
+			result.add(manifestElement(manifest));
+		}
+		result.add(resourcesElement(analyzer.getJar()));
+		return new Element(Type.BUNDLE, analyzer.getJar().getName(), result, CHANGED, CHANGED,
+				null);
+	}
+
+	/**
+	 * Create an element representing all resources in the JAR
+	 * 
+	 * @param jar
+	 * @return
+	 * @throws Exception
+	 */
+	private Element resourcesElement(Jar jar) throws Exception {
+		List<Element> resources = new ArrayList<Element>();
+		for (Map.Entry<String, Resource> entry : jar.getResources().entrySet()) {
+
+			InputStream in = entry.getValue().openInputStream();
+			try {
+				Digester<SHA1> digester = SHA1.getDigester();
+				IO.copy(in, digester);
+				String value = Hex.toHexString(digester.digest().digest());
+				resources
+						.add(new Element(Type.RESOURCE, entry.getKey()+"="+value, null, CHANGED, CHANGED, null));
+			} finally {
+				in.close();
+			}
+		}
+		return new Element(Type.RESOURCES, "<resources>", resources, CHANGED, CHANGED, null);
+	}
+
+
+
+
+	/**
+	 * Create an element for each manifest header. There are
+	 * {@link #IGNORE_HEADERS} and {@link #MAJOR_HEADERS} that will be treated
+	 * differently.
+	 * 
+	 * @param manifest
+	 * @return
+	 */
+
+	private Element manifestElement(Manifest manifest) {
+		List<Element> result = new ArrayList<Element>();
+
+		for (Object key : manifest.getMainAttributes().keySet()) {
+			String header = key.toString();
+			String value = manifest.getMainAttributes().getValue(header);
+			if (IGNORE_HEADERS.contains(header))
+				continue;
+
+			if (MAJOR_HEADERS.contains(header)) {
+				Parameters clauses = OSGiHeader.parseHeader(value);
+				Collection<Element> clausesDef = new ArrayList<Element>();
+				for (Map.Entry<String, Attrs> clause : clauses.entrySet()) {
+					Collection<Element> parameterDef = new ArrayList<Element>();
+					for (Map.Entry<String, String> parameter : clause.getValue().entrySet()) {
+						parameterDef.add(new Element(Type.PARAMETER, parameter.getKey() + ":" + parameter
+								.getValue(), null, CHANGED, CHANGED, null));
+					}
+					clausesDef.add(new Element(Type.CLAUSE, clause.getKey(), parameterDef,
+							CHANGED, CHANGED, null));
+				}
+				result.add(new Element(Type.HEADER, header, clausesDef, CHANGED, CHANGED, null));
+			} else {
+				result.add(new Element(Type.HEADER, header +":"+ value, null,CHANGED, CHANGED, null));
+			}
+		}
+		return new Element(Type.MANIFEST, "<manifest>", result, CHANGED, CHANGED, null);
+	}
+
+	public Tree deserialize(Data data) throws Exception {
+		return new Element(data);
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/Element.java b/bundleplugin/src/main/java/aQute/bnd/differ/Element.java
new file mode 100644
index 0000000..602f95c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/differ/Element.java
@@ -0,0 +1,144 @@
+package aQute.bnd.differ;
+
+import java.util.*;
+
+import aQute.bnd.service.diff.*;
+
+/**
+ * An element can be compared to another element of the same type. Elements with
+ * the same name and same place in the hierarchy should have the same type. The
+ * idea is that for a certain resource type you create an element (Structured or
+ * Leaf). This process is done for the newer and older resource.
+ * <p>
+ * A Leaf type has a value, comparison is rather simple in this case.
+ * <p>
+ * A Structured type has named children. The comparison between the newer and
+ * older child elements is then done on their name. Two elements with the same
+ * name are then matched.
+ * <p>
+ * The classes are prepared for extension but so far it turned out to be
+ * unnecessary.
+ */
+
+class Element implements Comparable<Element>, Tree {
+	final static Element[]	EMPTY	= new Element[0];
+	final Type				type;
+	final String			name;
+	final Delta				add;
+	final Delta				remove;
+	final String			comment;
+	final Element[]			children;
+
+	Element(Type type, String name) {
+		this(type, name, null, Delta.MINOR, Delta.MAJOR, null);
+	}
+
+	Element(Type type, String name, Element... children) {
+		this(type, name, Arrays.asList(children), Delta.MINOR, Delta.MAJOR, null);
+	}
+
+	Element(Type type, String name, Collection<? extends Element> children, Delta add,
+			Delta remove, String comment) {
+		this.type = type;
+		this.name = name;
+		this.add = add;
+		this.remove = remove;
+		this.comment = comment;
+		if (children != null && children.size() > 0) {
+			this.children = children.toArray(new Element[children.size()]);
+			Arrays.sort(this.children);
+		} else
+			this.children = EMPTY;
+	}
+
+	public Element(Data data) {
+		this.name = data.name;
+		this.type = data.type;
+		this.comment = data.comment;
+		this.add = data.add;
+		this.remove = data.rem;
+		if (data.children == null)
+			children = EMPTY;
+		else {
+			this.children = new Element[data.children.length];
+			for (int i = 0; i < children.length; i++)
+				children[i] = new Element(data.children[i]);
+			Arrays.sort(this.children);
+		}
+	}
+	public Data serialize() {
+		Data data = new Data();
+		data.type = this.type;
+		data.name = this.name;
+		data.add = this.add;
+		data.rem = this.remove;
+		data.comment = this.comment;
+		if (children.length != 0) {
+			data.children = new Data[children.length];
+			for (int i = 0; i < children.length; i++) {
+				data.children[i] = children[i].serialize();
+			}
+		}
+		return data;
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	String getComment() {
+		return comment;
+	}
+
+	public int compareTo(Element other) {
+		if (type == other.type)
+			return name.compareTo(other.name);
+		else
+			return type.compareTo(other.type);
+	}
+
+	public boolean equals(Object other) {
+		if (other == null || getClass() != other.getClass())
+			return false;
+
+		return compareTo((Element) other) == 0;
+	}
+
+	public int hashCode() {
+		return type.hashCode() ^ name.hashCode();
+	}
+
+	public Tree[] getChildren() {
+		return children;
+	}
+
+	public Delta ifAdded() {
+		return add;
+	}
+
+	public Delta ifRemoved() {
+		return remove;
+	}
+
+	public Diff diff(Tree older) {
+		return new DiffImpl(this, (Element) older);
+	}
+
+	public Element get(String name) {
+		for (Element e : children) {
+			if (e.name.equals(name))
+				return e;
+		}
+		return null;
+	}
+	
+	public String toString() {
+		return type + " " + name + " (" + add + "/" + remove + ")";
+	}
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/JavaElement.java b/bundleplugin/src/main/java/aQute/bnd/differ/JavaElement.java
new file mode 100644
index 0000000..e9a77a5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/differ/JavaElement.java
@@ -0,0 +1,655 @@
+package aQute.bnd.differ;
+
+import static aQute.bnd.service.diff.Delta.*;
+import static aQute.bnd.service.diff.Type.*;
+import static java.lang.reflect.Modifier.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.atomic.*;
+import java.util.jar.*;
+
+import aQute.bnd.annotation.*;
+import aQute.bnd.service.diff.*;
+import aQute.bnd.service.diff.Type;
+import aQute.lib.collections.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.JAVA;
+import aQute.lib.osgi.Clazz.MethodDef;
+import aQute.lib.osgi.Descriptors.PackageRef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.libg.generics.*;
+import aQute.libg.header.*;
+import aQute.libg.version.Version;
+
+/**
+ * An element that compares the access field in a binary compatible way. This
+ * element is used for classes, methods, constructors, and fields. For that
+ * reason we also included the only method that uses this class as a static
+ * method.
+ * <p>
+ * Packages
+ * <ul>
+ * <li>MAJOR - Remove a public type
+ * <li>MINOR - Add a public class
+ * <li>MINOR - Add an interface
+ * <li>MINOR - Add a method to a class
+ * <li>MINOR - Add a method to a provider interface
+ * <li>MAJOR - Add a method to a consumer interface
+ * <li>MINOR - Add a field
+ * <li>MICRO - Add an annotation to a member
+ * <li>MINOR - Change the value of a constant
+ * <li>MICRO - -abstract
+ * <li>MICRO - -final
+ * <li>MICRO - -protected
+ * <li>MAJOR - +abstract
+ * <li>MAJOR - +final
+ * <li>MAJOR - +protected
+ * </ul>
+ * 
+ */
+
+class JavaElement {
+	final static EnumSet<Type>			INHERITED		= EnumSet.of(FIELD, METHOD, EXTENDS,
+																IMPLEMENTS);
+	private static final Element		PROTECTED		= new Element(ACCESS, "protected", null,
+																MAJOR, MINOR, null);
+	private static final Element		STATIC			= new Element(ACCESS, "static", null,
+																MAJOR, MAJOR, null);
+	private static final Element		ABSTRACT		= new Element(ACCESS, "abstract", null,
+																MAJOR, MINOR, null);
+	private static final Element		FINAL			= new Element(ACCESS, "final", null, MAJOR,
+																MINOR, null);
+	// private static final Element DEPRECATED = new Element(ACCESS,
+	// "deprecated", null,
+	// CHANGED, CHANGED, null);
+
+	final Analyzer						analyzer;
+	final Map<PackageRef, Instructions>	providerMatcher	= Create.map();
+	final Set<TypeRef>					notAccessible	= Create.set();
+	final Map<Object, Element>			cache			= Create.map();
+	MultiMap<PackageRef, //
+	Element>							packages;
+	final MultiMap<TypeRef, //
+	Element>							covariant		= new MultiMap<TypeRef, Element>();
+	final Set<JAVA>						javas			= Create.set();
+	final Packages						exports;
+
+	/**
+	 * Create an element for the API. We take the exported packages and traverse
+	 * those for their classes. If there is no manifest or it does not describe
+	 * a bundle we assume the whole contents is exported.
+	 * 
+	 * @param infos
+	 */
+	JavaElement(Analyzer analyzer) throws Exception {
+		this.analyzer = analyzer;
+
+		Manifest manifest = analyzer.getJar().getManifest();
+		if (manifest != null
+				&& manifest.getMainAttributes().getValue(Constants.BUNDLE_MANIFESTVERSION) != null) {
+			exports = new Packages();
+			for (Map.Entry<String, Attrs> entry : OSGiHeader.parseHeader(
+					manifest.getMainAttributes().getValue(Constants.EXPORT_PACKAGE)).entrySet())
+				exports.put(analyzer.getPackageRef(entry.getKey()), entry.getValue());
+		} else
+			exports = analyzer.getContained();
+		//
+		// We have to gather the -providers and parse them into instructions
+		// so we can efficiently match them during class parsing to find
+		// out who the providers and consumers are
+		//
+
+		for (Entry<PackageRef, Attrs> entry : exports.entrySet()) {
+			String value = entry.getValue().get(Constants.PROVIDER_TYPE_DIRECTIVE);
+			if (value != null) {
+				providerMatcher.put(entry.getKey(), new Instructions(value));
+			}
+		}
+
+		// we now need to gather all the packages but without
+		// creating the packages yet because we do not yet know
+		// which classes are accessible
+
+		packages = new MultiMap<PackageRef, Element>();
+
+		for (Clazz c : analyzer.getClassspace().values()) {
+			if (c.isPublic() || c.isProtected()) {
+				PackageRef packageName = c.getClassName().getPackageRef();
+
+				if (exports.containsKey(packageName)) {
+					Element cdef = classElement(c);
+					packages.add(packageName, cdef);
+				}
+			}
+		}
+
+	}
+
+	static Element getAPI(Analyzer analyzer) throws Exception {
+		analyzer.analyze();
+		JavaElement te = new JavaElement(analyzer);
+		return te.getLocalAPI();
+	}
+
+	private Element getLocalAPI() throws Exception {
+		List<Element> result = new ArrayList<Element>();
+
+		for (Map.Entry<PackageRef, List<Element>> entry : packages.entrySet()) {
+			List<Element> set = entry.getValue();
+			for (Iterator<Element> i = set.iterator(); i.hasNext();) {
+				
+				if (notAccessible.contains( analyzer.getTypeRefFromFQN(i.next().getName())))
+					i.remove();
+				
+			}
+			String version = exports.get(entry.getKey()).get(Constants.VERSION_ATTRIBUTE);
+			if (version != null) {
+				Version v = new Version(version);
+				set.add(new Element(Type.VERSION, v.getWithoutQualifier().toString(), null,
+						IGNORED, IGNORED, null));
+			}
+			Element pd = new Element(Type.PACKAGE, entry.getKey().getFQN(), set, MINOR, MAJOR, null);
+			result.add(pd);
+		}
+
+		for (JAVA java : javas) {
+			result.add(new Element(CLASS_VERSION, java.toString(), null, Delta.CHANGED,
+					Delta.CHANGED, null));
+		}
+
+		return new Element(Type.API, "<api>", result, CHANGED, CHANGED, null);
+	}
+
+	/**
+	 * Calculate the class element. This requires parsing the class file and
+	 * finding all the methods that were added etc. The parsing will take super
+	 * interfaces and super classes into account. For this reason it maintains a
+	 * queue of classes/interfaces to parse.
+	 * 
+	 * @param analyzer
+	 * @param clazz
+	 * @param infos
+	 * @return
+	 * @throws Exception
+	 */
+	Element classElement(final Clazz clazz) throws Exception {
+		Element e = cache.get(clazz);
+		if (e != null)
+			return e;
+
+		final StringBuilder comment = new StringBuilder();
+		final Set<Element> members = new HashSet<Element>();
+		final Set<MethodDef> methods = Create.set();
+		final Set<Clazz.FieldDef> fields = Create.set();
+		final MultiMap<Clazz.Def, Element> annotations = new MultiMap<Clazz.Def, Element>();
+
+		final TypeRef name = clazz.getClassName();
+
+		final String fqn = name.getFQN();
+		final String shortName = name.getShortName();
+
+		// Check if this clazz is actually a provider or not
+		// providers must be listed in the exported package in the
+		// PROVIDER_TYPE directive.
+		Instructions matchers = providerMatcher.get(name.getPackageRef());
+		boolean p = matchers != null && matchers.matches(shortName);
+		final AtomicBoolean provider = new AtomicBoolean(p);
+
+		//
+		// Check if we already had this clazz in the cache
+		//
+
+		Element before = cache.get(clazz); // for super classes
+		if (before != null)
+			return before;
+
+		clazz.parseClassFileWithCollector(new ClassDataCollector() {
+			boolean			memberEnd;
+			Clazz.FieldDef	last;
+
+			@Override public void version(int minor, int major) {
+				javas.add(Clazz.JAVA.getJava(major, minor));
+			}
+
+			@Override public void method(MethodDef defined) {
+				if ((defined.isProtected() || defined.isPublic())) {
+					last = defined;
+					methods.add(defined);
+				} else {
+					last = null;
+				}
+			}
+
+			@Override public void deprecated() {
+				if (memberEnd)
+					clazz.setDeprecated(true);
+				else
+					last.setDeprecated(true);
+			}
+
+			@Override public void field(Clazz.FieldDef defined) {
+				if (defined.isProtected() || defined.isPublic()) {
+					last = defined;
+					fields.add(defined);
+				} else
+					last = null;
+			}
+
+			@Override public void constant(Object o) {
+				if (last != null) {
+					// Must be accessible now
+					last.setConstant(o);
+				}
+			}
+
+			@Override public void extendsClass(TypeRef name) throws Exception {
+				String comment = null;
+				if (!clazz.isInterface())
+					comment = inherit(members, name);
+
+				Clazz c = analyzer.findClass(name);
+				if ((c == null || c.isPublic()) && !name.isObject())
+					members.add(new Element(Type.EXTENDS, name.getFQN(), null, MICRO, MAJOR,
+							comment));
+			}
+
+			@Override public void implementsInterfaces(TypeRef names[]) throws Exception {
+				// TODO is interface reordering important for binary
+				// compatibility??
+
+				for (TypeRef name : names) {
+
+					String comment = null;
+					if (clazz.isInterface() || clazz.isAbstract())
+						comment = inherit(members, name);
+					members.add(new Element(Type.IMPLEMENTS, name.getFQN(), null, MINOR, MAJOR,
+							comment));
+				}
+			}
+
+			/**
+			 * @param members
+			 * @param name
+			 * @param comment
+			 * @return
+			 */
+			Set<Element>	OBJECT	= Create.set();
+
+			public String inherit(final Set<Element> members, TypeRef name) throws Exception {
+				if (name.isObject()) {
+					if (OBJECT.isEmpty()) {
+						Clazz c = analyzer.findClass(name);
+						Element s = classElement(c);
+						for (Element child : s.children) {
+							if (INHERITED.contains(child.type)) {
+								String n = child.getName();
+								if (child.type == METHOD) {
+									if (n.startsWith("<init>")
+											|| "getClass()".equals(child.getName())
+											|| n.startsWith("wait(") || n.startsWith("notify(")
+											|| n.startsWith("notifyAll("))
+										continue;
+								}
+								OBJECT.add(child);
+							}
+						}
+					}
+					members.addAll(OBJECT);
+				} else {
+
+					Clazz c = analyzer.findClass(name);
+					if (c == null) {
+						return "Cannot load " + name;
+					} else {
+						Element s = classElement(c);
+						for (Element child : s.children) {
+							if (INHERITED.contains(child.type) && !child.name.startsWith("<")) {
+								members.add(child);
+							}
+						}
+					}
+				}
+				return null;
+			}
+
+			@Override public void annotation(Annotation annotation) {
+				Collection<Element> properties = Create.set();
+				if (Deprecated.class.getName().equals(annotation.getName().getFQN())) {
+					if (memberEnd)
+						clazz.setDeprecated(true);
+					else
+						last.setDeprecated(true);
+					return;
+				}
+
+				for (String key : annotation.keySet()) {
+					StringBuilder sb = new StringBuilder();
+					sb.append(key);
+					sb.append('=');
+					toString(sb, annotation.get(key));
+
+					properties.add(new Element(Type.PROPERTY, sb.toString(), null, CHANGED,
+							CHANGED, null));
+				}
+
+				if (memberEnd) {
+					members.add(new Element(Type.ANNOTATED, annotation.getName().getFQN(),
+							properties, CHANGED, CHANGED, null));
+					if (ProviderType.class.getName().equals(annotation.getName().getFQN())) {
+						provider.set(true);
+					} else if (ConsumerType.class.getName().equals(annotation.getName().getFQN())) {
+						provider.set(false);
+					}
+				} else if (last != null)
+					annotations.add(last, new Element(Type.ANNOTATED,
+							annotation.getName().getFQN(), properties, CHANGED, CHANGED, null));
+			}
+
+			private void toString(StringBuilder sb, Object object) {
+
+				if (object.getClass().isArray()) {
+					sb.append('[');
+					int l = Array.getLength(object);
+					for (int i = 0; i < l; i++)
+						toString(sb, Array.get(object, i));
+					sb.append(']');
+				} else
+					sb.append(object);
+			}
+
+			@Override public void innerClass(TypeRef innerClass, TypeRef outerClass,
+					String innerName, int innerClassAccessFlags) throws Exception {
+				Clazz clazz = analyzer.findClass(innerClass);
+				if (clazz != null)
+					clazz.setInnerAccess(innerClassAccessFlags);
+
+				if (Modifier.isProtected(innerClassAccessFlags)
+						|| Modifier.isPublic(innerClassAccessFlags))
+					return;
+				notAccessible.add(innerClass);
+			}
+
+			@Override public void memberEnd() {
+				memberEnd = true;
+			}
+		});
+
+		// This is the heart of the semantic versioning. If we
+		// add or remove a method from an interface then
+		Delta add;
+		Delta remove;
+		Type type;
+
+		// Calculate the type of the clazz. A class
+		// can be an interface, class, enum, or annotation
+
+		if (clazz.isInterface())
+			if (clazz.isAnnotation())
+				type = Type.INTERFACE;
+			else
+				type = Type.ANNOTATION;
+		else if (clazz.isEnum())
+			type = Type.ENUM;
+		else
+			type = Type.CLASS;
+
+		if (type == Type.INTERFACE) {
+			if (provider.get()) {
+				// Adding a method for a provider is not an issue
+				// because it must be aware of the changes
+				add = MINOR;
+
+				// Removing a method influences consumers since they
+				// tend to call this guy.
+				remove = MAJOR;
+			} else {
+				// Adding a method is a major change
+				// because the consumer has to implement it
+				// or the provider will call a non existent
+				// method on the consumer
+				add = MAJOR;
+
+				// Removing a method is not an issue because the
+				// provider, which calls this contract must be
+				// aware of the removal
+
+				remove = MINOR;
+			}
+		} else {
+			// Adding a method to a class can never do any harm
+			add = MINOR;
+
+			// Removing it will likely hurt consumers
+			remove = MAJOR;
+		}
+
+		// Remove all synthetic methods, we need
+		// to treat them special for the covariant returns
+
+		Set<MethodDef> synthetic = Create.set();
+		for (Iterator<MethodDef> i = methods.iterator(); i.hasNext();) {
+			MethodDef m = i.next();
+			if (m.isSynthetic()) {
+				synthetic.add(m);
+				i.remove();
+			}
+		}
+
+		for (MethodDef m : methods) {
+			List<Element> children = annotations.get(m);
+			if (children == null)
+				children = new ArrayList<Element>();
+
+			access(children, m.getAccess(), m.isDeprecated());
+
+			// A final class cannot be extended, ergo,
+			// all methods defined in it are by definition
+			// final. However, marking them final (either
+			// on the method or inheriting it from the class)
+			// will create superfluous changes if we
+			// override a method from a super class that was not
+			// final. So we actually remove the final for methods
+			// in a final class.
+			if (clazz.isFinal())
+				children.remove(FINAL);
+
+			// for covariant types we need to add the return types
+			// and all the implemented and extended types. This is already
+			// do for us when we get the element of the return type.
+
+			getCovariantReturns(children, m.getType());
+
+			for (Iterator<MethodDef> i = synthetic.iterator(); i.hasNext();) {
+				MethodDef s = i.next();
+				if (s.getName().equals(m.getName())
+						&& Arrays.equals(s.getPrototype(), m.getPrototype())) {
+					i.remove();
+					getCovariantReturns(children, s.getType());
+				}
+			}
+
+			Element member = new Element(Type.METHOD, m.getName() + toString(m.getPrototype()),
+					children, add, remove, null);
+
+			if (!members.add(member)) {
+				members.remove(member);
+				members.add(member);
+			}
+		}
+
+		/**
+		 * Repeat for the remaining synthetic methods
+		 */
+		for (MethodDef m : synthetic) {
+			List<Element> children = annotations.get(m);
+			if (children == null)
+				children = new ArrayList<Element>();
+			access(children, m.getAccess(), m.isDeprecated());
+
+			// A final class cannot be extended, ergo,
+			// all methods defined in it are by definition
+			// final. However, marking them final (either
+			// on the method or inheriting it from the class)
+			// will create superfluous changes if we
+			// override a method from a super class that was not
+			// final. So we actually remove the final for methods
+			// in a final class.
+			if (clazz.isFinal())
+				children.remove(FINAL);
+
+			// for covariant types we need to add the return types
+			// and all the implemented and extended types. This is already
+			// do for us when we get the element of the return type.
+
+			getCovariantReturns(children, m.getType());
+
+			Element member = new Element(Type.METHOD, m.getName() + toString(m.getPrototype()),
+					children, add, remove, "synthetic");
+
+			if (!members.add(member)) {
+				members.remove(member);
+				members.add(member);
+			}
+		}
+
+		for (Clazz.FieldDef f : fields) {
+			List<Element> children = annotations.get(f);
+			if (children == null)
+				children = new ArrayList<Element>();
+
+			// Fields can have a constant value, this is a new element
+			if (f.getConstant() != null) {
+				children.add(new Element(Type.CONSTANT, f.getConstant().toString(), null, CHANGED,
+						CHANGED, null));
+			}
+
+			access(children, f.getAccess(), f.isDeprecated());
+			Element member = new Element(Type.FIELD, f.getType().getFQN() + " " + f.getName(),
+					children, MINOR, MAJOR, null);
+
+			if (!members.add(member)) {
+				members.remove(member);
+				members.add(member);
+			}
+		}
+
+		access(members, clazz.getAccess(), clazz.isDeprecated());
+
+		// And make the result
+		Element s = new Element(type, fqn, members, MINOR, MAJOR, comment.length() == 0 ? null
+				: comment.toString());
+		cache.put(clazz, s);
+		return s;
+	}
+
+	private String toString(TypeRef[] prototype) {
+		StringBuilder sb = new StringBuilder();
+		sb.append("(");
+		String del = "";
+		for (TypeRef ref : prototype) {
+			sb.append(del);
+			sb.append(ref.getFQN());
+			del = ",";
+		}
+		sb.append(")");
+		return sb.toString();
+	}
+
+	static Element	BOOLEAN_R	= new Element(RETURN, "boolean");
+	static Element	BYTE_R		= new Element(RETURN, "byte");
+	static Element	SHORT_R		= new Element(RETURN, "short");
+	static Element	CHAR_R		= new Element(RETURN, "char");
+	static Element	INT_R		= new Element(RETURN, "int");
+	static Element	LONG_R		= new Element(RETURN, "long");
+	static Element	FLOAT_R		= new Element(RETURN, "float");
+	static Element	DOUBLE_R	= new Element(RETURN, "double");
+
+	private void getCovariantReturns(Collection<Element> elements, TypeRef type) throws Exception {
+		if (type == null || type.isObject())
+			return;
+
+		if (type.isPrimitive()) {
+			if (type.getFQN().equals("void"))
+				return;
+
+			String name = type.getBinary();
+			Element e;
+			switch (name.charAt(0)) {
+			case 'Z':
+				e = BOOLEAN_R;
+				break;
+			case 'S':
+				e = SHORT_R;
+				break;
+			case 'I':
+				e = INT_R;
+				break;
+			case 'B':
+				e = BYTE_R;
+				break;
+			case 'C':
+				e = CHAR_R;
+				break;
+			case 'J':
+				e = LONG_R;
+				break;
+			case 'F':
+				e = FLOAT_R;
+				break;
+			case 'D':
+				e = DOUBLE_R;
+				break;
+
+			default:
+				throw new IllegalArgumentException("Unknown primitive " + type);
+			}
+			elements.add(e);
+			return;
+		}
+
+		List<Element> set = covariant.get(type);
+		if (set != null) {
+			elements.addAll(set);
+			return;
+		}
+
+		Element current = new Element(RETURN, type.getFQN());
+		Clazz clazz = analyzer.findClass(type);
+		if (clazz == null) {
+			elements.add(current);
+			return;
+		}
+
+		set = Create.list();
+		set.add(current);
+		getCovariantReturns(set, clazz.getSuper());
+
+		TypeRef[] interfaces = clazz.getInterfaces();
+		if (interfaces != null)
+			for (TypeRef intf : interfaces) {
+				getCovariantReturns(set, intf);
+			}
+
+		covariant.put(type, set);
+		elements.addAll(set);
+	}
+
+	private static void access(Collection<Element> children, int access, boolean deprecated) {
+		if (!isPublic(access))
+			children.add(PROTECTED);
+		if (isAbstract(access))
+			children.add(ABSTRACT);
+		if (isFinal(access))
+			children.add(FINAL);
+		if (isStatic(access))
+			children.add(STATIC);
+
+		// Ignore for now
+		// if (deprecated)
+		// children.add(DEPRECATED);
+
+	}
+
+}
\ No newline at end of file
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/changed.txt b/bundleplugin/src/main/java/aQute/bnd/help/changed.txt
new file mode 100644
index 0000000..14d0bd2
--- /dev/null
+++ b/bundleplugin/src/main/java/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/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/help/syntax.properties b/bundleplugin/src/main/java/aQute/bnd/help/syntax.properties
new file mode 100644
index 0000000..14ec642
--- /dev/null
+++ b/bundleplugin/src/main/java/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/java/aQute/bnd/help/syntax.xml b/bundleplugin/src/main/java/aQute/bnd/help/syntax.xml
new file mode 100644
index 0000000..e81df31
--- /dev/null
+++ b/bundleplugin/src/main/java/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/java/aQute/bnd/make/Make.java b/bundleplugin/src/main/java/aQute/bnd/make/Make.java
new file mode 100644
index 0000000..2b0ce8a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/Make.java
@@ -0,0 +1,97 @@
+package aQute.bnd.make;
+
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.libg.header.*;
+
+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) {
+		StringBuilder sb = new StringBuilder();
+		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);
+		Parameters make = builder.parseHeader(s);
+		
+		for (Entry<String, Attrs> entry : make.entrySet()) {
+			String pattern = Processor.removeDuplicateMarker(entry.getKey());
+
+			Instruction instr = new Instruction(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..581deb7
--- /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 = argumentsOnMake.get("type");
+        if (!"bnd".equals(type))
+            return null;
+
+        String recipe = 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, 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..e06cdc5f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java
@@ -0,0 +1,173 @@
+package aQute.bnd.make.calltree;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.MethodDef;
+
+/**
+ * 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.err.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>>(COMPARATOR);
+        final Map<Clazz.MethodDef, Set<Clazz.MethodDef>> usedby = new TreeMap<Clazz.MethodDef, Set<Clazz.MethodDef>>(COMPARATOR);
+
+        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
+     */
+    static Comparator<Clazz.MethodDef> COMPARATOR = new Comparator<Clazz.MethodDef>() {
+		
+		public int compare(MethodDef a, MethodDef b) {
+			int r =a.getName().compareTo(b.getName()); 
+			return  r != 0 ? r : a.getDescriptor().toString().compareTo(b.getDescriptor().toString());
+		}
+	};
+    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>(COMPARATOR));
+        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.getContainingClass().getFQN() + "'"
+                + getAccess(source.getAccess()) + 
+                ( source.isConstructor() ? "" :  " name='" + source.getName() + "'") + " descriptor='" + source.getDescriptor() + "' pretty='"
+                + source.toString() + "'" + 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..1a586b4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java
@@ -0,0 +1,351 @@
+package aQute.bnd.make.component;
+
+import static aQute.lib.osgi.Constants.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.annotation.component.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.MethodDef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+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");
+
+	static String[]				ACTIVATE_ARGUMENTS		= {
+		"org.osgi.service.component.ComponentContext", "org.osgi.framework.BundleContext",
+		Map.class.getName(), "org.osgi.framework.BundleContext" };
+	static String[]				OLD_ACTIVATE_ARGUMENTS	= { "org.osgi.service.component.ComponentContext" };
+	
+	Reporter					reporter				= new Processor();
+	MethodDef					method;
+	TypeRef						className;
+	Clazz						clazz;
+	TypeRef						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) {
+		String fqn = annotation.getName().getFQN();
+		
+		if (fqn.equals(Component.class.getName())) {
+			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].getBinary().equals("scala/ScalaObject"))
+							result.add(interfaces[i].getFQN());
+					}
+					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 (fqn.equals(Activate.class.getName())) {
+			if (!checkMethod())
+				setVersion(V1_1);
+
+			// TODO ... use the new descriptor to do better check
+
+			if (!ACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
+				reporter.error(
+						"Activate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+						className, method.getDescriptor());
+
+			if (method.getName().equals("activate")
+					&& OLDACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches()) {
+				// this is the default!
+			} else {
+				setVersion(V1_1);
+				set(COMPONENT_ACTIVATE, method, "<>");
+			}
+
+		} else if (fqn.equals(Deactivate.class.getName())) {
+			if (!checkMethod())
+				setVersion(V1_1);
+
+			if (!ACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches())
+				reporter.error(
+						"Deactivate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
+						className, method.getDescriptor());
+			if (method.getName().equals("deactivate")
+					&& OLDACTIVATEDESCRIPTOR.matcher(method.getDescriptor().toString()).matches()) {
+				// This is the default!
+			} else {
+				setVersion(V1_1);
+				set(COMPONENT_DEACTIVATE, method, "<>");
+			}
+		} else if (fqn.equals(Modified.class.getName())) {
+			set(COMPONENT_MODIFIED, method, "<>");
+			setVersion(V1_1);
+		} else if (fqn.equals(Reference.class.getName())) {
+
+			String name = (String) annotation.get(Reference.class.getName());
+			String bind = method.getName();
+			String unbind = null;
+
+			if (name == null) {
+				Matcher m = BINDMETHOD.matcher(method.getName());
+				if (m.matches()) {
+					name = m.group(2).toLowerCase() + m.group(3);
+				} else {
+					name = method.getName().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(method.getDescriptor().toString());
+				if (m.matches()) {
+					service = Descriptors.binaryToFQN(m.group(1));
+				} else
+					throw new IllegalArgumentException(
+							"Cannot detect the type of a Component Reference from the descriptor: "
+									+ method.getDescriptor());
+			}
+
+			// 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(method.getDescriptor().toString()).matches()
+					|| !OLDBINDDESCRIPTOR.matcher(method.getDescriptor().toString()).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(method.getAccess()) || Modifier.isProtected(method.getAccess());
+	}
+
+	static Pattern	PROPERTY_PATTERN	= Pattern.compile("[^=]+=.+");
+
+	private void doProperties(aQute.lib.osgi.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, TypeRef name) {
+		className = name;
+	}
+
+	@Override public void implementsInterfaces(TypeRef[] interfaces) {
+		this.interfaces = interfaces;
+	}
+
+	@Override public void method(Clazz.MethodDef method) {
+		this.method = method;
+		descriptors.add(method.getName());
+	}
+
+	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..1e5989f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java
@@ -0,0 +1,626 @@
+package aQute.bnd.make.component;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+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.QUERY;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.libg.header.*;
+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 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);
+			Parameters sc = parseHeader(header);
+
+			for (Entry<String, Attrs> 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.ANNOTATED.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);
+
+			TypeRef implRef = analyzer.getTypeRefFromFQN(impl);
+			// Check if such a class exists
+			analyzer.referTo(implRef);
+
+			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)) {
+				TypeRef ref = analyzer.getTypeRefFromFQN(c);
+				Clazz clazz = analyzer.getClassspace().get(ref);
+				if (clazz != null) {
+					analyzer.referTo(ref);
+					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();
+					TypeRef ref = analyzer.getTypeRefFromFQN(interfaceName);
+					pw.println("    <provide interface='" + interfaceName + "'/>");
+					analyzer.referTo(ref);
+
+					// 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);
+				}
+				TypeRef ref = analyzer.getTypeRefFromFQN(interfaceName);
+				analyzer.referTo(ref);
+
+				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) {
+		StringBuilder sb = new StringBuilder();
+		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..020b85a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java
@@ -0,0 +1,99 @@
+package aQute.bnd.make.coverage;
+
+import java.io.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.MethodDef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+
+/**
+ * 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(TypeRef names[]) {
+                    MethodDef def = clazz.getMethodDef(0,
+                            "<implements>", "()V");
+                    // TODO
+                    for (TypeRef interfaceName : names) {
+                        for (Map.Entry<MethodDef, List<MethodDef>> entry : catalog
+                                .entrySet()) {
+                            String catalogClass = entry.getKey().getContainingClass().getFQN();
+                            List<MethodDef> references = entry.getValue();
+
+                            if (catalogClass.equals(interfaceName.getFQN())) {
+                                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>>(new Comparator<MethodDef>() {
+			public int compare(MethodDef a, MethodDef b) {
+				return a.getName().compareTo(b.getName());
+			}
+		});
+        for (final Clazz clazz : sources) {
+            clazz.parseClassFileWithCollector(new ClassDataCollector() {
+
+                public boolean classStart(int access, TypeRef name) {
+                    return clazz.isPublic();
+                }
+
+                public void method(MethodDef source) {
+                    if (source.isPublic()
+                            || source.isProtected())
+                        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..d879e53
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/coverage/CoverageResource.java
@@ -0,0 +1,91 @@
+package aQute.bnd.make.coverage;
+
+import static aQute.bnd.make.coverage.Coverage.*;
+
+import java.io.*;
+import java.util.*;
+
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.MethodDef;
+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().getContainingClass().getFQN();
+            if (!className.equals(currentClass)) {
+                classTag = new Tag("class");
+                classTag.addAttribute("name", className);
+                classTag.addAttribute("package", Descriptors.getPackage(className));
+                classTag.addAttribute("short", Descriptors.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.toString());
+        if (method.isPublic())
+            tag.addAttribute("public", true);
+        if (method.isStatic())
+            tag.addAttribute("static", true);
+        if (method.isProtected())
+            tag.addAttribute("protected", true);
+        if (method.isInterface())
+            tag.addAttribute("interface", true);
+        tag.addAttribute("constructor", method.isConstructor());
+        if (!method.isConstructor())
+            tag.addAttribute("name", method.getName());
+        tag.addAttribute("descriptor", method.getDescriptor());
+        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..ae541d6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/metatype/MetaTypeReader.java
@@ -0,0 +1,319 @@
+package aQute.bnd.make.metatype;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.bnd.annotation.metatype.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Clazz.MethodDef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.lib.tag.*;
+import aQute.libg.generics.*;
+
+public class MetaTypeReader extends WriteResource {
+	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;
+	}
+
+	/**
+	 * @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.getGenericReturnType();
+		String id = Configurable.mangleMethodName(method.getName());
+		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.getClassName().getFQN(), method.getName(), method.getType().getFQN());
+			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;
+
+		TypeRef typeRef = reporter.getTypeRefFromFQN(rtype);
+		Clazz c = reporter.findClass(typeRef);
+		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.getName());
+				}
+			}
+		});
+		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;
+	}
+
+	class Find extends ClassDataCollector {
+		
+		@Override public void method(MethodDef mdef) {
+			method = mdef;
+			methods.put(mdef, null);
+		}
+		
+		@Override 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) {
+					MetaTypeReader.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();
+			}
+		}
+
+	}
+	
+
+
+	public void write(OutputStream out) throws IOException {
+		try {
+			finish();
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
+		pw.println("<?xml version='1.0'?>");
+		metadata.print(0, pw);
+		pw.flush();
+	}
+
+	void finish() throws Exception {
+		if (!finished) {
+			finished = true;
+			clazz.parseClassFileWithCollector(new Find());
+			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.getClassName().getFQN();
+			String name = Clazz.unCamel(clazz.getClassName().getShortName());
+			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;
+	}
+
+	@Override public long lastModified() {
+		return 0;
+	}
+}
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..ff43613
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/make/metatype/MetatypePlugin.java
@@ -0,0 +1,36 @@
+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.QUERY;
+import aQute.libg.header.*;
+
+/**
+ * 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 {
+
+		Parameters map = analyzer.parseHeader(analyzer
+				.getProperty(Constants.METATYPE));
+
+		Jar jar = analyzer.getJar();
+		for (String name : map.keySet()) {
+			Collection<Clazz> metatypes = analyzer.getClasses("", QUERY.ANNOTATED.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..e9cbfc3
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenCommand.java
@@ -0,0 +1,618 @@
+package aQute.bnd.maven;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.bnd.maven.support.*;
+import aQute.bnd.maven.support.Pom.Scope;
+import aQute.bnd.settings.*;
+import aQute.lib.collections.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Descriptors.PackageRef;
+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;
+		}
+		LineCollection lc = new LineCollection(IO.reader(settings));
+		while (lc.hasNext()) {
+			System.err.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 = null;
+				try {
+					in = new FileInputStream(args[i++]);
+					properties.load(in);
+				} catch (Exception e) {
+				} finally {
+					if (in != null) {
+						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.err.println(command);
+		StringBuilder stdout = new StringBuilder();
+		StringBuilder stderr = new StringBuilder();
+		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);
+		}
+
+		StringBuilder out = new StringBuilder();
+		StringBuilder err = new StringBuilder();
+
+		System.err.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) {
+		Parameters map = Processor.parseHeader(
+				attr.getValue(Constants.BUNDLE_LICENSE), null);
+		if (map.isEmpty())
+			return null;
+
+		StringBuilder sb = new StringBuilder();
+		String sep = "Licensed under ";
+		for (Entry<String, Attrs> 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.err;
+		
+		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.err.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 = IO.writer(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.err.printf( "%20s %-20s %10s%n", dep.getGroupId(), dep.getArtifactId(), dep.getVersion());
+					a.addClasspath(dep.getArtifact());
+				}
+				pw.println(a.getClasspath());
+				a.build();
+
+				TreeSet<PackageRef> sorted = new TreeSet<PackageRef>( a.getImports().keySet());
+				for ( PackageRef 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.err.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..52d2708
--- /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..ce936e7
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenDeploy.java
@@ -0,0 +1,187 @@
+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.header.*;
+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 {
+		Parameters 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);
+				Parameters 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());
+
+		StringBuilder stdout = new StringBuilder();
+		StringBuilder stderr = new StringBuilder();
+
+		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);
+		}
+
+		StringBuilder out = new StringBuilder();
+		StringBuilder err = new StringBuilder();
+		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..bbd233f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenDeployCmd.java
@@ -0,0 +1,223 @@
+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.header.*;
+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;
+		}
+
+		/* skip first argument */
+		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 {
+		Parameters 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);
+				Parameters 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());
+
+		StringBuilder stdout = new StringBuilder();
+		StringBuilder stderr = new StringBuilder();
+
+		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);
+		}
+
+		StringBuilder out = new StringBuilder();
+		StringBuilder err = new StringBuilder();
+		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..a5ad200
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenRepository.java
@@ -0,0 +1,200 @@
+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 final 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 ) {
+			String version = f.getParentFile().getName();
+			version = Builder.cleanupVersion(version);
+			Version v = new Version( version );
+			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 = 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;
+	}
+
+	public String getLocation() {
+		return root.toString();
+	}
+}
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..5b8c149
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java
@@ -0,0 +1,250 @@
+package aQute.bnd.maven;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+import aQute.lib.tag.*;
+import aQute.libg.header.*;
+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 = IO.writer(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");
+
+			Parameters map = Processor.parseHeader(licenses, null);
+			for (Iterator<Entry<String, Attrs>> 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>
+
+				Entry<String, Attrs> 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 = 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..416062d
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/PomResource.java
@@ -0,0 +1,162 @@
+package aQute.bnd.maven;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+import aQute.lib.tag.*;
+import aQute.libg.header.*;
+
+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 = IO.writer(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");
+
+			Parameters map = Processor.parseHeader(licenses, null);
+			for (Iterator<Entry<String, Attrs>> 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>
+
+				Entry<String, Attrs> 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 = 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..60ebb63
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenEntry.java
@@ -0,0 +1,341 @@
+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.err.println("Downloading "  + repo + " path " + path + " url " + url);
+			File file = new File(root, path);
+			IO.copy(url.openStream(), file);
+			System.err.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()) {
+				FileInputStream in = null;
+				try {
+					in = new FileInputStream(props);
+					properties.load(in);
+				} catch (Exception e) {
+					// we ignore for now, will handle it on safe
+				} finally {
+					IO.close(in);
+				}
+			}
+		}
+		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.err.println("Verified ok " + actualFile + " digest " + algorithm);
+				return true;
+			}
+		}
+		System.err.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..a9f0ba2
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenRemoteRepository.java
@@ -0,0 +1,137 @@
+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;
+	}
+
+	public String getLocation() {
+		if ( repositories == null || repositories.length==0)
+			return "maven central";
+		
+		return Arrays.toString(repositories); 
+	}
+}
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..30a3378
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/Pom.java
@@ -0,0 +1,351 @@
+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.*;
+
+import aQute.lib.io.*;
+
+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>();
+	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.err.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;
+	}
+
+	static 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.err.println("Cannot find " + dep + " from "
+									+ rover.previous.dependency);
+						else
+							System.err.println("Cannot find " + dep + " from top");
+				} catch (Exception e) {
+					if (rover.previous != null)
+						System.err.println("Cannot find " + dep + " from "
+								+ rover.previous.dependency);
+					else
+						System.err.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.err.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 = IO.writer(file);
+		try {
+			doEntry(writer, this);
+			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..069acb9
--- /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.err.print(indent);
+//		System.err.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;
+	
+	}
+
+	static 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.err.println("Replce: " + in);
+		if ( in == null) {
+			System.err.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..312825e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/repo/eclipse/EclipseRepo.java
@@ -0,0 +1,205 @@
+package aQute.bnd.repo.eclipse;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.jar.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.*;
+import aQute.libg.generics.*;
+import aQute.libg.header.*;
+import aQute.libg.reporter.*;
+import aQute.libg.version.*;
+
+public class EclipseRepo implements Plugin, RepositoryPlugin {
+    File                             root;
+    Reporter                         reporter;
+    String                           name;
+    Parameters index;
+
+    public final static String             LOCATION = "location";
+    public final static String             NAME     = "name";
+
+    public void setProperties(Map<String, String> map) {
+        String location = 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 = map.get(NAME);
+
+        try {
+            index = buildIndex();
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "Could not build index for eclipse repo: " + root);
+        }
+    }
+
+    Parameters 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()) {
+
+                    Parameters 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 = IO.reader(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, ? extends Map<String, String>> map)
+            throws Exception {
+        String s = Processor.printClauses(map);
+        index.getParentFile().mkdirs();
+        PrintWriter fw = IO.writer(index);
+        try {
+            fw.write(s);
+        } finally {
+            fw.close();
+        }
+    }
+
+    private Parameters buildIndex(File[] plugins) {
+        Parameters map = new Parameters();
+        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 (Entry<String, String> entry : instances.entrySet()) {
+            if (r.includes(new Version(entry.getKey()))) {
+                File f = new File(entry.getValue());
+                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 = new Instruction(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;
+	}
+
+	public String getLocation() {
+		return root.toString();
+	}
+}
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..e937110
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/BndListener.java
@@ -0,0 +1,23 @@
+package aQute.bnd.service;
+
+import java.io.*;
+import java.util.concurrent.atomic.*;
+
+import aQute.libg.reporter.*;
+
+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;
+    }
+    
+    public void signal(Reporter reporter) {
+    	
+    }
+}
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/IndexProvider.java b/bundleplugin/src/main/java/aQute/bnd/service/IndexProvider.java
new file mode 100644
index 0000000..5454c2d
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/IndexProvider.java
@@ -0,0 +1,13 @@
+package aQute.bnd.service;
+
+import java.net.URL;
+import java.util.List;
+import java.util.Set;
+
+public interface IndexProvider {
+
+	List<URL> getIndexLocations() throws Exception;
+
+	Set<ResolutionPhase> getSupportedPhases();
+
+}
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..9ba5b04
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/OBRIndexProvider.java
@@ -0,0 +1,11 @@
+package aQute.bnd.service;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+@Deprecated
+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..78f9801
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/OBRResolutionMode.java
@@ -0,0 +1,6 @@
+package aQute.bnd.service;
+
+@Deprecated
+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 100755
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..e441a4c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/RemoteRepositoryPlugin.java
@@ -0,0 +1,20 @@
+package aQute.bnd.service;
+
+import java.io.*;
+import java.util.*;
+
+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;
+	
+	File getCacheDirectory();
+}
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..13899f7
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/RepositoryListenerPlugin.java
@@ -0,0 +1,16 @@
+package aQute.bnd.service;
+
+import java.io.*;
+
+import aQute.lib.osgi.*;
+
+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..91b0a7e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java
@@ -0,0 +1,91 @@
+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();
+
+	/**
+	 * Return a location identifier of this repository
+	 */
+
+	String getLocation();
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/ResolutionPhase.java b/bundleplugin/src/main/java/aQute/bnd/service/ResolutionPhase.java
new file mode 100644
index 0000000..0fd7ec9
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/ResolutionPhase.java
@@ -0,0 +1,5 @@
+package aQute.bnd.service;
+
+public enum ResolutionPhase {
+	build, runtime
+}
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..be7f79b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/ResourceHandle.java
@@ -0,0 +1,12 @@
+package aQute.bnd.service;
+
+import java.io.*;
+
+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/diff/Delta.java b/bundleplugin/src/main/java/aQute/bnd/service/diff/Delta.java
new file mode 100644
index 0000000..eec4781
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/diff/Delta.java
@@ -0,0 +1,19 @@
+package aQute.bnd.service.diff;
+
+/**
+ * The Delta provides information about the {@link Diff} object. It tells the
+ * relation between the newer and older compared elements.
+ * 
+ */
+public enum Delta {
+
+	// ORDER IS IMPORTANT FOR TRANSITIONS TABLE!
+
+	/**
+	 * 
+	 */
+	IGNORED, // for all
+	UNCHANGED, CHANGED, MICRO, MINOR, MAJOR, // content
+	REMOVED, ADDED; // structural
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/diff/Diff.java b/bundleplugin/src/main/java/aQute/bnd/service/diff/Diff.java
new file mode 100644
index 0000000..43bf4e5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/diff/Diff.java
@@ -0,0 +1,23 @@
+package aQute.bnd.service.diff;
+
+import java.util.*;
+
+public interface Diff {
+	interface Ignore {
+		boolean contains(Diff diff);
+	}
+	
+	Delta getDelta();
+	Delta getDelta(Ignore ignore);
+
+	Type getType();
+	String getName();
+	Tree getOlder();
+	Tree getNewer();
+
+	Collection<? extends Diff> getChildren();
+	
+	Diff get(String name);
+	
+	
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/diff/Differ.java b/bundleplugin/src/main/java/aQute/bnd/service/diff/Differ.java
new file mode 100644
index 0000000..869a237
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/diff/Differ.java
@@ -0,0 +1,13 @@
+package aQute.bnd.service.diff;
+
+import aQute.lib.osgi.*;
+
+/**
+ * Compare two Jars and report the differences.
+ */
+public interface Differ {
+	Tree tree(Analyzer source ) throws Exception;
+	Tree tree(Jar source) throws Exception;
+
+	Tree deserialize(Tree.Data data) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/diff/Tree.java b/bundleplugin/src/main/java/aQute/bnd/service/diff/Tree.java
new file mode 100644
index 0000000..7072ac1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/diff/Tree.java
@@ -0,0 +1,29 @@
+package aQute.bnd.service.diff;
+
+public interface Tree {
+
+	public class Data {
+		public String	name;
+		public Type		type		= Type.METHOD;
+		public Delta	add			= Delta.MINOR;
+		public Delta	rem			= Delta.MAJOR;
+		public Data[]	children	= null;
+		public String	comment		= null;
+	}
+
+	Data serialize();
+
+	Tree[] getChildren();
+
+	String getName();
+
+	Type getType();
+
+	Delta ifAdded();
+
+	Delta ifRemoved();
+
+	Diff diff(Tree older);
+
+	Tree get(String name);
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/diff/Type.java b/bundleplugin/src/main/java/aQute/bnd/service/diff/Type.java
new file mode 100644
index 0000000..d71b9f4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/diff/Type.java
@@ -0,0 +1,10 @@
+package aQute.bnd.service.diff;
+
+public enum Type {
+	ACCESS, BUNDLE, API, MANIFEST, PACKAGE, CLASS, INTERFACE, ANNOTATION, ENUM, EXTENDS, IMPLEMENTS, FIELD, METHOD, ANNOTATED, PROPERTY, RESOURCE, CUSTOM, CLAUSE, HEADER, PARAMETER, CLASS_VERSION, RESOURCES, CONSTANT, RETURN, VERSION, DEPRECATED;
+
+	public boolean isInherited() {
+		// TODO Auto-generated method stub
+		return false;
+	} 
+}
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..0ff7674
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/packageinfo
@@ -0,0 +1 @@
+version 1.45.0
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/url/TaggedData.java b/bundleplugin/src/main/java/aQute/bnd/service/url/TaggedData.java
new file mode 100644
index 0000000..53332f4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/url/TaggedData.java
@@ -0,0 +1,37 @@
+package aQute.bnd.service.url;
+
+import java.io.InputStream;
+
+/**
+ * Represents a data stream that has a tag associated with it; the primary
+ * use-case is an HTTP response stream with an ETag header.
+ * 
+ * @author Neil Bartlett
+ * 
+ */
+public class TaggedData {
+
+	private final String tag;
+	private final InputStream inputStream;
+
+	public TaggedData(String tag, InputStream inputStream) {
+		this.tag = tag;
+		this.inputStream = inputStream;
+	}
+
+	/**
+	 * Returns the ETag for the retrieved resource, or {@code null} if the ETag
+	 * was not provided by the server.
+	 */
+	public String getTag() {
+		return tag;
+	}
+
+	/**
+	 * Returns the input stream containing the resource data.
+	 */
+	public InputStream getInputStream() {
+		return inputStream;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/url/URLConnector.java b/bundleplugin/src/main/java/aQute/bnd/service/url/URLConnector.java
new file mode 100644
index 0000000..e853509
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/url/URLConnector.java
@@ -0,0 +1,49 @@
+package aQute.bnd.service.url;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+public interface URLConnector {
+
+	/**
+	 * Connect to the specified URL.
+	 * 
+	 * @param url
+	 * @return
+	 * @throws IOException
+	 */
+	InputStream connect(URL url) throws IOException;
+
+	/**
+	 * Connect to the specified URL, also returning the ETag if available.
+	 * 
+	 * @param url
+	 *            The remote URL.
+	 * @return An instance of {@link TaggedData}; note that the
+	 *         {@link TaggedData#getTag()} method <strong>may</strong> return
+	 *         {@code null} if the resource has no tag.
+	 * @throws IOException
+	 * 
+	 * @since 1.1
+	 */
+	TaggedData connectTagged(URL url) throws IOException;
+
+	/**
+	 * Connect to the specified URL while providing the last known tag for the
+	 * remote resource; the response will be {@code null} if the remote resource
+	 * is unchanged.
+	 * 
+	 * @param url
+	 *            The remote URL.
+	 * @param tag
+	 *            The last known tag value for the resource.
+	 * @return An instance of {@link TaggedData}, or {@code null} if the
+	 *         resource has not modified (i.e., if it has the same tag value).
+	 * @throws IOException
+	 * 
+	 * @since 1.1
+	 */
+	TaggedData connectTagged(URL url, String tag) throws IOException;
+
+}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/url/packageinfo b/bundleplugin/src/main/java/aQute/bnd/service/url/packageinfo
new file mode 100644
index 0000000..7ae9673
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/service/url/packageinfo
@@ -0,0 +1 @@
+version 1.1
\ No newline at end of file
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..d0073b5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/signing/JartoolSigner.java
@@ -0,0 +1,144 @@
+package aQute.bnd.signing;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+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;
+    String digestalg;
+
+    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");
+        if (map.containsKey("digestalg"))
+            this.digestalg = map.get("digestalg");
+    }
+
+    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);
+        }
+
+        if (digestalg != null) {
+        	command.add("-digestalg");
+        	command.add(digestalg);
+	    }
+
+        command.add(tmp.getAbsolutePath());
+        command.add(alias);
+        builder.trace("Jarsigner command: %s", command);
+        command.setTimeout(20, TimeUnit.SECONDS);
+        StringBuilder out = new StringBuilder();
+        StringBuilder err = new StringBuilder();
+        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 (Entry<String, Resource> entry : dir.entrySet()) {
+            String path = entry.getKey();
+            if (path.matches(".*\\.(DSA|RSA|SF|MF)$")) {
+                jar.putResource(path, entry.getValue());
+            }
+        }
+        jar.setDoNotTouchManifest();
+    }
+
+    StringBuilder collect(final InputStream in) throws Exception {
+        final StringBuilder sb = new StringBuilder();
+        
+        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..1827cd6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/signing/Signer.java
@@ -0,0 +1,196 @@
+package aQute.bnd.signing;
+
+import java.io.*;
+import java.security.*;
+import java.security.KeyStore.PrivateKeyEntry;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.lib.base64.*;
+import aQute.lib.io.*;
+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;
+
+            java.io.FileInputStream keystoreInputStream = null;
+            try {
+            	keystoreInputStream = new java.io.FileInputStream(
+                        keystoreFile);
+                char[] pw = password == null ? new char[0]
+                        : password.toCharArray();
+                
+                keystore.load(keystoreInputStream, pw);
+                keystoreInputStream.close();
+                privateKeyEntry =  (PrivateKeyEntry) keystore.getEntry(
+                        alias, new KeyStore.PasswordProtection(pw));
+            } catch (Exception e) {
+                error("No able to load the private key from the give keystore("+keystoreFile.getAbsolutePath()+") with alias "+alias+" : "
+                        + e);
+                return;
+            } finally {
+            	IO.close(keystoreInputStream);
+            }
+            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) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        PrintWriter ps = IO.writer(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("UTF-8"));
+                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/configurable/Config.java b/bundleplugin/src/main/java/aQute/configurable/Config.java
new file mode 100644
index 0000000..bc2aebe
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/configurable/Config.java
@@ -0,0 +1,13 @@
+package aQute.configurable;
+
+import java.lang.annotation.*;
+
+@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) 
+public @interface Config {
+	String NULL = "<<NULL>>";
+	
+	boolean required() default false;
+	String description() default "";
+	String deflt() default NULL;
+	String id() default NULL;
+}
diff --git a/bundleplugin/src/main/java/aQute/configurable/Configurable.java b/bundleplugin/src/main/java/aQute/configurable/Configurable.java
new file mode 100644
index 0000000..79af122
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/configurable/Configurable.java
@@ -0,0 +1,368 @@
+package aQute.configurable;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.lang.reflect.Proxy;
+import java.net.*;
+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 {
+			Config ad = method.getAnnotation(Config.class);
+			String id = Configurable.mangleMethodName(method.getName());
+
+			if (ad != null && !ad.id().equals(Config.NULL))
+				id = ad.id();
+
+			Object o = properties.get(id);
+			if (o == null && args != null && args.length == 1)
+				o = args[0];
+
+			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(Config.NULL))
+						o = null;
+				}
+			}
+			if (o == null) {
+				Class< ? > rt = method.getReturnType();
+				if (rt == boolean.class || rt == Boolean.class)
+					return false;
+				if (method.getReturnType().isPrimitive()
+						|| Number.class
+								.isAssignableFrom(method.getReturnType())) {
+
+					o = "0";
+				}
+				else
+					return null;
+			}
+
+			if (args != null && args.length == 1) {
+				String s = (String) convert(String.class, o);
+
+				// Allow a base to be specified for File and URL
+				if (method.getReturnType() == File.class
+						&& args[0].getClass() == File.class) {
+					return new File((File) args[0], s);
+				}
+				else
+					if (method.getReturnType() == URL.class
+							&& args[0].getClass() == File.class) {
+						return new URL(((File) args[0]).toURI().toURL(), s);
+					}
+					else
+						if (method.getReturnType() == URL.class
+								&& args[0].getClass() == URL.class) {
+							return new URL((URL) args[0], s);
+						}
+			}
+			return convert(method.getGenericReturnType(), o);
+		}
+
+		@SuppressWarnings({"unchecked", "rawtypes"})
+		public Object convert(Type type, Object o) throws Exception {
+
+			// TODO type variables
+			// TODO wildcards
+
+			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;
+					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());
+				}
+			if (Map.class.isAssignableFrom(resultType)) {
+				Map< ? , ? > input = toMap(o);
+				if (resultType.isInterface()) {
+					if (resultType == SortedMap.class)
+						resultType = TreeMap.class;
+					else
+						if (resultType == Map.class)
+							resultType = LinkedHashMap.class;
+						else
+							throw new IllegalArgumentException(
+									"Unknown interface for a collection, no concrete class found: "
+											+ resultType);
+				}
+				@SuppressWarnings("unchecked")
+				Map<Object, Object> result = (Map<Object, Object>) resultType
+						.newInstance();
+				Type keyType = pType.getActualTypeArguments()[0];
+				Type valueType = pType.getActualTypeArguments()[1];
+
+				for (Map.Entry< ? , ? > entry : input.entrySet()) {
+					result.put(convert(keyType, entry.getKey()),
+							convert(valueType, entry.getValue()));
+				}
+				return result;
+			}
+			throw new IllegalArgumentException(
+					"cannot convert to "
+							+ pType
+							+ " because it uses generics and is not a Collection or a map");
+		}
+
+		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;
+				}
+				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);
+		}
+
+		private Map< ? , ? > toMap(Object o) {
+			if (o instanceof Map)
+				return (Map< ? , ? >) o;
+
+			throw new IllegalArgumentException("Cannot convert " + o
+					+ " to a map as requested");
+		}
+
+	}
+
+	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/configurable/packageinfo b/bundleplugin/src/main/java/aQute/configurable/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/configurable/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
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 100755
index 0000000..151adc4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/base64/Base64.java
@@ -0,0 +1,158 @@
+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) {
+		ByteArrayOutputStream bout= new ByteArrayOutputStream(string.length()*2/3);
+		StringReader rdr = new StringReader(string.trim());
+		try {
+			decode(rdr,bout);
+		} catch (Exception e) {
+			// cannot happen
+		}
+		return bout.toByteArray();
+	}
+	
+	public final static void decode(Reader rdr, OutputStream out) throws Exception {
+		int register = 0;
+		int i = 0;
+		int pads = 0;
+
+		byte test[] = new byte[3];
+		int c;
+		while ((c=rdr.read()) >= 0) {
+
+			if (c > 0x7F)
+				throw new IllegalArgumentException(
+						"Invalid base64 character in " + rdr
+								+ ", character value > 128 ");
+			
+			int v = 0;
+			if ( c == '=' ) {
+				pads++;
+			} else {
+				v = values[c];
+				if ( v < 0 )
+					throw new IllegalArgumentException(
+							"Invalid base64 character in " + rdr + ", " + 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;
+			}
+		}
+	}
+
+	static private void flush(OutputStream out, int register, int pads) throws IOException {
+		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[]) {
+		StringWriter sw = new StringWriter();
+		ByteArrayInputStream bin = new ByteArrayInputStream(data);
+		try {
+			encode(bin,sw);
+		} catch (IOException e) {
+			// can't happen
+		}
+		return sw.toString();
+	}
+	
+
+	public Object toData() {
+		return data;
+	}
+
+	public static void encode(InputStream in, Appendable sb) throws IOException {
+		//StringBuilder sb = new StringBuilder();
+		int buf = 0;
+		int bits = 0;
+		int out = 0;
+		
+		while (true) {
+			if (bits >= 6) {
+				bits -= 6;
+				int v = 0x3F & (buf >> bits);
+				sb.append(alphabet.charAt(v));
+				out++;
+			} else {
+				int c = in.read();
+				if (c < 0)
+					break;
+
+				buf <<= 8;
+				buf |= 0xFF & c;
+				bits += 8;
+			}
+		}
+		if (bits != 0) {// must be less than 7
+			sb.append(alphabet.charAt(0x3F & (buf << (6 - bits))));
+			out++;
+		}
+		int mod = 4 - (out % 4);
+		if (mod != 4) {
+			for (int i = 0; i < mod; i++)
+				sb.append('=');
+		}
+	}
+
+}
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..e39f616
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/base64/packageinfo
@@ -0,0 +1 @@
+version 1.1.0
diff --git a/bundleplugin/src/main/java/aQute/lib/codec/Codec.java b/bundleplugin/src/main/java/aQute/lib/codec/Codec.java
new file mode 100644
index 0000000..6de09cf
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/codec/Codec.java
@@ -0,0 +1,9 @@
+package aQute.lib.codec;
+
+import java.io.*;
+import java.lang.reflect.*;
+
+public interface Codec {
+	Object decode(Reader in, Type type) throws Exception;	
+	void encode(Type t, Object o, Appendable out) throws Exception;
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/codec/HCodec.java b/bundleplugin/src/main/java/aQute/lib/codec/HCodec.java
new file mode 100644
index 0000000..f97e695
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/codec/HCodec.java
@@ -0,0 +1,72 @@
+package aQute.lib.codec;
+
+import java.io.*;
+import java.lang.reflect.*;
+
+public class HCodec implements Codec {
+	final Codec	codec;
+
+	public HCodec(Codec codec) {
+		this.codec = codec;
+	}
+
+	public Object decode(Reader in, Type type) throws Exception {
+		return codec.decode(in, type);
+	}
+
+	public <T> T decode(InputStream in, Class<T> t) throws Exception {
+		return t.cast(decode(in, (Type)t));
+	}
+
+	public <T> T decode(Reader in, Class<T> t) throws Exception {
+		return t.cast(decode(in, (Type) t));
+	}
+
+	public Object decode(InputStream in, Type t) throws Exception {
+		InputStreamReader r = new InputStreamReader(in, "UTF-8");
+		return codec.decode(r, t);
+	}
+
+	public void encode(Type t, Object o, Appendable out) throws Exception {
+		codec.encode(t, o, out);
+	}
+
+	public void encode(Type t, Object o, OutputStream out) throws Exception {
+		OutputStreamWriter wr = new OutputStreamWriter(out, "UTF-8");
+		try {
+			codec.encode(t, o, wr);
+		} finally {
+			wr.flush();
+		}
+	}
+
+	public <T> T decode(File in, Class<T> t) throws Exception {
+		FileInputStream fin = new FileInputStream(in);
+		try {
+			InputStreamReader rdr = new InputStreamReader(fin, "UTF-8");
+			try {
+				return t.cast(decode(rdr, t));
+			} finally {
+				rdr.close();
+			}
+		} finally {
+			fin.close();
+		}
+
+	}
+
+	public void encode(Type t, Object o, File out) throws Exception {
+		OutputStream oout = new FileOutputStream(out);
+		try {
+			Writer wr = new OutputStreamWriter(oout, "UTF-8");
+			try {
+				codec.encode(t, o, wr);
+			} finally {
+				wr.close();
+			}
+		} finally {
+			oout.close();
+		}
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/codec/packageinfo b/bundleplugin/src/main/java/aQute/lib/codec/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/codec/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/EnumerationIterator.java b/bundleplugin/src/main/java/aQute/lib/collections/EnumerationIterator.java
new file mode 100644
index 0000000..ec7aec6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/EnumerationIterator.java
@@ -0,0 +1,42 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+/**
+ * Simple facade for enumerators so they can be used in for loops.
+ * 
+ * @param <T>
+ */
+public class EnumerationIterator<T> implements Iterable<T>, Iterator<T> {
+	
+	public static <T> EnumerationIterator<T> iterator(Enumeration<T> e) {
+		return new EnumerationIterator<T>(e);
+	}
+	
+	final Enumeration<T>	enumerator;
+	volatile boolean		done	= false;
+
+	public EnumerationIterator(Enumeration<T> e) {
+		enumerator = e;
+	}
+
+	public synchronized Iterator<T> iterator() {
+		if (done)
+			throw new IllegalStateException("Can only be used once");
+		done = true;
+		return this;
+
+	}
+
+	public boolean hasNext() {
+		return enumerator.hasMoreElements();
+	}
+
+	public T next() {
+		return enumerator.nextElement();
+	}
+
+	public void remove() {
+		throw new UnsupportedOperationException("Does not support removes");
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java b/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java
new file mode 100644
index 0000000..4c4f558
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java
@@ -0,0 +1,31 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+public class ExtList<T> extends ArrayList<T> {
+	private static final long	serialVersionUID	= 1L;
+
+	public ExtList(T ... ts) {
+		super(ts.length);
+		for (T t : ts){
+			add(t);
+		}
+	}
+	
+	public String join() {
+		return join(",");
+	}
+
+	public String join(String del) {
+		StringBuilder sb = new StringBuilder();
+		String d= "";
+		for ( T t : this) {
+			sb.append(d);
+			d=del;
+			if ( t != null)
+				sb.append(t.toString());
+		}
+		return sb.toString();
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/IteratorList.java b/bundleplugin/src/main/java/aQute/lib/collections/IteratorList.java
new file mode 100644
index 0000000..cb96d16
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/IteratorList.java
@@ -0,0 +1,12 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+public class IteratorList<T> extends ArrayList<T> {
+	private static final long	serialVersionUID	= 1L;
+
+	public IteratorList(Iterator<T> i){
+		while(i.hasNext())
+			add(i.next());
+	}
+}
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..a04ab36
--- /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 InputStreamReader( new FileInputStream(in),"UTF-8"));
+	}
+
+	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..fcf28ac
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java
@@ -0,0 +1,155 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+public class MultiMap<K,V> extends HashMap<K,List<V>> {
+	private static final long	serialVersionUID	= 1L;
+	final boolean noduplicates;
+	final Class<?> keyClass;
+	final Class<?> valueClass;
+	
+	final Set<V> EMPTY = Collections.emptySet();
+	
+	public MultiMap() {
+		noduplicates = false;
+		keyClass = Object.class;
+		valueClass = Object.class;
+	}
+	
+	public MultiMap(Class<K> keyClass, Class<V> valueClass, boolean noduplicates ) {
+		this.noduplicates = noduplicates;		
+		this.keyClass = keyClass;
+		this.valueClass = valueClass;
+	}
+	
+	@SuppressWarnings("unchecked") public boolean add( K key, V value ) {
+		assert keyClass.isInstance(key);
+		assert valueClass.isInstance(value);
+		
+		List<V> set = get(key);
+		if ( set == null) {
+			set=new ArrayList<V>();
+			if ( valueClass != Object.class) {
+				set = Collections.checkedList(set, (Class<V>)valueClass);
+			}
+			put(key,set);
+		}else {
+			if (noduplicates) {
+				if ( set.contains(value))
+					return false;
+			}
+		}
+		return set.add(value);
+	}
+	
+	@SuppressWarnings("unchecked") public boolean addAll( K key, Collection<? extends V> value ) {
+		assert keyClass.isInstance(key);
+		List<V> set = get(key);
+		if ( set == null) {
+			set=new ArrayList<V>();
+			if ( valueClass != Object.class) {
+				set = Collections.checkedList(set, (Class<V>)valueClass);
+			}
+			put(key,set);
+		} else
+		if ( noduplicates) {
+			boolean r=false;
+			for ( V v : value) {
+				assert valueClass.isInstance(v);
+				if ( !set.contains(value))
+					r|=set.add(v);
+			}
+			return r;
+		}
+		return set.addAll(value);
+	}
+	
+	public boolean remove( K key, V value ) {
+		assert keyClass.isInstance(key);
+		assert valueClass.isInstance(value);
+		
+		List<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 ) {
+		assert keyClass.isInstance(key);
+		List<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) {
+		assert keyClass.isInstance(key);
+		List<V> set = get(key);
+		if ( set == null)
+			return EMPTY.iterator();
+		return set.iterator();
+	}
+	
+	public Iterator<V> all() {
+		return new Iterator<V>() {
+			Iterator<List<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();
+			}
+			
+		};
+	}
+	
+	public Map<K,V> flatten() {
+		Map<K,V> map = new LinkedHashMap<K,V>();
+		for ( Map.Entry<K, List<V>> entry : entrySet()) {
+			List<V> v = entry.getValue();
+			if ( v == null || v.isEmpty())
+				continue;
+
+			map.put(entry.getKey(), v.get(0));
+		}
+		return map;
+	}
+	
+	public MultiMap<V,K> transpose() {
+		MultiMap<V,K> inverted = new MultiMap<V,K>();
+		for ( Map.Entry<K, List<V>> entry : entrySet()) {
+			K key = entry.getKey();
+			
+			List<V> value = entry.getValue();
+			if ( value == null)
+				continue;
+			
+			for ( V v : value)
+				inverted.add(v, key);
+		}
+		
+		return inverted;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/SortedList.java b/bundleplugin/src/main/java/aQute/lib/collections/SortedList.java
new file mode 100644
index 0000000..220d875
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/SortedList.java
@@ -0,0 +1,423 @@
+package aQute.lib.collections;
+
+import java.util.*;
+
+/**
+ * An immutbale list that sorts objects by their natural order or through a
+ * comparator. It has convenient methods/constructors to create it from
+ * collections and iterators.
+ * 
+ * Why not maintain the lists in their sorted form? Well, TreeMaps are quite
+ * expensive ... I once profiled bnd and was shocked how much memory the Jar
+ * class took due to the TreeMaps. I could not easily change it unfortunately.
+ * The other reason is that Parameters uses a LinkedHashMap because the
+ * preferred order should be the declaration order. However, sometimes you need
+ * to sort the keys by name.
+ * 
+ * Last, and most important reason, is that sometimes you do not know what
+ * collection you have or it is not available in a sort ordering (MultiMap for
+ * example) ... I found myself sorting these things over and over again and
+ * decided to just make an immutable SortedList that is easy to slice and dice
+ * 
+ * @param <T>
+ */
+@SuppressWarnings("unchecked") public class SortedList<T> implements SortedSet<T>, List<T> {
+	static SortedList<?>		empty		= new SortedList<Object>();
+
+	final T[]					list;
+	final int					start;
+	final int					end;
+	final Comparator<T>			cmp;
+	Class<?>					type;
+	static Comparator<Object>	comparator	= //
+
+											new Comparator<Object>() {
+												public int compare(Object o1, Object o2) {
+
+													if (o1 == o2)
+														return 0;
+
+													if (o1.equals(o2))
+														return 0;
+
+													return ((Comparable<Object>) o1).compareTo(o2);
+												}
+											};
+
+	class It implements ListIterator<T> {
+		int	n;
+
+		private It(int n) {
+			this.n = n;
+		}
+
+		public boolean hasNext() {
+			return n < end;
+		}
+
+		public T next() throws NoSuchElementException {
+			if (!hasNext()) {
+				throw new NoSuchElementException("");
+			}
+			return list[n++];
+		}
+
+		public boolean hasPrevious() {
+			return n > start;
+		}
+
+		public T previous() {
+			return get(n - 1);
+		}
+
+		public int nextIndex() {
+			return (n + 1 - start);
+		}
+
+		public int previousIndex() {
+			return (n - 1) - start;
+		}
+
+		@Deprecated public void remove() {
+			throw new UnsupportedOperationException("Immutable");
+		}
+
+		@Deprecated public void set(T e) {
+			throw new UnsupportedOperationException("Immutable");
+		}
+
+		@Deprecated public void add(T e) {
+			throw new UnsupportedOperationException("Immutable");
+		}
+	}
+
+	public SortedList(Collection<? extends Comparable<?>> x) {
+		this((Collection<T>) x, 0, x.size(), (Comparator<T>) comparator);
+	}
+
+	public SortedList(Collection<T> x, Comparator<T> cmp) {
+		this(x, 0, x.size(), cmp);
+	}
+
+	@SuppressWarnings("cast")
+	public SortedList(T... x) {
+		this((T[]) x.clone(), 0, x.length, (Comparator<T>) comparator);
+	}
+
+	@SuppressWarnings("cast")
+	public SortedList(Comparator<T> cmp, T... x) {
+		this((T[]) x.clone(), 0, x.length, cmp);
+	}
+
+	private SortedList(SortedList<T> other, int start, int end) {
+		this.list = other.list;
+		this.cmp = other.cmp;
+		this.start = start;
+		this.end = end;
+	}
+
+	public SortedList(T[] x, int start, int end, Comparator<T> comparator2) {
+		if (start > end) {
+			int tmp = start;
+			start = end;
+			end = tmp;
+		}
+		if (start < 0 || start >= x.length)
+			throw new IllegalArgumentException("Start is not in list");
+
+		if (end < 0 || end > x.length)
+			throw new IllegalArgumentException("End is not in list");
+
+		this.list = x.clone();
+		Arrays.sort(this.list, start, end, comparator2);
+		this.start = start;
+		this.end = end;
+		this.cmp = comparator2;
+	}
+
+	public SortedList(Collection<? extends T> x, int start, int end, Comparator<T> cmp) {
+		if (start > end) {
+			int tmp = start;
+			start = end;
+			end = tmp;
+		}
+		if (start < 0 || start > x.size())
+			throw new IllegalArgumentException("Start is not in list");
+
+		if (end < 0 || end > x.size())
+			throw new IllegalArgumentException("End is not in list");
+
+		this.list = (T[]) x.toArray();
+		Arrays.sort(this.list, start, end, cmp);
+		this.start = start;
+		this.end = end;
+		this.cmp = cmp;
+	}
+
+	private SortedList() {
+		list = null;
+		start = 0;
+		end = 0;
+		cmp = null;
+	}
+
+	public int size() {
+		return end - start;
+	}
+
+	public boolean isEmpty() {
+		return start == end;
+	}
+
+	@SuppressWarnings("cast")
+	public boolean contains(Object o) {
+		assert type != null & type.isInstance(o);
+		return indexOf((T) o) >= 0;
+	}
+
+	public Iterator<T> iterator() {
+		return new It(start);
+	}
+
+	public Object[] toArray() {
+		return list.clone();
+	}
+
+	@SuppressWarnings("hiding") public <T> T[] toArray(T[] a) {
+		if (a == null || a.length < list.length) {
+			return (T[]) list.clone();
+		}
+		System.arraycopy(list, 0, a, 0, list.length);
+		return a;
+	}
+
+	public boolean add(T e) {
+		throw new UnsupportedOperationException("Immutable");
+	}
+
+	public boolean remove(Object o) {
+		throw new UnsupportedOperationException("Immutable");
+	}
+
+	public boolean containsAll(Collection<?> c) {
+		if (c.isEmpty())
+			return true;
+
+		if (isEmpty())
+			return false;
+
+		// TODO take advantage of sorted nature for this
+
+		for (Object el : c) {
+			if (!contains(el))
+				return false;
+		}
+		return false;
+	}
+
+	public boolean addAll(Collection<? extends T> c) {
+		throw new UnsupportedOperationException("Immutable");
+	}
+
+	public boolean retainAll(Collection<?> c) {
+		throw new UnsupportedOperationException("Immutable");
+	}
+
+	public boolean removeAll(Collection<?> c) {
+		throw new UnsupportedOperationException("Immutable");
+	}
+
+	public void clear() {
+		throw new UnsupportedOperationException("Immutable");
+	}
+
+	public Comparator<? super T> comparator() {
+		return cmp;
+	}
+
+	public boolean isSubSet() {
+		return start > 0 && end < list.length;
+	}
+
+	public SortedList<T> subSet(T fromElement, T toElement) {
+		int start = indexOf(fromElement);
+		int end = indexOf(toElement);
+		if (isSubSet() && (start < 0 || end < 0))
+			throw new IllegalArgumentException("This list is a subset");
+		if (start < 0)
+			start = 0;
+		if (end < 0)
+			end = list.length;
+
+		return subList(start, end);
+	}
+
+	public int indexOf(Object o) {
+		assert type != null && type.isInstance(o);
+
+		int n = Arrays.binarySearch(list, (T) o, cmp);
+		if (n >= start && n < end)
+			return n - start;
+
+		return -1;
+	}
+
+	public SortedList<T> headSet(T toElement) {
+		int i = indexOf(toElement);
+		if (i < 0) {
+			if (isSubSet())
+				throw new IllegalArgumentException("This list is a subset");
+			i = end;
+		}
+
+		if (i == end)
+			return this;
+
+		return subList(0, i);
+	}
+
+	public SortedSet<T> tailSet(T fromElement) {
+		int i = indexOf(fromElement);
+		if (i < 0) {
+			if (isSubSet())
+				throw new IllegalArgumentException("This list is a subset");
+			i = start;
+		}
+
+		return subList(i, end);
+	}
+
+	public T first() {
+		if (isEmpty())
+			throw new NoSuchElementException("first");
+		return get(0);
+	}
+
+	public T last() {
+		if (isEmpty())
+			throw new NoSuchElementException("last");
+		return get(end - 1);
+	}
+
+	@Deprecated public boolean addAll(int index, Collection<? extends T> c) {
+		throw new UnsupportedOperationException("Immutable");
+	}
+
+	public T get(int index) {
+		return list[index + start];
+	}
+
+	@Deprecated public T set(int index, T element) {
+		throw new UnsupportedOperationException("Immutable");
+	}
+
+	@Deprecated public void add(int index, T element) {
+		throw new UnsupportedOperationException("Immutable");
+	}
+
+	@Deprecated public T remove(int index) {
+		throw new UnsupportedOperationException("Immutable");
+	}
+
+	public int lastIndexOf(Object o) {
+		int n = indexOf(o);
+		if (n < 0)
+			return -1;
+
+		while (cmp.compare(list[n], (T) o) == 0)
+			n++;
+
+		return n;
+	}
+
+	public ListIterator<T> listIterator() {
+		return new It(start);
+	}
+
+	public ListIterator<T> listIterator(int index) {
+		return new It(index + start);
+	}
+
+	public SortedList<T> subList(int fromIndex, int toIndex) {
+		fromIndex += start;
+		toIndex += start;
+
+		if (toIndex < fromIndex) {
+			int tmp = toIndex;
+			toIndex = fromIndex;
+			fromIndex = tmp;
+		}
+
+		toIndex = Math.max(0, toIndex);
+		toIndex = Math.min(toIndex, end);
+		fromIndex = Math.max(0, fromIndex);
+		fromIndex = Math.min(fromIndex, end);
+		if (fromIndex == start && toIndex == end)
+			return this;
+
+		return new SortedList<T>(this, fromIndex, toIndex);
+	}
+
+	@Deprecated public boolean equals(Object other) {
+		return super.equals(other);
+	}
+
+	@Deprecated public int hashCode() {
+		return super.hashCode();
+	}
+
+	public boolean isEqual(SortedList<T> list) {
+		if (size() != list.size())
+			return false;
+
+		for (int as = start, bs = list.start, al = size(); as < al && bs < al; as++, bs++) {
+			if (comparator.compare(this.list[as], this.list[bs]) != 0)
+				return false;
+		}
+		return true;
+	}
+
+	public Class<?> getType() {
+		return type;
+	}
+
+	public void setType(Class<?> type) {
+		this.type = type;
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		sb.append("[");
+		String del = "";
+		for (T s : list) {
+			sb.append(del);
+			sb.append(s);
+			del = ", ";
+		}
+
+		sb.append("]");
+		return sb.toString();
+	}
+
+	public boolean hasDuplicates() {
+		if (list.length < 2)
+			return false;
+
+		T prev = list[0];
+		for (int i = 1; i < list.length; i++) {
+			if (prev.equals(list[i]))
+				return true;
+		}
+		return false;
+	}
+
+	public static <T extends Comparable<?>> SortedList<T> fromIterator(Iterator<T> it) {
+		IteratorList<T> l = new IteratorList<T>(it);
+		return new SortedList<T>(l);
+	}
+
+	public static <T> SortedList<T> fromIterator(Iterator<T> it, Comparator<T> cmp) {
+		IteratorList<T> l = new IteratorList<T>(it);
+		return new SortedList<T>(l, cmp);
+	}
+}
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..3987f9c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/collections/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/bundleplugin/src/main/java/aQute/lib/converter/Converter.java b/bundleplugin/src/main/java/aQute/lib/converter/Converter.java
new file mode 100644
index 0000000..abbbf9b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/converter/Converter.java
@@ -0,0 +1,364 @@
+package aQute.lib.converter;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.regex.*;
+
+import aQute.lib.base64.*;
+
+/**
+ * General Java type converter from an object to any type. Supports number
+ * conversion
+ * 
+ * @author aqute
+ * 
+ */
+@SuppressWarnings({ "unchecked", "rawtypes" }) public class Converter {
+	boolean	fatal	= true;
+
+	public <T> T convert(Class<T> type, Object o) throws Exception {
+		return (T) convert((Type) type, o);
+	}
+
+	public Object convert(Type type, Object o) throws Exception {
+		if (o == null)
+			return null; // compatible with any
+
+		Class resultType = getRawClass(type);
+		Class<?> actualType = o.getClass();
+		// Is it a compatible type?
+		if (resultType.isAssignableFrom(actualType))
+			return o;
+
+		// We can always make a string
+
+		if (resultType == String.class) {
+			if (actualType.isArray()) {
+				if (actualType == char[].class)
+					return new String((char[]) o);
+				if (actualType == byte[].class)
+					return Base64.encodeBase64((byte[]) o);
+				int l = Array.getLength(o);
+				StringBuilder sb = new StringBuilder("[");
+				String del = "";
+				for (int i = 0; i < l; i++) {
+					sb.append(del);
+					del = ",";
+					sb.append(convert(String.class, Array.get(o, i)));
+				}
+				sb.append("]");
+				return sb.toString();
+			}
+			return o.toString();
+		}
+
+		if (Collection.class.isAssignableFrom(resultType))
+			return collection(type, resultType, o);
+
+		if (Map.class.isAssignableFrom(resultType))
+			return map(type, resultType, o);
+
+		if (type instanceof GenericArrayType) {
+			GenericArrayType gType = (GenericArrayType) type;
+			return array(gType.getGenericComponentType(), o);
+		}
+
+		if (resultType.isArray()) {
+			if (actualType == String.class) {
+				String s = (String) o;
+				if (byte[].class == resultType)
+					return Base64.decodeBase64(s);
+
+				if (char[].class == resultType)
+					return s.toCharArray();
+			}
+			if (byte[].class == resultType) {
+				// Sometimes classes implement toByteArray
+				try {
+					Method m = actualType.getMethod("toByteArray");
+					if (m.getReturnType() == byte[].class)
+						return m.invoke(o);
+
+				} catch (Exception e) {
+					// Ignore
+				}
+			}
+
+			return array(resultType.getComponentType(), o);
+		}
+
+		// Simple type coercion
+
+		if (resultType == boolean.class || resultType == Boolean.class) {
+			if (actualType == boolean.class || actualType == Boolean.class)
+				return o;
+			Number n = number(o);
+			if (n != null)
+				return n.longValue() == 0 ? false : true;
+
+			resultType = Boolean.class;
+		} else if (resultType == byte.class || resultType == Byte.class) {
+			Number n = number(o);
+			if (n != null)
+				return n.byteValue();
+			resultType = Byte.class;
+		} else if (resultType == char.class || resultType == Character.class) {
+			Number n = number(o);
+			if (n != null)
+				return (char) n.shortValue();
+			resultType = Character.class;
+		} else if (resultType == short.class || resultType == Short.class) {
+			Number n = number(o);
+			if (n != null)
+				return n.shortValue();
+
+			resultType = Short.class;
+		} else if (resultType == int.class || resultType == Integer.class) {
+			Number n = number(o);
+			if (n != null)
+				return n.intValue();
+
+			resultType = Integer.class;
+		} else if (resultType == long.class || resultType == Long.class) {
+			Number n = number(o);
+			if (n != null)
+				return n.longValue();
+
+			resultType = Long.class;
+		} else if (resultType == float.class || resultType == Float.class) {
+			Number n = number(o);
+			if (n != null)
+				return n.floatValue();
+
+			resultType = Float.class;
+		} else if (resultType == double.class || resultType == Double.class) {
+			Number n = number(o);
+			if (n != null)
+				return n.doubleValue();
+
+			resultType = Double.class;
+		}
+
+		assert !resultType.isPrimitive();
+
+		if (actualType == String.class) {
+			String input = (String) o;
+			if (resultType == char[].class)
+				return input.toCharArray();
+
+			if (resultType == byte[].class)
+				return Base64.decodeBase64(input);
+
+			if (Enum.class.isAssignableFrom(resultType)) {
+				return Enum.valueOf((Class<Enum>) resultType, input);
+			}
+			if (resultType == Pattern.class) {
+				return Pattern.compile(input);
+			}
+
+			try {
+				Constructor<?> c = resultType.getConstructor(String.class);
+				return c.newInstance(o.toString());
+			} catch (Throwable t) {
+			}
+			try {
+				Method m = resultType.getMethod("valueOf", String.class);
+				if (Modifier.isStatic(m.getModifiers()))
+					return m.invoke(null, o.toString());
+			} catch (Throwable t) {
+			}
+
+			if (resultType == Character.class && input.length() == 1)
+				return input.charAt(0);
+		}
+		Number n = number(o);
+		if (n != null) {
+			if (Enum.class.isAssignableFrom(resultType)) {
+				try {
+					Method values = resultType.getMethod("values");
+					Enum[] vs = (Enum[]) values.invoke(null);
+					int nn = n.intValue();
+					if (nn > 0 && nn < vs.length)
+						return vs[nn];
+				} catch (Exception e) {
+					// Ignore
+				}
+			}
+		}
+		return error("No conversion found for " + o.getClass() + " to " + type);
+	}
+
+	private Number number(Object o) {
+		if (o instanceof Number)
+			return (Number) o;
+
+		if (o instanceof Boolean)
+			return ((Boolean) o).booleanValue() ? 1 : 0;
+
+		if (o instanceof Character)
+			return (int) ((Character) o).charValue();
+
+		if (o instanceof String) {
+			String s = (String) o;
+			try {
+				return Double.parseDouble(s);
+			} catch (Exception e) {
+				// Ignore
+			}
+		}
+		return null;
+	}
+
+	private Collection collection(Type collectionType, Class<? extends Collection> rawClass,
+			Object o) throws Exception {
+		Collection collection;
+		if (rawClass.isInterface() || Modifier.isAbstract(rawClass.getModifiers())) {
+			if (rawClass.isAssignableFrom(ArrayList.class))
+				collection = new ArrayList();
+			else if (rawClass.isAssignableFrom(HashSet.class))
+				collection = new HashSet();
+			else if (rawClass.isAssignableFrom(TreeSet.class))
+				collection = new TreeSet();
+			else if (rawClass.isAssignableFrom(LinkedList.class))
+				collection = new LinkedList();
+			else if (rawClass.isAssignableFrom(Vector.class))
+				collection = new Vector();
+			else if (rawClass.isAssignableFrom(Stack.class))
+				collection = new Stack();
+			else if (rawClass.isAssignableFrom(ConcurrentLinkedQueue.class))
+				collection = new ConcurrentLinkedQueue();
+			else
+				return (Collection) error("Cannot find a suitable collection for the collection interface "
+						+ rawClass);
+		} else
+			collection = rawClass.newInstance();
+
+		Type subType = Object.class;
+		if (collectionType instanceof ParameterizedType) {
+			ParameterizedType ptype = (ParameterizedType) collectionType;
+			subType = ptype.getActualTypeArguments()[0];
+		}
+
+		Collection input = toCollection(o);
+
+		for (Object i : input)
+			collection.add(convert(subType, i));
+
+		return collection;
+	}
+
+	private Map map(Type mapType, Class<? extends Map<?, ?>> rawClass, Object o) throws Exception {
+		Map result;
+		if (rawClass.isInterface() || Modifier.isAbstract(rawClass.getModifiers())) {
+			if (rawClass.isAssignableFrom(HashMap.class))
+				result = new HashMap();
+			else if (rawClass.isAssignableFrom(TreeMap.class))
+				result = new TreeMap();
+			else if (rawClass.isAssignableFrom(ConcurrentHashMap.class))
+				result = new ConcurrentHashMap();
+			else
+				return (Map) error("Cannot find suitable map for map interface " + rawClass);
+		} else
+			result = rawClass.newInstance();
+
+		Map<?, ?> input = toMap(o);
+
+		Type keyType = Object.class;
+		Type valueType = Object.class;
+		if (mapType instanceof ParameterizedType) {
+			ParameterizedType ptype = (ParameterizedType) mapType;
+			keyType = ptype.getActualTypeArguments()[0];
+			valueType = ptype.getActualTypeArguments()[1];
+		}
+
+		for (Map.Entry<?, ?> entry : input.entrySet()) {
+			Object key = convert(keyType, entry.getKey());
+			Object value = convert(valueType, entry.getValue());
+			if (value == null)
+				return (Map) error("Key for map must not be null");
+			result.put(key, value);
+		}
+
+		return result;
+	}
+
+	public Object array(Type type, Object o) throws Exception {
+		Collection<?> input = toCollection(o);
+		Class<?> componentClass = getRawClass(type);
+		Object array = Array.newInstance(componentClass, input.size());
+
+		int i = 0;
+		for (Object next : input) {
+			Array.set(array, i++, convert(type, next));
+		}
+		return array;
+	}
+
+	private Class<?> getRawClass(Type type) {
+		if (type instanceof Class)
+			return (Class<?>) type;
+
+		if (type instanceof ParameterizedType)
+			return (Class<?>) ((ParameterizedType) type).getRawType();
+
+		if (type instanceof GenericArrayType) {
+			Type componentType = ((GenericArrayType) type).getGenericComponentType();
+			return Array.newInstance(getRawClass(componentType), 0).getClass();
+		}
+
+		if (type instanceof TypeVariable) {
+			Type componentType = ((TypeVariable) type).getBounds()[0];
+			return Array.newInstance(getRawClass(componentType), 0).getClass();
+		}
+
+		if (type instanceof WildcardType) {
+			Type componentType = ((WildcardType) type).getUpperBounds()[0];
+			return Array.newInstance(getRawClass(componentType), 0).getClass();
+		}
+
+		return Object.class;
+	}
+
+	public 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;
+			}
+			return Arrays.asList((Object[]) o);
+		}
+
+		return Arrays.asList(o);
+	}
+
+	public Map<?, ?> toMap(Object o) throws Exception {
+		if (o instanceof Map)
+			return (Map<?, ?>) o;
+		Map result = new HashMap();
+		Field fields[] = o.getClass().getFields();
+		for (Field f : fields)
+			result.put(f.getName(), f.get(o));
+		if (result.isEmpty())
+			return null;
+
+		return result;
+	}
+
+	private Object error(String string) {
+		if (fatal)
+			throw new IllegalArgumentException(string);
+		return null;
+	}
+
+	public void setFatalIsException(boolean b) {
+		fatal = b;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/converter/packageinfo b/bundleplugin/src/main/java/aQute/lib/converter/packageinfo
new file mode 100644
index 0000000..3390555
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/converter/packageinfo
@@ -0,0 +1 @@
+version 2.0.1
diff --git a/bundleplugin/src/main/java/aQute/lib/data/AllowNull.java b/bundleplugin/src/main/java/aQute/lib/data/AllowNull.java
new file mode 100644
index 0000000..2bbf253
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/data/AllowNull.java
@@ -0,0 +1,9 @@
+package aQute.lib.data;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value={ElementType.FIELD})
+public @interface AllowNull {
+	String reason() default "";
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/data/Data.java b/bundleplugin/src/main/java/aQute/lib/data/Data.java
new file mode 100644
index 0000000..d790d2e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/data/Data.java
@@ -0,0 +1,79 @@
+package aQute.lib.data;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+public class Data {
+
+	public static String validate(Object o) throws Exception {
+		StringBuilder sb = new StringBuilder();
+		Formatter formatter = new Formatter(sb);
+
+		Field fields[] = o.getClass().getFields();
+		for (Field f : fields) {
+			Validator patternValidator = f.getAnnotation(Validator.class);
+			Numeric numericValidator = f.getAnnotation(Numeric.class);
+			AllowNull allowNull = f.getAnnotation(AllowNull.class);
+			Object value = f.get(o);
+			if (value == null) {
+				if (allowNull == null)
+					formatter.format("Value for %s must not be null\n", f.getName());
+			} else {
+				
+
+				if (patternValidator != null) {
+					Pattern p = Pattern.compile(patternValidator.value());
+					Matcher m = p.matcher(value.toString());
+					if (!m.matches()) {
+						String reason = patternValidator.reason();
+						if (reason.length() == 0)
+							formatter.format("Value for %s=%s does not match pattern %s\n",
+									f.getName(), value, patternValidator.value());
+						else
+							formatter.format("Value for %s=%s %s\n", f.getName(), value, reason);
+					}
+				}
+
+				if (numericValidator != null) {
+					if (o instanceof String) {
+						try {
+							o = Double.parseDouble((String) o);
+						} catch (Exception e) {
+							formatter.format("Value for %s=%s %s\n", f.getName(), value, "Not a number");
+						}
+					}
+					
+					try {
+						Number n = (Number) o;
+						long number = n.longValue();
+						if (number >= numericValidator.min() && number < numericValidator.max()) {
+							formatter.format("Value for %s=%s not in valid range (%s,%s]\n",
+									f.getName(), value, numericValidator.min(), numericValidator.max());
+						}
+					} catch (ClassCastException e) {
+						formatter.format("Value for %s=%s [%s,%s) is not a number\n", f.getName(), value,
+								numericValidator.min(), numericValidator.max());
+					}
+				}
+			}
+		}
+		if ( sb.length() == 0)
+			return null;
+		
+		if ( sb.length() > 0)
+			sb.delete(sb.length() - 1, sb.length());
+		return sb.toString();
+	}
+
+	public static void details(Object data, Appendable out) throws Exception {
+		Field fields[] = data.getClass().getFields();
+		Formatter formatter = new Formatter(out);
+		
+		for ( Field f : fields ) {
+			String name = f.getName();
+			name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
+			formatter.format("%-40s %s\n", name, f.get(data));
+		}
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/data/Numeric.java b/bundleplugin/src/main/java/aQute/lib/data/Numeric.java
new file mode 100644
index 0000000..19d60cf
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/data/Numeric.java
@@ -0,0 +1,11 @@
+package aQute.lib.data;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value={ElementType.FIELD})
+public @interface Numeric {
+	long min() default Long.MIN_VALUE;
+	long max() default Long.MAX_VALUE;
+	String reason() default "";
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/data/Validator.java b/bundleplugin/src/main/java/aQute/lib/data/Validator.java
new file mode 100644
index 0000000..e8a8d4f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/data/Validator.java
@@ -0,0 +1,10 @@
+package aQute.lib.data;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(value={ElementType.FIELD})
+public @interface Validator {
+	String value();
+	String reason() default "";
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/data/packageinfo b/bundleplugin/src/main/java/aQute/lib/data/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/data/packageinfo
@@ -0,0 +1 @@
+version 1.0.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..780c32f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/FileInstallRepo.java
@@ -0,0 +1,150 @@
+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.header.*;
+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");
+
+        Parameters 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 = new Instruction(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 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..8cd39f1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java
@@ -0,0 +1,333 @@
+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.header.*;
+import aQute.libg.reporter.*;
+import aQute.libg.version.*;
+
+public class FileRepo implements Plugin, RepositoryPlugin, Refreshable, RegistryPlugin {
+	public final static String	LOCATION	= "location";
+	public final static String	READONLY	= "readonly";
+	public final 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 = 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 = map.get(READONLY);
+		if (readonly != null && Boolean.valueOf(readonly).booleanValue())
+			canWrite = false;
+
+		name = 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 = 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");
+
+		Parameters 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);
+
+		reporter.trace("bsn=%s version=%s",bsn,version);
+		
+		File dir = new File(root, bsn);
+		dir.mkdirs();
+		String fName = bsn + "-" + version.getWithoutQualifier() + ".jar";
+		File file = new File(dir, fName);
+
+		reporter.trace("updating %s ", 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 = new Instruction(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 = Integer.MAX_VALUE + "";
+					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 Jar get(String bsn, Version v) throws Exception {
+		init();
+		File bsns = new File(root, bsn);
+		File version = new File(bsns, bsn + "-" + v.getMajor() + "." + v.getMinor() + "."
+				+ v.getMicro() + ".jar");
+		if ( version.exists())
+			return new Jar(version);
+		else
+			return null;
+	}
+
+	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;
+
+			if (vr.getHigh().getMajor() == Integer.MAX_VALUE)
+				version = "latest";
+
+			File file = IO.getFile(root, bsn + "/" + bsn + "-" + version + ".jar");
+			if (file.isFile())
+				return file;
+			else {
+				file = IO.getFile(root, bsn + "/" + bsn + "-" + version + ".lib");
+				if (file.isFile())
+					return file;
+			}
+			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;
+	}
+
+	public String getLocation() {
+		return root.toString();
+	}
+
+}
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 100755
index 0000000..ab75db9
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/filter/Filter.java
@@ -0,0 +1,343 @@
+/**
+ * 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 static int	EQ			= 0;
+	final static int	LE			= 1;
+	final static int	GE			= 2;
+	final static 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() {
+			StringBuilder sb = new StringBuilder();
+			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) {
+		StringBuilder sb = new StringBuilder();
+		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);
+			}
+		}
+		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/getopt/Arguments.java b/bundleplugin/src/main/java/aQute/lib/getopt/Arguments.java
new file mode 100644
index 0000000..36fc73c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/getopt/Arguments.java
@@ -0,0 +1,8 @@
+package aQute.lib.getopt;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Arguments {
+	String[] arg();
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/getopt/CommandLine.java b/bundleplugin/src/main/java/aQute/lib/getopt/CommandLine.java
new file mode 100644
index 0000000..f95b6c4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/getopt/CommandLine.java
@@ -0,0 +1,472 @@
+package aQute.lib.getopt;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.*;
+
+import aQute.configurable.*;
+import aQute.lib.justif.*;
+import aQute.libg.generics.*;
+import aQute.libg.reporter.*;
+
+/**
+ * Helps parsing command lines. This class takes target object, a primary
+ * command, and a list of arguments. It will then find the command in the target
+ * object. The method of this command must start with a "_" and take an
+ * parameter of Options type. Usually this is an interface that extends Options.
+ * The methods on this interface are options or flags (when they return
+ * boolean).
+ * 
+ */
+@SuppressWarnings("unchecked") public class CommandLine {
+	static int		LINELENGTH	= 60;
+	static Pattern	ASSIGNMENT	= Pattern.compile("(\\w[\\w\\d]*+)\\s*=\\s*([^\\s]+)\\s*");
+	Reporter		reporter;
+	Justif			justif = new Justif(60);
+	
+	public CommandLine(Reporter reporter) {
+		this.reporter = reporter;
+	}
+
+	/**
+	 * Execute a command in a target object with a set of options and arguments
+	 * and returns help text if something fails. Errors are reported.
+	 */
+
+	public String execute(Object target, String cmd, List<String> input) throws Exception {
+
+		if (cmd.equals("help")) {
+			StringBuilder sb = new StringBuilder();
+			Formatter f = new Formatter(sb);
+			if (input.isEmpty())
+				help(f, target);
+			else {
+				for (String s : input) {
+					help(f, target, s);
+				}
+			}
+			f.flush();
+			justif.wrap(sb);
+			return sb.toString();
+		}
+
+		//
+		// Find the appropriate method
+		//
+
+		List<String> arguments = new ArrayList<String>(input);
+		Map<String, Method> commands = getCommands(target);
+
+		Method m = commands.get(cmd);
+		if (m == null) {
+			reporter.error("No such command %s\n", cmd);
+			return help(target, null, null);
+		}
+
+		//
+		// Parse the options
+		//
+
+		Class<? extends Options> optionClass = (Class<? extends Options>) m.getParameterTypes()[0];
+		Options options = getOptions(optionClass, arguments);
+		if (options == null) {
+			// had some error, already reported
+			return help(target, cmd, null);
+		}
+
+		// Check if we have an @Arguments annotation that
+		// provides patterns for the remainder arguments
+
+		Arguments argumentsAnnotation = optionClass.getAnnotation(Arguments.class);
+		if (argumentsAnnotation != null) {
+			String[] patterns = argumentsAnnotation.arg();
+
+			// Check for commands without any arguments
+
+			if (patterns.length == 0 && arguments.size() > 0) {
+				reporter.error("This command takes no arguments but found %s\n", arguments);
+				return help(target, cmd, null);
+			}
+
+			// Match the patterns to the given command line
+
+			int i = 0;
+			for (; i < patterns.length; i++) {
+				String pattern = patterns[i];
+
+				boolean optional = pattern.matches("\\[.*\\]");
+
+				// Handle vararg
+
+				if (pattern.equals("...")) {
+					i = Integer.MAX_VALUE;
+					break;
+				}
+
+				// Check if we're running out of args
+
+				if (i > arguments.size()) {
+					if (!optional)
+						reporter.error("Missing argument %s\n", patterns[i]);
+					return help(target, cmd, optionClass);
+				}
+			}
+
+			// Check if we have unconsumed arguments left
+
+			if (i < arguments.size()) {
+				reporter.error("Too many arguments specified %s, expecting %s\n", arguments,
+						Arrays.asList(patterns));
+				return help(target, cmd, optionClass);
+			}
+		}
+		if (reporter.getErrors().size() == 0) {
+			m.setAccessible(true);
+			m.invoke(target, options);
+			return null;
+		}
+		return help(target, cmd, optionClass);
+	}
+
+	private String help(Object target, String cmd, Class<? extends Options> type) throws Exception {
+		StringBuilder sb = new StringBuilder();
+		Formatter f = new Formatter(sb);
+		if (cmd == null)
+			help(f, target);
+		else if (type == null)
+			help(f, target, cmd);
+		else
+			help(f, target, cmd, type);
+
+		f.flush();
+		justif.wrap(sb);
+		return sb.toString();
+	}
+
+	/**
+	 * Parse the options in a command line and return an interface that provides
+	 * the options from this command line. This will parse up to (and including)
+	 * -- or an argument that does not start with -
+	 * 
+	 */
+	public <T extends Options> T getOptions(Class<T> specification, List<String> arguments)
+			throws Exception {
+		Map<String, String> properties = Create.map();
+		Map<String, Object> values = new HashMap<String, Object>();
+		Map<String, Method> options = getOptions(specification);
+
+		argloop: while (arguments.size() > 0) {
+
+			String option = arguments.get(0);
+
+			if (option.startsWith("-")) {
+
+				arguments.remove(0);
+
+				if (option.startsWith("--")) {
+
+					if ("--".equals(option))
+						break argloop;
+
+					// Full named option, e.g. --output
+					String name = option.substring(2);
+					Method m = options.get(name);
+					if (m == null)
+						reporter.error("Unrecognized option %s\n", name);
+					else
+						assignOptionValue(values, m, arguments, true);
+
+				} else {
+
+					// Set of single character named options like -a
+
+					charloop: for (int j = 1; j < option.length(); j++) {
+
+						char optionChar = option.charAt(j);
+
+						for (Entry<String, Method> entry : options.entrySet()) {
+							if (entry.getKey().charAt(0) == optionChar) {
+								boolean last = (j + 1) >= option.length();
+								assignOptionValue(values, entry.getValue(),
+										arguments, last);
+								continue charloop;
+							}
+						}
+						reporter.error("No such option -%s\n", optionChar);
+					}
+				}
+			} else {
+				Matcher m = ASSIGNMENT.matcher(option);
+				if (m.matches()) {
+					properties.put(m.group(1), m.group(2));
+				}
+				break;
+			}
+		}
+
+		// check if all required elements are set
+
+		for (Entry<String, Method> entry : options.entrySet()) {
+			Method m = entry.getValue();
+			String name = entry.getKey();
+			if (!values.containsKey(name) && isMandatory(m))
+				reporter.error("Required option --%s not set", name);
+		}
+
+		values.put(".", arguments);
+		values.put(".command", this);
+		values.put(".properties", properties);
+		return Configurable.createConfigurable(specification, values);
+	}
+
+	/**
+	 * Answer a list of the options specified in an options interface
+	 */
+	private Map<String, Method> getOptions(Class<? extends Options> interf) {
+		Map<String, Method> map = new TreeMap<String, Method>();
+
+		for (Method m : interf.getMethods()) {
+			if (m.getName().startsWith("_"))
+				continue;
+
+			String name;
+
+			Config cfg = m.getAnnotation(Config.class);
+			if (cfg == null || cfg.id() == null || cfg.id().equals(Config.NULL))
+				name = m.getName();
+			else
+				name = cfg.id();
+
+			map.put(name, m);
+		}
+		return map;
+	}
+
+	/**
+	 * Assign an option, must handle flags, parameters, and parameters that can
+	 * happen multiple times.
+	 * 
+	 * @param options
+	 *            The command line map
+	 * @param args
+	 *            the args input
+	 * @param i
+	 *            where we are
+	 * @param m
+	 *            the selected method for this option
+	 * @param last
+	 *            if this is the last in a multi single character option
+	 * @return
+	 */
+	public void assignOptionValue(Map<String, Object> options, Method m, List<String> args,
+			boolean last) {
+		String name = m.getName();
+		Type type = m.getGenericReturnType();
+
+		if (isOption(m)) {
+
+			// The option is a simple flag
+
+			options.put(name, true);
+		} else {
+
+			// The option is followed by an argument
+
+			if (!last) {
+				reporter.error(
+						"Option --%s not last in a set of 1-letter options (%s) but it requires an argument of type ",
+						name, name.charAt(0), getTypeDescriptor(type));
+				return;
+			}
+
+			if (args.isEmpty()) {
+				reporter.error("Missing argument %s for option --%s, -%s ",
+						getTypeDescriptor(type), name, name.charAt(0));
+				return;
+			}
+
+			String parameter = args.remove(0);
+
+			if (Collection.class.isAssignableFrom(m.getReturnType())) {
+
+				Collection<Object> optionValues = (Collection<Object>) options.get(m.getName());
+
+				if (optionValues == null) {
+					optionValues = new ArrayList<Object>();
+					options.put(name, optionValues);
+				}
+
+				optionValues.add(parameter);
+			} else {
+
+				if (options.containsKey(name)) {
+					reporter.error("The option %s can only occur once", name);
+					return;
+				}
+
+				options.put(name, parameter);
+			}
+		}
+	}
+
+	/**
+	 * Provide a help text.
+	 */
+
+	public void help(Formatter f, Object target, String cmd, Class<? extends Options> specification) {
+		Description descr = specification.getAnnotation(Description.class);
+		Arguments patterns = specification.getAnnotation(Arguments.class);
+		Map<String, Method> options = getOptions(specification);
+
+		String description = descr == null ? "" : descr.value();
+
+		f.format("NAME\n  %s - %s\n\n", cmd, description);
+		f.format("SYNOPSIS\n   %s [options] ", cmd);
+
+		if (patterns == null)
+			f.format(" ...\n\n");
+		else {
+			String del = " ";
+			for (String pattern : patterns.arg()) {
+				if (pattern.equals("..."))
+					f.format("%s...", del);
+				else
+					f.format("%s<%s>", del, pattern);
+				del = " ";
+			}
+			f.format("\n\n");
+		}
+
+		f.format("OPTIONS\n");
+		for (Entry<String, Method> entry : options.entrySet()) {
+			String optionName = entry.getKey();
+			Method m = entry.getValue();
+
+			Config cfg = m.getAnnotation(Config.class);
+			Description d = m.getAnnotation(Description.class);
+			boolean required = isMandatory(m);
+
+			String methodDescription = cfg != null ? cfg.description() : (d == null ? "" : d
+					.value());
+
+			f.format("   %s -%s, --%s %s%s - %s\n", required ? " " : "[", //
+					optionName.charAt(0), //
+					optionName, //
+					getTypeDescriptor(m.getGenericReturnType()), //
+					required ? " " : "]",//
+					methodDescription);
+		}
+		f.format("\n");
+	}
+
+	static Pattern	LAST_PART	= Pattern.compile(".*[\\$\\.]([^\\$\\.]+)");
+
+	private static String lastPart(String name) {
+		Matcher m = LAST_PART.matcher(name);
+		if (m.matches())
+			return m.group(1);
+		return name;
+	}
+
+	/**
+	 * Show all commands in a target
+	 */
+	public void help(Formatter f, Object target) throws Exception {
+		// TODO get help from the class
+		Description descr = target.getClass().getAnnotation(Description.class);
+		if (descr != null) {
+			f.format("%s\n\n", descr.value());
+		}
+		f.format("Available commands: ");
+
+		String del = "";
+		for (String name : getCommands(target).keySet()) {
+			f.format("%s%s", del, name);
+			del = ", ";
+		}
+		f.format("\n");
+
+	}
+
+	/**
+	 * Show the full help for a given command
+	 */
+	public void help(Formatter f, Object target, String cmd) {
+
+		Method m = getCommands(target).get(cmd);
+		if (m == null)
+			f.format("No such command: %s\n", cmd);
+		else {
+			Class<? extends Options> options = (Class<? extends Options>) m.getParameterTypes()[0];
+			help(f, target, cmd, options);
+		}
+	}
+
+	/**
+	 * Parse a class and return a list of command names
+	 * 
+	 * @param target
+	 * @return
+	 */
+	public Map<String, Method> getCommands(Object target) {
+		Map<String, Method> map = new TreeMap<String, Method>();
+
+		for (Method m : target.getClass().getMethods()) {
+
+			if (m.getParameterTypes().length == 1 && m.getName().startsWith("_")) {
+				Class<?> clazz = m.getParameterTypes()[0];
+				if (Options.class.isAssignableFrom(clazz)) {
+					String name = m.getName().substring(1);
+					map.put(name, m);
+				}
+			}
+		}
+		return map;
+	}
+
+	/**
+	 * Answer if the method is marked mandatory
+	 */
+	private boolean isMandatory(Method m) {
+		Config cfg = m.getAnnotation(Config.class);
+		if (cfg == null)
+			return false;
+
+		return cfg.required();
+	}
+
+	/**
+	 * @param m
+	 * @return
+	 */
+	private boolean isOption(Method m) {
+		return m.getReturnType() == boolean.class || m.getReturnType() == Boolean.class;
+	}
+
+	/**
+	 * Show a type in a nice way
+	 */
+
+	private String getTypeDescriptor(Type type) {
+		if (type instanceof ParameterizedType) {
+			ParameterizedType pt = (ParameterizedType) type;
+			Type c = pt.getRawType();
+			if (c instanceof Class) {
+				if (Collection.class.isAssignableFrom((Class<?>) c)) {
+					return getTypeDescriptor(pt.getActualTypeArguments()[0]) + "*";
+				}
+			}
+		}
+		if (!(type instanceof Class))
+			return "<>";
+
+		Class<?> clazz = (Class<?>) type;
+
+		if (clazz == Boolean.class || clazz == boolean.class)
+			return ""; // Is a flag
+
+		return "<" + lastPart(clazz.getName().toLowerCase()) + ">";
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/getopt/Description.java b/bundleplugin/src/main/java/aQute/lib/getopt/Description.java
new file mode 100644
index 0000000..d5baead
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/getopt/Description.java
@@ -0,0 +1,8 @@
+package aQute.lib.getopt;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Description {
+	String value();
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/getopt/OptionArgument.java b/bundleplugin/src/main/java/aQute/lib/getopt/OptionArgument.java
new file mode 100644
index 0000000..f4e9faa
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/getopt/OptionArgument.java
@@ -0,0 +1,8 @@
+package aQute.lib.getopt;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OptionArgument {
+	String value();
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/getopt/Options.java b/bundleplugin/src/main/java/aQute/lib/getopt/Options.java
new file mode 100644
index 0000000..aab2b7f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/getopt/Options.java
@@ -0,0 +1,11 @@
+package aQute.lib.getopt;
+
+import java.util.*;
+
+public interface Options {
+	List<String> _();
+	CommandLine _command();
+	Map<String,String> _properties();
+	boolean _ok();
+	boolean _help();
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/getopt/packageinfo b/bundleplugin/src/main/java/aQute/lib/getopt/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/getopt/packageinfo
@@ -0,0 +1 @@
+version 1.0.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 100755
index 0000000..3c7fa4a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/hex/Hex.java
@@ -0,0 +1,60 @@
+package aQute.lib.hex;
+
+import java.io.*;
+
+
+/*
+ * Hex converter.
+ * 
+ * TODO Implement string to byte[]
+ */
+public class Hex {
+	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++) {
+			int high = nibble(string.charAt(i*2))<<4;
+			int low = nibble(string.charAt(i*2+1));
+			out[i] = (byte) (high + low);
+		}
+		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..4414f9d
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/index/Index.java
@@ -0,0 +1,349 @@
+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 static int		TYPE_OFFSET		= 0;
+		final static 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, ((long) 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, ((long) 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;
+						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;
+				return c(i);
+			}
+			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.err.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..3d4458e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/io/IO.java
@@ -0,0 +1,388 @@
+package aQute.lib.io;
+
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+import java.security.*;
+import java.util.*;
+
+public class IO {
+
+	public static void copy(Reader r, Writer w) throws IOException {
+		try {
+			char buffer[] = new char[8000];
+			int size = r.read(buffer);
+			while (size > 0) {
+				w.write(buffer, 0, size);
+				size = r.read(buffer);
+			}
+		} finally {
+			r.close();
+			w.flush();
+		}
+	}
+
+	public static void copy(InputStream r, Writer w) throws IOException {
+		copy(r, w, "UTF-8");
+	}
+
+	public static void copy(byte []r, Writer w) throws IOException {
+		copy( new ByteArrayInputStream(r), w, "UTF-8");
+	}
+
+	public static void copy(byte []r, OutputStream w) throws IOException {
+		copy( new ByteArrayInputStream(r), w);
+	}
+
+	public static void copy(InputStream r, Writer w, String charset) throws IOException {
+		try {
+			InputStreamReader isr = new InputStreamReader(r, charset);
+			copy(isr, w);
+		} finally {
+			r.close();
+		}
+	}
+
+	public static void copy(Reader r, OutputStream o) throws IOException {
+		copy(r, o, "UTF-8");
+	}
+
+	public static void copy(Reader r, OutputStream o, String charset) throws IOException {
+		try {
+			OutputStreamWriter osw = new OutputStreamWriter(o, charset);
+			copy(r, osw);
+		} finally {
+			r.close();
+		}
+	}
+
+	public static void copy(InputStream in, OutputStream out) throws IOException {
+		DataOutputStream dos = new DataOutputStream(out);
+		copy(in, (DataOutput) dos);
+		out.flush();
+	}
+
+	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(URL in, MessageDigest md) throws IOException {
+		copy(in.openStream(), md);
+	}
+
+	public static void copy(File in, MessageDigest md) throws IOException {
+		copy(new FileInputStream(in), md);
+	}
+
+	public static void copy(URLConnection in, MessageDigest md) throws IOException {
+		copy(in.getInputStream(), md);
+	}
+
+
+	public static void copy(InputStream in, MessageDigest md) throws IOException {
+		byte[] buffer = new byte[10000];
+		try {
+			int size = in.read(buffer);
+			while (size > 0) {
+				md.update(buffer, 0, size);
+				size = in.read(buffer);
+			}
+		} finally {
+			in.close();
+		}
+	}
+
+	public static void copy(URL url, File file) throws IOException {
+		URLConnection c = url.openConnection();
+		copy(c, file);
+	}
+
+	public static void copy(URLConnection c, File file) throws IOException {
+		copy(c.getInputStream(), file);
+	}
+
+	public static void copy(InputStream in, URL out) throws IOException {
+		copy(in, out, null);
+	}
+
+	public static void copy(InputStream in, URL out, String method) throws IOException {
+		URLConnection c = out.openConnection();
+		if (c instanceof HttpURLConnection && method != null) {
+			HttpURLConnection http = (HttpURLConnection) c;
+			http.setRequestMethod(method);
+		}
+		c.setDoOutput(true);
+		copy(in, c.getOutputStream());
+	}
+
+	public static void copy(File a, File b) throws IOException {
+		if (a.isFile()) {
+			FileOutputStream out = new FileOutputStream(b);
+			try {
+				copy(new FileInputStream(a), out);
+			} finally {
+				out.close();
+			}
+		} else if (a.isDirectory()) {
+			b.mkdirs();
+			if (!b.isDirectory())
+				throw new IllegalArgumentException(
+						"target directory for a directory must be a directory: " + b);
+			File subs[] = a.listFiles();
+			for (File sub : subs) {
+				copy(sub, new File(b, sub.getName()));
+			}
+		} else
+			throw new FileNotFoundException("During copy: " + a.toString());
+	}
+
+	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(URL a) throws IOException {
+		return collect(a, "UTF-8");
+	}
+
+	public static String collect(File a) throws IOException {
+		return collect(a, "UTF-8");
+	}
+
+	public static String collect(String a) throws IOException {
+		return collect(new File(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();
+		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 long drain(InputStream in) throws IOException {
+		long result = 0;
+		byte[] buffer = new byte[10000];
+		try {
+			int size = in.read(buffer);
+			while (size >= 0) {
+				result += size;
+				size = in.read(buffer);
+			}
+		} finally {
+			in.close();
+		}
+		return result;
+	}
+
+	public void copy(Collection<?> c, OutputStream out) throws IOException {
+		Writer w = new OutputStreamWriter(out,"UTF-8");
+		PrintWriter ps = new PrintWriter(w);
+		for (Object o : c) {
+			ps.println(o);
+		}
+		ps.flush();
+		w.flush();
+	}
+
+	public static Throwable close(Closeable in) {
+		if ( in == null)
+			return null;
+		
+		try {
+			in.close();
+			return null;
+		} catch (Throwable e) {
+			return e;
+		}
+	}
+
+	public static URL toURL(String s, File base) throws MalformedURLException {
+		int n = s.indexOf(':');
+		if (n > 0 && n < 10) {
+			// is url
+			return new URL(s);
+		}
+		return getFile(base, s).toURI().toURL();
+	}
+
+	public static void store(Object o, File out) throws IOException {
+		store(o, out, "UTF-8");
+	}
+
+	public static void store(Object o, File out, String encoding) throws IOException {
+		FileOutputStream fout = new FileOutputStream(out);
+		try {
+			store(o, fout, encoding);
+		} finally {
+			fout.close();
+		}
+	}
+
+	public static void store(Object o, OutputStream fout) throws UnsupportedEncodingException,
+			IOException {
+		store(o, fout, "UTF-8");
+	}
+
+	public static void store(Object o, OutputStream fout, String encoding)
+			throws UnsupportedEncodingException, IOException {
+		String s;
+
+		if (o == null)
+			s = "";
+		else
+			s = o.toString();
+
+		try {
+			fout.write(s.getBytes(encoding));
+		} finally {
+			fout.close();
+		}
+	}
+
+	public static InputStream stream(String s) {
+		try {
+			return new ByteArrayInputStream(s.getBytes("UTF-8"));
+		} catch (Exception e) {
+			// Ignore
+			return null;
+		}
+	}
+
+	public static InputStream stream(String s, String encoding) throws UnsupportedEncodingException {
+		return new ByteArrayInputStream(s.getBytes(encoding));
+	}
+
+	public static InputStream stream(File s) throws FileNotFoundException {
+		return new FileInputStream(s);
+	}
+
+	public static InputStream stream(URL s) throws IOException {
+		return s.openStream();
+	}
+
+	public static Reader reader(String s) {
+		return new StringReader(s);
+	}
+
+
+	public static BufferedReader reader(File f, String encoding) throws IOException {
+		return reader( new FileInputStream(f), encoding);
+	}
+	
+	public static BufferedReader reader(File f) throws IOException {
+		return reader(f,"UTF-8");
+	}
+	
+	public static PrintWriter writer(File f, String encoding) throws IOException {
+		return writer( new FileOutputStream(f),encoding);
+	}
+	
+	public static PrintWriter writer(File f) throws IOException {
+		return writer(f, "UTF-8");
+	}
+	
+	public static PrintWriter writer(OutputStream out, String encoding) throws IOException {
+		return new PrintWriter( new OutputStreamWriter( out,encoding));
+	}
+	public static BufferedReader reader(InputStream in, String encoding) throws IOException {
+		return new BufferedReader( new InputStreamReader(in, encoding));
+	}
+	
+	public static BufferedReader reader(InputStream in) throws IOException {
+		return reader(in, "UTF-8");
+	}
+	public static PrintWriter writer(OutputStream out) throws IOException {
+		return writer(out, "UTF-8");
+	}
+}
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..897578f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/io/packageinfo
@@ -0,0 +1 @@
+version 1.2.0
diff --git a/bundleplugin/src/main/java/aQute/lib/json/ArrayHandler.java b/bundleplugin/src/main/java/aQute/lib/json/ArrayHandler.java
new file mode 100644
index 0000000..62af4a7
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/ArrayHandler.java
@@ -0,0 +1,40 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+public class ArrayHandler extends Handler {
+	Type	componentType;
+
+	ArrayHandler(Class< ? > rawClass, Type componentType) {
+		this.componentType = componentType;
+	}
+
+	@Override
+	void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException, Exception {
+		app.append("[");
+		String del = "";
+		int l = Array.getLength(object);
+		for (int i = 0; i < l; i++) {
+			app.append(del);
+			app.encode(Array.get(object, i), componentType, visited);
+			del = ",";
+		}
+		app.append("]");
+	}
+
+	@Override
+	Object decodeArray(Decoder r) throws Exception {
+		ArrayList<Object> list = new ArrayList<Object>();
+		r.codec.parseArray(list, componentType, r);
+		Object array = Array.newInstance(r.codec.getRawClass(componentType),
+				list.size());
+		int n = 0;
+		for (Object o : list)
+			Array.set(array, n++, o);
+
+		return array;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/BooleanHandler.java b/bundleplugin/src/main/java/aQute/lib/json/BooleanHandler.java
new file mode 100644
index 0000000..d3b56ea
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/BooleanHandler.java
@@ -0,0 +1,30 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+public class BooleanHandler extends Handler {
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException, Exception {
+		app.append( object.toString());
+	}
+	
+	@Override Object decode(boolean s) {
+		return s;
+	}
+
+	@Override Object decode(String s) {
+		return Boolean.parseBoolean(s);
+	}
+
+	@Override Object decode(Number s) {
+		return s.intValue() != 0;
+	}
+
+	@Override Object decode() {
+		return false;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/ByteArrayHandler.java b/bundleplugin/src/main/java/aQute/lib/json/ByteArrayHandler.java
new file mode 100644
index 0000000..65f5f74
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/ByteArrayHandler.java
@@ -0,0 +1,30 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import aQute.lib.base64.*;
+
+public class ByteArrayHandler extends Handler {
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException, Exception {
+		StringHandler.string(app, Base64.encodeBase64((byte[]) object));
+	}
+
+	@Override Object decodeArray(Decoder r) throws Exception {
+		ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+		ArrayList<Object> list = new ArrayList<Object>();
+		r.codec.parseArray(list, Byte.class, r);
+		for (Object b : list) {
+			out.write(((Byte) b).byteValue());
+		}
+		return out.toByteArray();
+	}
+
+	@Override Object decode(String s) throws Exception {
+		return Base64.decodeBase64(s);
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/CharacterHandler.java b/bundleplugin/src/main/java/aQute/lib/json/CharacterHandler.java
new file mode 100644
index 0000000..7009e0c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/CharacterHandler.java
@@ -0,0 +1,31 @@
+package aQute.lib.json;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+public class CharacterHandler extends Handler {
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws Exception {	
+		Character c  = (Character) object;
+		int v = (int) c.charValue();
+		app.append( v+"" );
+	}
+	
+	@Override Object decode(boolean s) {
+		return s ? 't' : 'f';
+	}
+
+	@Override Object decode(String s) {
+		return (char) Integer.parseInt(s);
+	}
+
+	@Override Object decode(Number s) {
+		return (char) s.shortValue();
+	}
+
+	@Override Object decode() {
+		return 0;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/CollectionHandler.java b/bundleplugin/src/main/java/aQute/lib/json/CollectionHandler.java
new file mode 100644
index 0000000..3fb14ee
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/CollectionHandler.java
@@ -0,0 +1,57 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+public class CollectionHandler extends Handler {
+	Class<?>	rawClass;
+	Type		componentType;
+	
+	CollectionHandler(Class<?> rawClass, Type componentType) {
+		this.componentType = componentType;
+		if (rawClass.isInterface()) {
+			if (rawClass.isAssignableFrom(ArrayList.class))
+				rawClass = ArrayList.class;
+			else if (rawClass.isAssignableFrom(LinkedList.class))
+				rawClass = LinkedList.class;
+			else if (rawClass.isAssignableFrom(HashSet.class))
+				rawClass = HashSet.class;
+			else if (rawClass.isAssignableFrom(TreeSet.class))
+				rawClass = TreeSet.class;
+			else if (rawClass.isAssignableFrom(Vector.class))
+				rawClass = Vector.class;
+			else if (rawClass.isAssignableFrom(ConcurrentLinkedQueue.class))
+				rawClass = ConcurrentLinkedQueue.class;
+			else if (rawClass.isAssignableFrom(CopyOnWriteArrayList.class))
+				rawClass = CopyOnWriteArrayList.class;
+			else if (rawClass.isAssignableFrom(CopyOnWriteArraySet.class))
+				rawClass = CopyOnWriteArraySet.class;
+			else
+				throw new IllegalArgumentException("Unknown interface type for collection: "
+						+ rawClass);
+		}
+		this.rawClass = rawClass;
+	}
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException, Exception {
+		Collection<?> collection = (Collection<?>) object;
+
+		app.append("[");
+		String del = "";
+		for (Object o : collection) {
+			app.append(del);
+			app.encode(o, componentType, visited);
+			del = ",";
+		}
+		app.append("]");
+	}
+
+	@SuppressWarnings("unchecked") @Override Object decodeArray(Decoder r) throws Exception {
+		Collection<Object> c = (Collection<Object>) rawClass.newInstance();
+		r.codec.parseArray(c, componentType, r);
+		return c;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/DateHandler.java b/bundleplugin/src/main/java/aQute/lib/json/DateHandler.java
new file mode 100644
index 0000000..d4f262e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/DateHandler.java
@@ -0,0 +1,30 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.text.*;
+import java.util.*;
+
+public class DateHandler extends Handler {
+	final static SimpleDateFormat	sdf	= new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException, Exception {
+		String s;
+		synchronized (sdf) {
+			s = sdf.format((Date) object);
+		}
+		StringHandler.string(app, s);
+	}
+
+	@Override Object decode(String s) throws Exception {
+		synchronized (sdf) {
+			return sdf.parse(s);
+		}
+	}
+
+	@Override Object decode(Number s) throws Exception {
+		return new Date(s.longValue());
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/Decoder.java b/bundleplugin/src/main/java/aQute/lib/json/Decoder.java
new file mode 100644
index 0000000..3cbed4b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/Decoder.java
@@ -0,0 +1,137 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.security.*;
+import java.util.*;
+
+public class Decoder implements Closeable {
+	final JSONCodec		codec;
+	Reader				reader;
+	int					current;
+	MessageDigest		digest;
+	Map<String, Object>	extra;
+	String encoding = "UTF-8";
+	
+	boolean strict;
+
+	Decoder(JSONCodec codec) {
+		this.codec = codec;
+	}
+
+	public Decoder from(File file) throws Exception {
+		return from(new FileInputStream(file));
+	}
+
+	public Decoder from(InputStream in) throws Exception {
+		return from(new InputStreamReader(in, encoding));
+	}
+	
+	public Decoder charset(String encoding) {
+		this.encoding = encoding;
+		return this;
+	}
+	
+	public Decoder strict() {
+		this.strict = true;
+		return this;
+	}
+
+	public Decoder from(Reader in) throws Exception {
+		reader = in;
+		read();
+		return this;
+	}
+
+	public Decoder faq(String in) throws Exception {
+		return from(in.replace('\'', '"'));
+	}
+
+	public Decoder from(String in) throws Exception {
+		return from(new StringReader(in));
+	}
+
+	public Decoder mark() throws NoSuchAlgorithmException {
+		if (digest == null)
+			digest = MessageDigest.getInstance("SHA1");
+		digest.reset();
+		return this;
+	}
+
+	public byte[] digest() {
+		if (digest == null)
+			return null;
+
+		return digest.digest();
+	}
+
+	@SuppressWarnings("unchecked") public <T> T get(Class<T> clazz) throws Exception {
+		return (T) codec.decode(clazz, this);
+	}
+
+	public Object get(Type type) throws Exception {
+		return codec.decode(type, this);
+	}
+
+	public Object get() throws Exception {
+		return codec.decode(null, this);
+	}
+
+	int read() throws Exception {
+		current = reader.read();
+		if (digest != null) {
+			digest.update((byte) (current / 256));
+			digest.update((byte) (current % 256));
+		}
+		return current;
+	}
+
+	int current() {
+		return current;
+	}
+
+	/**
+	 * Skip any whitespace.
+	 * 
+	 * @return
+	 * @throws Exception
+	 */
+	int skipWs() throws Exception {
+		while (Character.isWhitespace(current()))
+			read();
+		return current();
+	}
+
+	/**
+	 * Skip any whitespace.
+	 * 
+	 * @return
+	 * @throws Exception
+	 */
+	int next() throws Exception {
+		read();
+		return skipWs();
+	}
+
+	void expect(String s) throws Exception {
+		for (int i = 0; i < s.length(); i++)
+			if (!(s.charAt(i) == read()))
+				throw new IllegalArgumentException("Expected " + s + " but got something different");
+		read();
+	}
+
+	public boolean isEof() throws Exception {
+		int c = skipWs();
+		return c < 0;
+	}
+
+	public void close() throws IOException {
+		reader.close();
+	}
+
+	public Map<String, Object> getExtra() {
+		if (extra == null)
+			extra = new HashMap<String, Object>();
+		return extra;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/Encoder.java b/bundleplugin/src/main/java/aQute/lib/json/Encoder.java
new file mode 100644
index 0000000..09990ed
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/Encoder.java
@@ -0,0 +1,112 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.security.*;
+import java.util.*;
+
+public class Encoder implements Appendable, Closeable, Flushable {
+	final JSONCodec	codec;
+	Appendable		app;
+	MessageDigest	digest;
+	boolean			writeDefaults;
+	String			encoding	= "UTF-8";
+
+	Encoder(JSONCodec codec) {
+		this.codec = codec;
+	}
+
+	public Encoder put(Object object) throws Exception {
+		if (app == null)
+			to();
+
+		codec.encode(this, object, null, new IdentityHashMap<Object, Type>());
+		return this;
+	}
+
+	public Encoder mark() throws NoSuchAlgorithmException {
+		if (digest == null)
+			digest = MessageDigest.getInstance("SHA1");
+		digest.reset();
+		return this;
+	}
+
+	public byte[] digest() throws NoSuchAlgorithmException, IOException {
+		if (digest == null)
+			return null;
+		append('\n');
+		return digest.digest();
+	}
+
+	public Encoder to() throws IOException {
+		to(new StringWriter());
+		return this;
+	}
+
+	public Encoder to(File file) throws IOException {
+		return to(new FileOutputStream(file));
+	}
+
+	public Encoder charset(String encoding) {
+		this.encoding = encoding;
+		return this;
+	}
+
+	public Encoder to(OutputStream out) throws IOException {
+		return to(new OutputStreamWriter(out, encoding));
+	}
+
+	public Encoder to(Appendable out) throws IOException {
+		app = out;
+		return this;
+	}
+
+	public Appendable append(char c) throws IOException {
+		if (digest != null) {
+			digest.update((byte) (c / 256));
+			digest.update((byte) (c % 256));
+		}
+		app.append(c);
+		return this;
+	}
+
+	public Appendable append(CharSequence sq) throws IOException {
+		return append(sq, 0, sq.length());
+	}
+
+	public Appendable append(CharSequence sq, int start, int length) throws IOException {
+		if (digest != null) {
+			for (int i = start; i < length; i++) {
+				char c = sq.charAt(i);
+				digest.update((byte) (c / 256));
+				digest.update((byte) (c % 256));
+			}
+		}
+		app.append(sq, start, length);
+		return this;
+	}
+
+	public String toString() {
+		return app.toString();
+	}
+
+	public void close() throws IOException {
+		if (app != null && app instanceof Closeable)
+			((Closeable) app).close();
+	}
+
+	void encode(Object object, Type type, Map<Object, Type> visited) throws Exception {
+		codec.encode(this, object, type, visited);
+	}
+
+	public Encoder writeDefaults() {
+		writeDefaults = true;
+		return this;
+	}
+
+	public void flush() throws IOException {
+		if (app instanceof Flushable) {
+			((Flushable) app).flush();
+		}
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/EnumHandler.java b/bundleplugin/src/main/java/aQute/lib/json/EnumHandler.java
new file mode 100644
index 0000000..dbdb492
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/EnumHandler.java
@@ -0,0 +1,24 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+public class EnumHandler extends Handler {
+	@SuppressWarnings("rawtypes")
+	final Class				type;
+
+	public EnumHandler(Class<?> type) {
+		this.type = type;
+	}
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException, Exception {
+		StringHandler.string(app, object.toString());
+	}
+
+	@SuppressWarnings("unchecked") Object decode(String s) throws Exception {
+		return Enum.valueOf(type, s);
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/FileHandler.java b/bundleplugin/src/main/java/aQute/lib/json/FileHandler.java
new file mode 100644
index 0000000..2f0eea5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/FileHandler.java
@@ -0,0 +1,38 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import aQute.lib.base64.*;
+
+public class FileHandler extends Handler {
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException, Exception {
+		File f = (File) object;
+		if ( !f.isFile())
+			throw new RuntimeException("Encoding a file requires the file to exist and to be a normal file " + f );
+		
+		FileInputStream in = new FileInputStream(f);
+		try {
+			app.append('"');
+			Base64.encode(in, app);
+			app.append('"');
+		} finally {
+			in.close();
+		}
+	}
+
+	Object decode(String s) throws Exception {
+		File tmp = File.createTempFile("json", ".bin");
+		FileOutputStream fout = new FileOutputStream(tmp);
+		try {
+			Base64.decode(new StringReader(s), fout);
+		} finally {
+			fout.close();
+		}
+		return tmp;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/Handler.java b/bundleplugin/src/main/java/aQute/lib/json/Handler.java
new file mode 100644
index 0000000..18957e8
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/Handler.java
@@ -0,0 +1,35 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+abstract class Handler {
+	abstract void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException, Exception;
+
+	Object decodeObject(Decoder isr) throws Exception {
+		throw new UnsupportedOperationException("Cannot be mapped to object " + this);
+	}
+
+	Object decodeArray(Decoder isr) throws Exception {
+		throw new UnsupportedOperationException("Cannot be mapped to array " + this);
+	}
+
+	Object decode(String s) throws Exception {
+		throw new UnsupportedOperationException("Cannot be mapped to string " + this);
+	}
+
+	Object decode(Number s) throws Exception {
+		throw new UnsupportedOperationException("Cannot be mapped to number " + this);
+	}
+
+	Object decode(boolean s) {
+		throw new UnsupportedOperationException("Cannot be mapped to boolean " + this);
+	}
+
+	Object decode() {
+		return null;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/JSONCodec.java b/bundleplugin/src/main/java/aQute/lib/json/JSONCodec.java
new file mode 100644
index 0000000..a45b5b4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/JSONCodec.java
@@ -0,0 +1,481 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+/**
+ * This is a simple JSON Coder and Encoder that uses the Java type system to
+ * convert data objects to JSON and JSON to (type safe) Java objects. The
+ * conversion is very much driven by classes and their public fields. Generic
+ * information, when present is taken into account. </p> Usage patterns to
+ * encode:
+ * 
+ * <pre>
+ *  JSONCoder codec = new JSONCodec(); // 
+ * 	assert "1".equals( codec.enc().to().put(1).toString());
+ * 	assert "[1,2,3]".equals( codec.enc().to().put(Arrays.asList(1,2,3).toString());
+ * 
+ *  Map m = new HashMap();
+ *  m.put("a", "A");
+ * 	assert "{\"a\":\"A\"}".equals( codec.enc().to().put(m).toString());
+ * 
+ *  static class D { public int a; }
+ *  D d = new D();
+ *  d.a = 41;
+ *  assert "{\"a\":41}".equals( codec.enc().to().put(d).toString());
+ * </pre>
+ * 
+ * It is possible to redirect the encoder to another output (default is a
+ * string). See {@link Encoder#to()},{@link Encoder#to(File))},
+ * {@link Encoder#to(OutputStream)}, {@link Encoder#to(Appendable))}. To reset
+ * the string output call {@link Encoder#to()}.
+ * <p/>
+ * This Codec class can be used in a concurrent environment. The Decoders and
+ * Encoders, however, must only be used in a single thread.
+ */
+public class JSONCodec {
+	final static String								START_CHARACTERS	= "[{\"-0123456789tfn";
+
+	// Handlers
+	private final static WeakHashMap<Type, Handler>	handlers			= new WeakHashMap<Type, Handler>();
+	private static StringHandler					sh					= new StringHandler();
+	private static BooleanHandler					bh					= new BooleanHandler();
+	private static CharacterHandler					ch					= new CharacterHandler();
+	private static CollectionHandler				dch					= new CollectionHandler(
+																				ArrayList.class,
+																				Object.class);
+	private static SpecialHandler					sph					= new SpecialHandler(
+																				Pattern.class,
+																				null, null);
+	private static DateHandler						sdh					= new DateHandler();
+	private static FileHandler						fh					= new FileHandler();
+	private static ByteArrayHandler					byteh				= new ByteArrayHandler();
+
+	/**
+	 * Create a new Encoder with the state and appropriate API.
+	 * 
+	 * @return an Encoder
+	 */
+	public Encoder enc() {
+		return new Encoder(this);
+	}
+
+	/**
+	 * Create a new Decoder with the state and appropriate API.
+	 * 
+	 * @return a Decoder
+	 */
+	public Decoder dec() {
+		return new Decoder(this);
+	}
+
+	/*
+	 * Work horse encode methods, all encoding ends up here.
+	 */
+	void encode(Encoder app, Object object, Type type, Map<Object, Type> visited) throws Exception {
+
+		// Get the null out of the way
+
+		if (object == null) {
+			app.append("null");
+			return;
+		}
+
+		// If we have no type or the type is Object.class
+		// we take the type of the object itself. Normally types
+		// come from declaration sites (returns, fields, methods, etc)
+		// and contain generic info.
+
+		if (type == null || type == Object.class)
+			type = object.getClass();
+
+		// Dispatch to the handler who knows how to handle the given type.
+		Handler h = getHandler(type);
+		h.encode(app, object, visited);
+	}
+
+	/*
+	 * This method figures out which handler should handle the type specific
+	 * stuff. It returns a handler for each type. If no appropriate handler
+	 * exists, it will create one for the given type. There are actually quite a
+	 * lot of handlers since Java is not very object oriented.
+	 * 
+	 * @param type
+	 * 
+	 * @return
+	 * 
+	 * @throws Exception
+	 */
+	Handler getHandler(Type type) throws Exception {
+
+		// First the static hard coded handlers for the common types.
+
+		if (type == String.class)
+			return sh;
+
+		if (type == Boolean.class || type == boolean.class)
+			return bh;
+
+		if (type == byte[].class)
+			return byteh;
+
+		if (Character.class == type || char.class == type)
+			return ch;
+
+		if (Pattern.class == type)
+			return sph;
+
+		if (Date.class == type)
+			return sdh;
+
+		if (File.class == type)
+			return fh;
+
+		Handler h;
+		synchronized (handlers) {
+			h = handlers.get(type);
+		}
+
+		if (h != null)
+			return h;
+
+		if (type instanceof Class) {
+
+			Class<?> clazz = (Class<?>) type;
+
+			if (Enum.class.isAssignableFrom(clazz))
+				h = new EnumHandler(clazz);
+			else if (Collection.class.isAssignableFrom(clazz)) // A Non Generic
+																// collection
+
+				h = dch;
+			else if (clazz.isArray()) // Non generic array
+				h = new ArrayHandler(clazz, clazz.getComponentType());
+			else if (Map.class.isAssignableFrom(clazz)) // A Non Generic map
+				h = new MapHandler(clazz, Object.class, Object.class);
+			else if (Number.class.isAssignableFrom(clazz) || clazz.isPrimitive())
+				h = new NumberHandler(clazz);
+			else {
+				Method valueOf = null;
+				Constructor<?> constructor = null;
+
+				try {
+					constructor = clazz.getConstructor(String.class);
+				} catch (Exception e) {
+					// Ignore
+				}
+				try {
+					valueOf = clazz.getMethod("valueOf", String.class);
+				} catch (Exception e) {
+					// Ignore
+				}
+				if (constructor != null || valueOf != null)
+					h = new SpecialHandler(clazz, constructor, valueOf);
+				else
+					h = new ObjectHandler(this, clazz); // Hmm, might not be a
+														// data class ...
+			}
+
+		} else {
+
+			// We have generic information available
+			// We only support generics on Collection, Map, and arrays
+
+			if (type instanceof ParameterizedType) {
+				ParameterizedType pt = (ParameterizedType) type;
+				Type rawType = pt.getRawType();
+				if (rawType instanceof Class) {
+					Class<?> rawClass = (Class<?>) rawType;
+					if (Collection.class.isAssignableFrom(rawClass))
+						h = new CollectionHandler(rawClass, pt.getActualTypeArguments()[0]);
+					else if (Map.class.isAssignableFrom(rawClass))
+						h = new MapHandler(rawClass, pt.getActualTypeArguments()[0],
+								pt.getActualTypeArguments()[1]);
+					else
+						throw new IllegalArgumentException(
+								"Found a parameterized type that is not a map or collection");
+				}
+			} else if (type instanceof GenericArrayType) {
+				GenericArrayType gat = (GenericArrayType) type;
+				h = new ArrayHandler(getRawClass(type), gat.getGenericComponentType());
+			} else
+				throw new IllegalArgumentException(
+						"Found a parameterized type that is not a map or collection");
+		}
+		synchronized (handlers) {
+			// We might actually have duplicates
+			// but who cares? They should be identical
+			handlers.put(type, h);
+		}
+		return h;
+	}
+
+	Object decode(Type type, Decoder isr) throws Exception {
+		int c = isr.skipWs();
+		Handler h;
+
+		if (type == null || type == Object.class) {
+
+			// Establish default behavior when we run without
+			// type information
+
+			switch (c) {
+			case '{':
+				type = LinkedHashMap.class;
+				break;
+
+			case '[':
+				type = ArrayList.class;
+				break;
+
+			case '"':
+				return parseString(isr);
+
+			case 'n':
+				isr.expect("ull");
+				return null;
+
+			case 't':
+				isr.expect("rue");
+				return true;
+
+			case 'f':
+				isr.expect("alse");
+				return false;
+
+			case '0':
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+			case '-':
+				return parseNumber(isr);
+
+			default:
+				throw new IllegalArgumentException("Invalid character at begin of token: "
+						+ (char) c);
+			}
+		}
+
+		h = getHandler(type);
+
+		switch (c) {
+		case '{':
+			return h.decodeObject(isr);
+
+		case '[':
+			return h.decodeArray(isr);
+
+		case '"':
+			return h.decode(parseString(isr));
+
+		case 'n':
+			isr.expect("ull");
+			return h.decode();
+
+		case 't':
+			isr.expect("rue");
+			return h.decode(Boolean.TRUE);
+
+		case 'f':
+			isr.expect("alse");
+			return h.decode(Boolean.FALSE);
+
+		case '0':
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+		case '-':
+			return h.decode(parseNumber(isr));
+
+		default:
+			throw new IllegalArgumentException("Unexpected character in input stream: " + (char) c);
+		}
+	}
+
+	String parseString(Decoder r) throws Exception {
+		assert r.current() == '"';
+
+		int c = r.next(); // skip first "
+
+		StringBuilder sb = new StringBuilder();
+		while (c != '"') {
+			if (c < 0 || Character.isISOControl(c))
+				throw new IllegalArgumentException(
+						"JSON strings may not contain control characters: " + r.current());
+
+			if (c == '\\') {
+				c = r.read();
+				switch (c) {
+				case '"':
+				case '\\':
+				case '/':
+					sb.append((char)c);
+					break;
+
+				case 'b':
+					sb.append('\b');
+					break;
+
+				case 'f':
+					sb.append('\f');
+					break;
+				case 'n':
+					sb.append('\n');
+					break;
+				case 'r':
+					sb.append('\r');
+					break;
+				case 't':
+					sb.append('\t');
+					break;
+				case 'u':
+					int a3 = hexDigit(r.read()) << 12;
+					int a2 = hexDigit(r.read()) << 8;
+					int a1 = hexDigit(r.read()) << 4;
+					int a0 = hexDigit(r.read()) << 0;
+					c = a3 + a2 + a1 + a0;
+					sb.append((char) c);
+					break;
+
+				default:
+					throw new IllegalArgumentException(
+							"The only characters after a backslash are \", \\, b, f, n, r, t, and u but got "
+									+ c);
+				}
+			} else
+				sb.append((char) c);
+
+			c = r.read();
+		}
+		assert c == '"';
+		r.read(); // skip quote
+		return sb.toString();
+	}
+
+	private int hexDigit(int c) throws EOFException {
+		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("Invalid hex character: " + c);
+	}
+
+	private Number parseNumber(Decoder r) throws Exception {
+		StringBuilder sb = new StringBuilder();
+		boolean d = false;
+
+		if (r.current() == '-') {
+			sb.append('-');
+			r.read();
+		}
+
+		int c = r.current();
+		if (c == '0') {
+			sb.append('0');
+			c = r.read();
+		} else if (c >= '1' && c <= '9') {
+			sb.append((char) c);
+			c = r.read();
+
+			while (c >= '0' && c <= '9') {
+				sb.append((char) c);
+				c = r.read();
+			}
+		} else
+			throw new IllegalArgumentException("Expected digit");
+
+		if (c == '.') {
+			d = true;
+			sb.append('.');
+			c = r.read();
+			while (c >= '0' && c <= '9') {
+				sb.append((char) c);
+				c = r.read();
+			}
+		}
+		if (c == 'e' || c == 'E') {
+			d = true;
+			sb.append('e');
+			c = r.read();
+			if (c == '+') {
+				sb.append('+');
+				c = r.read();
+			} else if (c == '-') {
+				sb.append('-');
+				c = r.read();
+			}
+			while (c >= '0' && c <= '9') {
+				sb.append((char) c);
+				c = r.read();
+			}
+		}
+		if (d)
+			return Double.parseDouble(sb.toString());
+		long l = Long.parseLong(sb.toString());
+		if (l > Integer.MAX_VALUE || l < Integer.MIN_VALUE)
+			return l;
+		return (int) l;
+	}
+
+	void parseArray(Collection<Object> list, Type componentType, Decoder r) throws Exception {
+		assert r.current() == '[';
+		int c = r.next();
+		while (START_CHARACTERS.indexOf(c) >= 0) {
+			Object o = decode(componentType, r);
+			list.add(o);
+
+			c = r.skipWs();
+			if (c == ']')
+				break;
+
+			if (c == ',') {
+				c = r.next();
+				continue;
+			}
+
+			throw new IllegalArgumentException(
+					"Invalid character in parsing list, expected ] or , but found " + (char) c);
+		}
+		assert r.current() == ']';
+		r.read(); // skip closing
+	}
+
+	@SuppressWarnings("rawtypes")
+	Class<?> getRawClass(Type type) {
+		if (type instanceof Class)
+			return (Class) type;
+
+		if (type instanceof ParameterizedType)
+			return getRawClass(((ParameterizedType) type).getRawType());
+
+		if (type instanceof GenericArrayType) {
+			Type subType = ((GenericArrayType) type).getGenericComponentType();
+			Class c = getRawClass(subType);
+			return Array.newInstance(c, 0).getClass();
+		}
+
+		throw new IllegalArgumentException(
+				"Does not support generics beyond Parameterized Type  and GenericArrayType, got "
+						+ type);
+	}
+
+}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/lib/json/MapHandler.java b/bundleplugin/src/main/java/aQute/lib/json/MapHandler.java
new file mode 100644
index 0000000..5a413b6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/MapHandler.java
@@ -0,0 +1,91 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+public class MapHandler extends Handler {
+	final Class<?>	rawClass;
+	final Type		keyType;
+	final Type		valueType;
+
+	MapHandler(Class<?> rawClass, Type keyType, Type valueType) {
+		this.keyType = keyType;
+		this.valueType = valueType;
+		if (rawClass.isInterface()) {
+			if (rawClass.isAssignableFrom(HashMap.class))
+				rawClass = HashMap.class;
+			else if (rawClass.isAssignableFrom(TreeMap.class))
+				rawClass = TreeMap.class;
+			else if (rawClass.isAssignableFrom(Hashtable.class))
+				rawClass = Hashtable.class;
+			else if (rawClass.isAssignableFrom(LinkedHashMap.class))
+				rawClass = LinkedHashMap.class;
+			else
+				throw new IllegalArgumentException("Unknown map interface: " + rawClass);
+		}
+		this.rawClass = rawClass;
+	}
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException, Exception {
+		Map<?, ?> map = (Map<?, ?>) object;
+
+		app.append("{");
+		String del = "";
+		for (Map.Entry<?, ?> e : map.entrySet()) {
+			app.append(del);
+			String key;
+			if (e.getKey() != null && (keyType == String.class || keyType == Object.class))
+				key = e.getKey().toString();
+			else {
+				key = app.codec.enc().put(e.getKey()).toString();
+			}
+			StringHandler.string(app, key);
+			app.append(":");
+			app.encode(e.getValue(), valueType, visited);
+			del = ",";
+		}
+		app.append("}");
+	}
+
+	@SuppressWarnings("unchecked") @Override Object decodeObject(Decoder r) throws Exception {
+		assert r.current() == '{';
+		
+		Map<Object, Object> map = (Map<Object, Object>) rawClass.newInstance();
+		
+		int c = r.next();
+		while (JSONCodec.START_CHARACTERS.indexOf(c) >= 0) {
+			Object key = r.codec.parseString(r);
+			if ( !(keyType == null || keyType == Object.class)) {
+				Handler h = r.codec.getHandler(keyType);
+				key = h.decode((String)key);
+			}
+			
+			c = r.skipWs();
+			if ( c != ':')
+				throw new IllegalArgumentException("Expected ':' but got " + (char) c);
+
+			c = r.next();
+			Object value = r.codec.decode(valueType, r);
+			map.put(key, value);
+
+			c = r.skipWs();
+			
+			if (c == '}') 
+				break;
+
+			if (c == ',') {
+				c = r.next();
+				continue;
+			}
+
+			throw new IllegalArgumentException(
+					"Invalid character in parsing list, expected } or , but found " + (char) c);
+		}
+		assert r.current() == '}';
+		r.read(); // skip closing
+		return map;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/NumberHandler.java b/bundleplugin/src/main/java/aQute/lib/json/NumberHandler.java
new file mode 100644
index 0000000..644d49a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/NumberHandler.java
@@ -0,0 +1,71 @@
+package aQute.lib.json;
+
+import java.lang.reflect.*;
+import java.math.*;
+import java.util.*;
+
+public class NumberHandler extends Handler {
+	final Class<?>	type;
+
+	NumberHandler(Class<?> clazz) {
+		this.type = clazz;
+	}
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws Exception {
+		String s = object.toString();
+		if ( s.endsWith(".0"))
+			s  = s.substring(0,s.length()-2);
+		
+		app.append(s);
+	}
+
+	@Override Object decode(boolean s) {
+		return decode(s ? 1d : 0d);
+	}
+
+	@Override Object decode(String s) {
+		double d = Double.parseDouble(s);
+		return decode(d);
+	}
+
+	@Override Object decode() {
+		return decode(0d);
+	}
+
+	@Override Object decode(Number s) {
+		double dd = s.doubleValue();
+		
+		if (type == double.class || type == Double.class)
+			return s.doubleValue();
+
+		if ((type == int.class || type == Integer.class)
+				&& within(dd, Integer.MIN_VALUE, Integer.MAX_VALUE))
+			return s.intValue();
+
+		if ((type == long.class || type == Long.class) && within(dd, Long.MIN_VALUE, Long.MAX_VALUE))
+			return s.longValue();
+
+		if ((type == byte.class || type == Byte.class) && within(dd, Byte.MIN_VALUE, Byte.MAX_VALUE))
+			return s.byteValue();
+
+		if ((type == short.class || type == Short.class)
+				&& within(dd, Short.MIN_VALUE, Short.MAX_VALUE))
+			return s.shortValue();
+
+		if (type == float.class || type == Float.class)
+			return s.floatValue();
+
+		if (type == BigDecimal.class)
+			return BigDecimal.valueOf(dd);
+
+		if (type == BigInteger.class)
+			return BigInteger.valueOf(s.longValue());
+
+		throw new IllegalArgumentException("Unknown number format: " + type);
+	}
+
+	private boolean within(double s, double minValue, double maxValue) {
+		return s >= minValue && s <= maxValue;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/ObjectHandler.java b/bundleplugin/src/main/java/aQute/lib/json/ObjectHandler.java
new file mode 100644
index 0000000..fc6f6bd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/ObjectHandler.java
@@ -0,0 +1,147 @@
+package aQute.lib.json;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+public class ObjectHandler extends Handler {
+	@SuppressWarnings("rawtypes")
+	final Class		rawClass;
+	final Field		fields[];
+	final Type		types[];
+	final Object	defaults[];
+	final Field		extra;
+
+	ObjectHandler(JSONCodec codec, Class<?> c) throws Exception {
+		rawClass = c;
+		fields = c.getFields();
+
+		// Sort the fields so the output is canonical
+		Arrays.sort(fields, new Comparator<Field>() {
+			public int compare(Field o1, Field o2) {
+				return o1.getName().compareTo(o2.getName());
+			}
+		});
+
+		types = new Type[fields.length];
+		defaults = new Object[fields.length];
+
+		Field x = null;
+		for (int i = 0; i < fields.length; i++) {
+			if (fields[i].getName().equals("__extra"))
+				x = fields[i];
+			types[i] = fields[i].getGenericType();
+		}
+		if (x != null && Map.class.isAssignableFrom(x.getType()))
+			extra = x;
+		else
+			extra = null;
+		
+		try {
+			Object template = c.newInstance();
+
+			for (int i = 0; i < fields.length; i++) {
+				defaults[i] = fields[i].get(template);
+			}
+		} catch (Exception e) {
+			// Ignore
+		}
+	}
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited) throws Exception {
+		app.append("{");
+		String del = "";
+		for (int i = 0; i < fields.length; i++) {
+			if (fields[i].getName().startsWith("__"))
+				continue;
+
+			Object value = fields[i].get(object);
+			if (!app.writeDefaults) {
+				if (value == defaults[i])
+					continue;
+
+				if (value != null && value.equals(defaults[i]))
+					continue;
+			}
+
+			app.append(del);
+			StringHandler.string(app, fields[i].getName());
+			app.append(":");
+			app.encode(value, types[i], visited);
+			del = ",";
+		}
+		app.append("}");
+	}
+
+	@SuppressWarnings("unchecked") @Override Object decodeObject(Decoder r) throws Exception {
+		assert r.current() == '{';
+		Object targetObject = rawClass.newInstance();
+
+		int c = r.next();
+		while (JSONCodec.START_CHARACTERS.indexOf(c) >= 0) {
+
+			// Get key
+			String key = r.codec.parseString(r);
+
+			// Get separator
+			c = r.skipWs();
+			if (c != ':')
+				throw new IllegalArgumentException("Expected ':' but got " + (char) c);
+
+			c = r.next();
+
+			// Get value
+
+			Field f = getField(key);
+			if (f != null) {
+				// We have a field and thus a type
+				Object value = r.codec.decode(f.getGenericType(), r);
+				f.set(targetObject, value);
+			} else {
+				// No field, but may extra is defined
+				if (extra == null) {
+					if (r.strict)
+						throw new IllegalArgumentException("No such field " + key);
+					Object value = r.codec.decode(null, r);
+					r.getExtra().put(rawClass.getName() + "." + key, value);
+				} else {
+
+					Map<String, Object> map = (Map<String, Object>) extra.get(targetObject);
+					if (map == null) {
+						map = new LinkedHashMap<String, Object>();
+						extra.set(targetObject, map);
+					}
+					Object value = r.codec.decode(null, r);
+					map.put(key, value);
+				}
+			}
+
+			c = r.skipWs();
+
+			if (c == '}')
+				break;
+
+			if (c == ',') {
+				c = r.next();
+				continue;
+			}
+
+			throw new IllegalArgumentException(
+					"Invalid character in parsing object, expected } or , but found " + (char) c);
+		}
+		assert r.current() == '}';
+		r.read(); // skip closing
+		return targetObject;
+	}
+
+	private Field getField(String key) {
+		for (int i = 0; i < fields.length; i++) {
+			int n = key.compareTo(fields[i].getName());
+			if (n == 0)
+				return fields[i];
+			if (n < 0)
+				return null;
+		}
+		return null;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/SpecialHandler.java b/bundleplugin/src/main/java/aQute/lib/json/SpecialHandler.java
new file mode 100644
index 0000000..33bde8f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/SpecialHandler.java
@@ -0,0 +1,44 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.text.*;
+import java.util.*;
+import java.util.regex.*;
+
+public class SpecialHandler extends Handler {
+	@SuppressWarnings("rawtypes")
+	final Class						type;
+	final Method					valueOf;
+	final Constructor< ? >			constructor;
+	final static SimpleDateFormat	sdf	= new SimpleDateFormat();
+
+	public SpecialHandler(Class< ? > type, Constructor< ? > constructor,
+			Method valueOf) {
+		this.type = type;
+		this.constructor = constructor;
+		this.valueOf = valueOf;
+	}
+
+	@Override
+	void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException, Exception {
+		StringHandler.string(app, object.toString());
+	}
+
+	@Override
+	Object decode(String s) throws Exception {
+		if (type == Pattern.class)
+			return Pattern.compile(s);
+
+		if (constructor != null)
+			return constructor.newInstance(s);
+
+		if (valueOf != null)
+			return valueOf.invoke(null, s);
+
+		throw new IllegalArgumentException("Do not know how to convert a "
+				+ type + " from a string");
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/StringHandler.java b/bundleplugin/src/main/java/aQute/lib/json/StringHandler.java
new file mode 100644
index 0000000..2450ed0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/StringHandler.java
@@ -0,0 +1,146 @@
+package aQute.lib.json;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+public class StringHandler extends Handler {
+
+	@Override void encode(Encoder app, Object object, Map<Object, Type> visited)
+			throws IOException {
+		string(app, object.toString());
+	}
+
+	static void string(Appendable app, String s) throws IOException {
+
+		app.append('"');
+		for (int i = 0; i < s.length(); i++) {
+			char c = s.charAt(i);
+			switch (c) {
+			case '"':
+				app.append("\\\"");
+				break;
+
+			case '\\':
+				app.append("\\\\");
+				break;
+
+			case '\b':
+				app.append("\\b");
+				break;
+
+			case '\f':
+				app.append("\\f");
+				break;
+
+			case '\n':
+				app.append("\\n");
+				break;
+
+			case '\r':
+				app.append("\\r");
+				break;
+
+			case '\t':
+				app.append("\\t");
+				break;
+
+			default:
+				if (Character.isISOControl(c)) {
+					app.append("\\u");
+					app.append("0123456789ABCDEF".charAt(0xF & (c >> 12)));
+					app.append("0123456789ABCDEF".charAt(0xF & (c >> 8)));
+					app.append("0123456789ABCDEF".charAt(0xF & (c >> 4)));
+					app.append("0123456789ABCDEF".charAt(0xF & (c >> 0)));
+				} else
+					app.append(c);
+			}
+		}
+		app.append('"');
+	}
+
+	Object decode(String s) throws Exception {
+		return s;
+	}
+
+	Object decode(Number s) {
+		return s.toString();
+	}
+
+	Object decode(boolean s) {
+		return Boolean.toString(s);
+	}
+
+	Object decode() {
+		return null;
+	}
+
+	/**
+	 * An object can be assigned to a string. This means that the stream is
+	 * interpreted as the object but stored in its complete in the string.
+	 */
+	Object decodeObject(Decoder r) throws Exception {
+		return collect(r, '}');
+	}
+
+	/**
+	 * An array can be assigned to a string. This means that the stream is
+	 * interpreted as the array but stored in its complete in the string.
+	 */
+	Object decodeArray(Decoder r) throws Exception {
+		return collect(r, ']');
+	}
+
+	/**
+	 * Gather the input until you find the the closing character making sure
+	 * that new blocks are are take care of.
+	 * <p>
+	 * This method parses the input for a complete block so that it can be
+	 * stored in a string. This allows envelopes.
+	 * 
+	 * @param isr
+	 * @param c
+	 * @return
+	 * @throws Exception
+	 */
+	private Object collect(Decoder isr, char close) throws Exception {
+		boolean instring = false;
+		int level = 1;
+		StringBuilder sb = new StringBuilder();
+
+		int c = isr.current();
+		while (c > 0 && level > 0) {
+			sb.append((char) c);
+			if (instring)
+				switch (c) {
+				case '"':
+					instring = true;
+					break;
+
+				case '[':
+				case '{':
+					level++;
+					break;
+
+				case ']':
+				case '}':
+					level--;
+					break;
+				}
+			else
+				switch (c) {
+				case '"':
+					instring = false;
+					break;
+
+				case '\\':
+					sb.append((char) isr.read());
+					break;
+				}
+
+			c = isr.read();
+		}
+		return sb.toString();
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/packageinfo b/bundleplugin/src/main/java/aQute/lib/json/packageinfo
new file mode 100644
index 0000000..86528b7
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/json/packageinfo
@@ -0,0 +1 @@
+version 2.4.0
diff --git a/bundleplugin/src/main/java/aQute/lib/justif/Justif.java b/bundleplugin/src/main/java/aQute/lib/justif/Justif.java
new file mode 100644
index 0000000..663a9d6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/justif/Justif.java
@@ -0,0 +1,104 @@
+package aQute.lib.justif;
+
+import java.util.*;
+
+
+public class Justif {
+	int []tabs;
+	
+	public Justif(int width, int ... tabs) {
+		this.tabs = tabs;
+	}
+
+	/**
+	 * Routine to wrap a stringbuffer. Basically adds line endings but has the
+	 * following control characters:
+	 * <ul>
+	 * <li>Space at the beginnng of a line is repeated when wrapped for indent.</li>
+	 * <li>A tab will mark the current position and wrapping will return to that
+	 * position</li>
+	 * <li>A form feed in a tabbed colum will break but stay in the column</li>
+	 * </ul>
+	 * 
+	 * @param sb
+	 */
+	public void wrap(StringBuilder sb) {
+		List<Integer> indents = new ArrayList<Integer>();
+		
+		int indent = 0;
+		int linelength = 0;
+		int lastSpace = 0;
+		int r = 0;
+		boolean begin = true;
+
+		while (r < sb.length()) {
+			switch (sb.charAt(r++)) {
+			case '\n':
+				linelength = 0;
+				
+				indent = indents.isEmpty() ? 0 : indents.remove(0);
+				begin = true;
+				lastSpace = 0;
+				break;
+
+			case ' ':
+				if (begin)
+					indent++;
+				lastSpace = r - 1;
+				linelength++;
+				break;
+
+			case '\t':
+				indents.add(indent);
+				indent = linelength;
+				sb.deleteCharAt(--r);
+				
+				if (r < sb.length()) {
+					char digit = sb.charAt(r);
+					if (Character.isDigit(digit)) {
+						sb.deleteCharAt(r--);
+
+						int column = (digit - '0');
+						if (column < tabs.length)
+							indent = tabs[column];
+						else
+							indent = column * 8;
+
+						int diff = indent - linelength;
+						if (diff > 0) {
+							for (int i=0; i<diff; i++) {
+								sb.insert(r, ' ');
+							}
+							r += diff;
+							linelength += diff;
+						}
+					}
+				}
+				break;
+
+			case '\f':
+				linelength = 100000; // force a break
+				lastSpace = r-1;
+
+				//$FALL-THROUGH$
+
+			default:
+				linelength++;
+				begin = false;
+				if (lastSpace != 0 && linelength > 60) {
+					sb.setCharAt(lastSpace, '\n');
+					linelength = 0;
+
+					for (int i = 0; i < indent; i++) {
+						sb.insert(lastSpace + 1, ' ');
+						linelength++;
+					}
+					r += indent;
+					lastSpace = 0;
+				}
+			}
+		}
+	}
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/justif/packageinfo b/bundleplugin/src/main/java/aQute/lib/justif/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/justif/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
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 100755
index 0000000..7265212
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/About.java
@@ -0,0 +1,51 @@
+package aQute.lib.osgi;
+
+import aQute.libg.header.*;
+
+/**
+ * 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.
+ * 
+ * Headers are translated to {@link Parameters} that contains all headers (the
+ * order is maintained). The attribute of each header are maintained in an
+ * {@link Attrs}. Each additional file in a header definition will have its own
+ * entry (only native code does not work this way). The ':' of directives is
+ * considered part of the name. This allows attributes and directives to be
+ * maintained in the Attributes map.
+ * 
+ * An important aspect of the specification is to allow the use of wildcards.
+ * Wildcards select from a set and can decorate the entries with new attributes.
+ * This functionality is implemented in Instructions.
+ * 
+ * Much of the information calculated is in packages. A package is identified
+ * by a PackageRef (and a type by a TypeRef). The namespace is maintained
+ * by {@link Descriptors}, which here is owned by {@link Analyzer}. A special
+ * class, {@link Packages} maintains the attributes that are found in the code.
+ * 
+ * @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..4c52103
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/AbstractResource.java
@@ -0,0 +1,54 @@
+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;
+    
+    public long size() throws IOException {
+    	return getLocalBytes().length;
+    }
+}
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 100755
index 0000000..8be2edb
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Analyzer.java
@@ -0,0 +1,2486 @@
+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 static aQute.libg.generics.Create.*;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.Map.Entry;
+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.base64.*;
+import aQute.lib.collections.*;
+import aQute.lib.filter.*;
+import aQute.lib.hex.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.Descriptors.Descriptor;
+import aQute.lib.osgi.Descriptors.PackageRef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.libg.cryptography.*;
+import aQute.libg.generics.*;
+import aQute.libg.header.*;
+import aQute.libg.version.Version;
+
+public class Analyzer extends Processor {
+	private final SortedSet<Clazz.JAVA>				ees						= new TreeSet<Clazz.JAVA>();
+	static Properties								bndInfo;
+
+	// Bundle parameters
+	private Jar										dot;
+	private final Packages							contained				= new Packages();
+	private final Packages							referred				= new Packages();
+	private Packages								exports;
+	private Packages								imports;
+	private TypeRef									activator;
+
+	// Global parameters
+	private final MultiMap<PackageRef, PackageRef>	uses					= new MultiMap<PackageRef, PackageRef>(
+																					PackageRef.class,
+																					PackageRef.class,
+																					true);
+	private final Packages							classpathExports		= new Packages();
+	private final Descriptors						descriptors				= new Descriptors();
+	private final List<Jar>							classpath				= list();
+	private final Map<TypeRef, Clazz>				classspace				= map();
+	private final Map<TypeRef, Clazz>				importedClassesCache	= map();
+	private boolean									analyzed				= false;
+	private boolean									diagnostics				= false;
+	private boolean									inited					= false;
+
+	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;
+			uses.clear();
+			classspace.clear();
+			classpathExports.clear();
+
+			// Parse all the class in the
+			// the jar according to the OSGi bcp
+			analyzeBundleClasspath();
+
+			//
+			// calculate class versions in use
+			//
+			for (Clazz c : classspace.values()) {
+				ees.add(c.getFormat());
+			}
+
+			//
+			// Get exported packages from the
+			// entries on the classpath
+			//
+
+			for (Jar current : getClasspath()) {
+				getExternalExports(current, classpathExports);
+				for (String dir : current.getDirectories().keySet()) {
+					PackageRef packageRef = getPackageRef(dir);
+					Resource resource = current.getResource(dir + "/packageinfo");
+					setPackageInfo(packageRef, resource, classpathExports);
+				}
+			}
+
+			// Handle the bundle activator
+
+			String s = getProperty(BUNDLE_ACTIVATOR);
+			if (s != null) {
+				activator = getTypeRefFromFQN(s);
+				referTo(activator);
+			}
+
+			// Execute any plugins
+			// TODO handle better reanalyze
+			doPlugins();
+
+			Jar extra = getExtra();
+			while (extra != null) {
+				dot.addAll(extra);
+				analyzeJar(extra, "", true);
+				extra = getExtra();
+			}
+
+			referred.keySet().removeAll(contained.keySet());
+
+			//
+			// EXPORTS
+			//
+			{
+				Set<Instruction> unused = Create.set();
+
+				Instructions filter = new Instructions(getExportPackage());
+				filter.append(getExportContents());
+
+				exports = filter(filter, contained, unused);
+
+				if (!unused.isEmpty()) {
+					warning("Unused Export-Package instructions: %s ", unused);
+				}
+
+				// See what information we can find to augment the
+				// exports. I.e. look on the classpath
+				augmentExports(exports);
+			}
+
+			//
+			// IMPORTS
+			// Imports MUST come after exports because we use information from
+			// the exports
+			//
+			{
+				// Add all exports that do not have an -noimport: directive
+				// to the imports.
+				Packages referredAndExported = new Packages(referred);
+				referredAndExported.putAll(doExportsToImports(exports));
+
+				removeDynamicImports(referredAndExported);
+
+				// Remove any Java references ... where are the closures???
+				for (Iterator<PackageRef> i = referredAndExported.keySet().iterator(); i.hasNext();) {
+					if (i.next().isJava())
+						i.remove();
+				}
+
+				Set<Instruction> unused = Create.set();
+				String h = getProperty(IMPORT_PACKAGE);
+				if (h == null) // If not set use a default
+					h = "*";
+
+				if (isPedantic() && h.trim().length() == 0)
+					warning("Empty Import-Package header");
+
+				Instructions filter = new Instructions(h);
+				imports = filter(filter, referredAndExported, unused);
+				if (!unused.isEmpty()) {
+					// We ignore the end wildcard catch
+					if (!(unused.size() == 1 && unused.iterator().next().toString().equals("*")))
+						warning("Unused Import-Package instructions: %s ", unused);
+				}
+
+				// See what information we can find to augment the
+				// imports. I.e. look in the exports
+				augmentImports(imports, exports);
+			}
+
+			//
+			// USES
+			//
+			// Add the uses clause to the exports
+			doUses(exports, uses, imports);
+
+			//
+			// Checks
+			//
+			if (referred.containsKey(Descriptors.DEFAULT_PACKAGE)) {
+				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 "
+						+ uses.transpose().get(Descriptors.DEFAULT_PACKAGE));
+			}
+
+		}
+	}
+
+	/**
+	 * Discussed with BJ and decided to kill the .
+	 * 
+	 * @param referredAndExported
+	 */
+	void removeDynamicImports(Packages referredAndExported) {
+
+		// // Remove any matching a dynamic import package instruction
+		// Instructions dynamicImports = new
+		// Instructions(getDynamicImportPackage());
+		// Collection<PackageRef> dynamic = dynamicImports.select(
+		// referredAndExported.keySet(), false);
+		// referredAndExported.keySet().removeAll(dynamic);
+	}
+
+	protected Jar getExtra() throws Exception {
+		return null;
+	}
+
+	/**
+	 * 
+	 */
+	void doPlugins() {
+		for (AnalyzerPlugin plugin : getPlugins(AnalyzerPlugin.class)) {
+			try {
+				boolean reanalyze = plugin.analyzeJar(this);
+				if (reanalyze) {
+					classspace.clear();
+					analyzeBundleClasspath();
+				}
+			}
+			catch (Exception e) {
+				error("Analyzer Plugin %s failed %s", plugin, e);
+			}
+		}
+	}
+
+	/**
+	 * 
+	 * @return
+	 */
+	boolean isResourceOnly() {
+		return isTrue(getProperty(RESOURCEONLY));
+	}
+
+	/**
+	 * 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);
+
+		// Remove all the Java packages from the imports
+		if (!imports.isEmpty()) {
+			main.putValue(IMPORT_PACKAGE, printClauses(imports));
+		}
+		else {
+			main.remove(IMPORT_PACKAGE);
+		}
+
+		Packages temp = new Packages(contained);
+		temp.keySet().removeAll(exports.keySet());
+
+		if (!temp.isEmpty())
+			main.putValue(PRIVATE_PACKAGE, printClauses(temp));
+		else
+			main.remove(PRIVATE_PACKAGE);
+
+		Parameters bcp = getBundleClasspath();
+		if (bcp.isEmpty() || (bcp.containsKey(".") && bcp.size() == 1))
+			main.remove(BUNDLE_CLASSPATH);
+		else
+			main.putValue(BUNDLE_CLASSPATH, printClauses(bcp));
+
+		doNamesection(dot, manifest);
+
+		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
+		Instructions instructions = new Instructions(getProperty(REMOVEHEADERS));
+		Collection<Object> result = instructions.select(main.keySet(), false);
+		main.keySet().removeAll(result);
+
+		dot.setManifest(manifest);
+		return manifest;
+	}
+
+	/**
+	 * Parse the namesection as instructions and then match them against the
+	 * current set of resources
+	 * 
+	 * For example:
+	 * 
+	 * <pre>
+	 * 	-namesection: *;baz=true, abc/def/bar/X.class=3
+	 * </pre>
+	 * 
+	 * The raw value of {@link Constants#NAMESECTION} is used but the values of
+	 * the attributes are replaced where @ is set to the resource name. This
+	 * allows macro to operate on the resource
+	 * 
+	 */
+
+	private void doNamesection(Jar dot, Manifest manifest) {
+
+		Parameters namesection = parseHeader(getProperties().getProperty(NAMESECTION));
+		Instructions instructions = new Instructions(namesection);
+		Set<String> resources = new HashSet<String>(dot.getResources().keySet());
+
+		//
+		// For each instruction, iterator over the resources and filter
+		// them. If a resource matches, it must be removed even if the
+		// instruction is negative. If positive, add a name section
+		// to the manifest for the given resource name. Then add all
+		// attributes from the instruction to that name section.
+		//
+		for (Map.Entry<Instruction, Attrs> instr : instructions.entrySet()) {
+			boolean matched = false;
+
+			// For each instruction
+
+			for (Iterator<String> i = resources.iterator(); i.hasNext();) {
+				String path = i.next();
+				// For each resource
+
+				if (instr.getKey().matches(path)) {
+
+					// Instruction matches the resource
+
+					matched = true;
+					if (!instr.getKey().isNegated()) {
+
+						// Positive match, add the attributes
+
+						Attributes attrs = manifest.getAttributes(path);
+						if (attrs == null) {
+							attrs = new Attributes();
+							manifest.getEntries().put(path, attrs);
+						}
+
+						//
+						// Add all the properties from the instruction to the
+						// name section
+						//
+
+						for (Map.Entry<String, String> property : instr.getValue().entrySet()) {
+							setProperty("@", path);
+							try {
+								String processed = getReplacer().process(property.getValue());
+								attrs.putValue(property.getKey(), processed);
+							}
+							finally {
+								unsetProperty("@");
+							}
+						}
+					}
+					i.remove();
+				}
+			}
+
+			if (!matched && resources.size() > 0)
+				warning("The instruction %s in %s did not match any resources", instr.getKey(),
+						NAMESECTION);
+		}
+
+	}
+
+	/**
+	 * 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 = "";
+		StringBuilder sb = new StringBuilder();
+		Map<String, Map<String, Resource>> map = bundle.getDirectories();
+		for (Iterator<String> i = map.keySet().iterator(); i.hasNext();) {
+			String directory = 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 Packages getContained() {
+		return contained;
+	}
+
+	public Packages getExports() {
+		return exports;
+	}
+
+	public Packages getImports() {
+		return imports;
+	}
+
+	public Jar getJar() {
+		return dot;
+	}
+
+	public Packages getReferred() {
+		return referred;
+	}
+
+	/**
+	 * Return the set of unreachable code depending on exports and the bundle
+	 * activator.
+	 * 
+	 * @return
+	 */
+	public Set<PackageRef> getUnreachable() {
+		Set<PackageRef> unreachable = new HashSet<PackageRef>(uses.keySet()); // all
+		for (Iterator<PackageRef> r = exports.keySet().iterator(); r.hasNext();) {
+			PackageRef packageRef = r.next();
+			removeTransitive(packageRef, unreachable);
+		}
+		if (activator != null) {
+			removeTransitive(activator.getPackageRef(), unreachable);
+		}
+		return unreachable;
+	}
+
+	public MultiMap<PackageRef, PackageRef> 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) {
+		synchronized (Analyzer.class) {
+			if (bndInfo == null) {
+				bndInfo = new Properties();
+				InputStream in = Analyzer.class.getResourceAsStream("bnd.info");
+				try {
+					if (in != null) {
+						bndInfo.load(in);
+						in.close();
+					}
+				}
+				catch (IOException ioe) {
+					warning("Could not read bnd.info in " + Analyzer.class.getPackage() + ioe);
+				}
+				finally {
+					IO.close(in);
+				}
+			}
+		}
+		return bndInfo.getProperty(key, defaultValue);
+	}
+
+	/**
+	 * Merge the existing manifest with the instructions but do not override
+	 * existing properties.
+	 * 
+	 * @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, attributes.getValue(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) {
+		if (dot != null)
+			removeClose(dot);
+
+		this.dot = jar;
+		if (dot != null)
+			addClose(dot);
+
+		return jar;
+	}
+
+	protected void begin() {
+		if (inited == false) {
+			inited = true;
+			super.begin();
+
+			updateModified(getBndLastModified(), "bnd last modified");
+			verifyManifestHeadersCase(getProperties());
+
+		}
+	}
+
+	/**
+	 * 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.getSource() != null && entry.getSource().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
+	 */
+	private 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());
+				}
+			}
+		}
+	}
+
+	/**
+	 * 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 ...
+	 * 
+	 */
+	Packages doExportsToImports(Packages exports) {
+
+		// private packages = contained - exported.
+		Set<PackageRef> privatePackages = new HashSet<PackageRef>(contained.keySet());
+		privatePackages.removeAll(exports.keySet());
+
+		// private references = ∀ p : private packages | uses(p)
+		Set<PackageRef> privateReferences = newSet();
+		for (PackageRef p : privatePackages) {
+			Collection<PackageRef> uses = this.uses.get(p);
+			if (uses != null)
+				privateReferences.addAll(uses);
+		}
+
+		// Assume we are going to export all exported packages
+		Set<PackageRef> toBeImported = new HashSet<PackageRef>(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.
+		// TODO 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<PackageRef> i = toBeImported.iterator(); i.hasNext();) {
+			PackageRef next = i.next();
+			Collection<PackageRef> usedByExportedPackage = this.uses.get(next);
+
+			for (PackageRef privatePackage : privatePackages) {
+				if (usedByExportedPackage.contains(privatePackage)) {
+					i.remove();
+					break;
+				}
+			}
+		}
+
+		// Clean up attributes and generate result map
+		Packages result = new Packages();
+		for (Iterator<PackageRef> i = toBeImported.iterator(); i.hasNext();) {
+			PackageRef ep = i.next();
+			Attrs 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 = new Attrs();
+			parameters.remove(VERSION_ATTRIBUTE);
+			result.put(ep, parameters);
+		}
+		return result;
+	}
+
+	public boolean referred(PackageRef packageName) {
+		// return true;
+		for (Map.Entry<PackageRef, List<PackageRef>> contained : uses.entrySet()) {
+			if (!contained.getKey().equals(packageName)) {
+				if (contained.getValue().contains(packageName))
+					return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * 
+	 * @param jar
+	 */
+	private void getExternalExports(Jar jar, Packages classpathExports) {
+		try {
+			Manifest m = jar.getManifest();
+			if (m != null) {
+				Domain domain = Domain.domain(m);
+				Parameters exported = domain.getExportPackage();
+				for (Entry<String, Attrs> e : exported.entrySet()) {
+					PackageRef ref = getPackageRef(e.getKey());
+					if (!classpathExports.containsKey(ref)) {
+						// TODO e.getValue().put(SOURCE_DIRECTIVE,
+						// jar.getBsn()+"-"+jar.getVersion());
+
+						classpathExports.put(ref, e.getValue());
+					}
+				}
+			}
+		}
+		catch (Exception e) {
+			warning("Erroneous Manifest for " + jar + " " + e);
+		}
+	}
+
+	/**
+	 * Find some more information about imports in manifest and other places. It
+	 * is assumed that the augmentsExports has already copied external attrs
+	 * from the classpathExports.
+	 * 
+	 * @throws Exception
+	 */
+	void augmentImports(Packages imports, Packages exports) throws Exception {
+		List<PackageRef> noimports = Create.list();
+		Set<PackageRef> provided = findProvidedPackages();
+
+		for (PackageRef packageRef : imports.keySet()) {
+			String packageName = packageRef.getFQN();
+
+			setProperty(CURRENT_PACKAGE, packageName);
+			try {
+				Attrs importAttributes = imports.get(packageRef);
+				Attrs exportAttributes = exports.get(packageRef,
+						classpathExports.get(packageRef, new Attrs()));
+
+				String exportVersion = exportAttributes.getVersion();
+				String importRange = importAttributes.getVersion();
+
+				if (exportVersion == null) {
+					// TODO Should check if the source is from a bundle.
+
+				}
+				else {
+
+					//
+					// Version Policy - Import version substitution. We
+					// calculate the export version and then allow the
+					// import version attribute to use it in a substitution
+					// by using a ${@} macro. The export version can
+					// be defined externally or locally
+					//
+
+					boolean provider = isTrue(importAttributes.get(PROVIDE_DIRECTIVE))
+							|| isTrue(exportAttributes.get(PROVIDE_DIRECTIVE))
+							|| provided.contains(packageRef);
+
+					exportVersion = cleanupVersion(exportVersion);
+
+					try {
+						setProperty("@", exportVersion);
+
+						if (importRange != null) {
+							importRange = cleanupVersion(importRange);
+							importRange = getReplacer().process(importRange);
+						}
+						else
+							importRange = getVersionPolicy(provider);
+
+					}
+					finally {
+						unsetProperty("@");
+					}
+					importAttributes.put(VERSION_ATTRIBUTE, importRange);
+				}
+
+				//
+				// Check if exporter has mandatory attributes
+				//
+				String mandatory = exportAttributes.get(MANDATORY_DIRECTIVE);
+				if (mandatory != null) {
+					String[] attrs = mandatory.split("\\s*,\\s*");
+					for (int i = 0; i < attrs.length; i++) {
+						if (!importAttributes.containsKey(attrs[i]))
+							importAttributes.put(attrs[i], exportAttributes.get(attrs[i]));
+					}
+				}
+
+				if (exportAttributes.containsKey(IMPORT_DIRECTIVE))
+					importAttributes.put(IMPORT_DIRECTIVE, exportAttributes.get(IMPORT_DIRECTIVE));
+
+				fixupAttributes(importAttributes);
+				removeAttributes(importAttributes);
+
+				String result = importAttributes.get(Constants.VERSION_ATTRIBUTE);
+				if (result == null)
+					noimports.add(packageRef);
+			}
+			finally {
+				unsetProperty(CURRENT_PACKAGE);
+			}
+		}
+
+		if (isPedantic() && noimports.size() != 0) {
+			warning("Imports that lack version ranges: %s", noimports);
+		}
+	}
+
+	/**
+	 * Find the packages we depend on, where we implement an interface that is a
+	 * Provider Type. These packages, when we import them, must use the provider
+	 * policy.
+	 * 
+	 * @throws Exception
+	 */
+	Set<PackageRef> findProvidedPackages() throws Exception {
+		Set<PackageRef> providers = Create.set();
+		Set<TypeRef> cached = Create.set();
+
+		for (Clazz c : classspace.values()) {
+			TypeRef[] interfaces = c.getInterfaces();
+			if (interfaces != null)
+				for (TypeRef t : interfaces)
+					if (cached.contains(t) || isProvider(t)) {
+						cached.add(t);
+						providers.add(t.getPackageRef());
+					}
+		}
+		return providers;
+	}
+
+	private boolean isProvider(TypeRef t) throws Exception {
+		Clazz c = findClass(t);
+		if (c == null)
+			return false;
+
+		if (c.annotations == null)
+			return false;
+
+		TypeRef pt = getTypeRefFromFQN(ProviderType.class.getName());
+		boolean result = c.annotations.contains(pt);
+		return result;
+	}
+
+	/**
+	 * Provide any macro substitutions and versions for exported packages.
+	 */
+
+	void augmentExports(Packages exports) {
+		for (PackageRef packageRef : exports.keySet()) {
+			String packageName = packageRef.getFQN();
+			setProperty(CURRENT_PACKAGE, packageName);
+			try {
+				Attrs attributes = exports.get(packageRef);
+				Attrs exporterAttributes = classpathExports.get(packageRef);
+				if (exporterAttributes == null)
+					continue;
+
+				for (Map.Entry<String, String> entry : exporterAttributes.entrySet()) {
+					String key = entry.getKey();
+					if (key.equalsIgnoreCase(SPECIFICATION_VERSION))
+						key = VERSION_ATTRIBUTE;
+
+					// dont overwrite and no directives
+					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(Attrs 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. 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.
+	 */
+
+	void removeAttributes(Attrs attributes) {
+		String remove = attributes.remove(REMOVE_ATTRIBUTE_DIRECTIVE);
+
+		if (remove != null) {
+			Instructions removeInstr = new Instructions(remove);
+			attributes.keySet().removeAll(removeInstr.select(attributes.keySet(), false));
+		}
+
+		// Remove any ! valued attributes
+		for (Iterator<Entry<String, String>> i = attributes.entrySet().iterator(); i.hasNext();) {
+			String v = i.next().getValue();
+			if (v.equals("!"))
+				i.remove();
+		}
+	}
+
+	/**
+	 * 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(Packages exports, MultiMap<PackageRef, PackageRef> uses, Packages imports) {
+		if ("true".equalsIgnoreCase(getProperty(NOUSES)))
+			return;
+
+		for (Iterator<PackageRef> i = exports.keySet().iterator(); i.hasNext();) {
+			PackageRef packageRef = i.next();
+			String packageName = packageRef.getFQN();
+			setProperty(CURRENT_PACKAGE, packageName);
+			try {
+				doUses(packageRef, exports, uses, imports);
+			}
+			finally {
+				unsetProperty(CURRENT_PACKAGE);
+			}
+
+		}
+	}
+
+	/**
+	 * @param packageName
+	 * @param exports
+	 * @param uses
+	 * @param imports
+	 */
+	protected void doUses(PackageRef packageRef, Packages exports,
+			MultiMap<PackageRef, PackageRef> uses, Packages imports) {
+		Attrs clause = exports.get(packageRef);
+
+		// Check if someone already set the uses: directive
+		String override = clause.get(USES_DIRECTIVE);
+		if (override == null)
+			override = USES_USES;
+
+		// Get the used packages
+		Collection<PackageRef> usedPackages = uses.get(packageRef);
+
+		if (usedPackages != null) {
+
+			// Only do a uses on exported or imported packages
+			// and uses should also not contain our own package
+			// name
+			Set<PackageRef> sharedPackages = new HashSet<PackageRef>();
+			sharedPackages.addAll(imports.keySet());
+			sharedPackages.addAll(exports.keySet());
+			sharedPackages.retainAll(usedPackages);
+			sharedPackages.remove(packageRef);
+
+			StringBuilder sb = new StringBuilder();
+			String del = "";
+			for (Iterator<PackageRef> u = sharedPackages.iterator(); u.hasNext();) {
+				PackageRef usedPackage = u.next();
+				if (!usedPackage.isJava()) {
+					sb.append(del);
+					sb.append(usedPackage.getFQN());
+					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, Matcher.quoteReplacement(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(PackageRef name, Set<PackageRef> unreachable) {
+		if (!unreachable.contains(name))
+			return;
+
+		unreachable.remove(name);
+
+		List<PackageRef> ref = uses.get(name);
+		if (ref != null) {
+			for (Iterator<PackageRef> r = ref.iterator(); r.hasNext();) {
+				PackageRef element = r.next();
+				removeTransitive(element, unreachable);
+			}
+		}
+	}
+
+	/**
+	 * Helper method to set the package info resource
+	 * 
+	 * @param dir
+	 * @param key
+	 * @param value
+	 * @throws Exception
+	 */
+	void setPackageInfo(PackageRef packageRef, Resource r, Packages classpathExports)
+			throws Exception {
+		if (r == null)
+			return;
+
+		Properties p = new Properties();
+		InputStream in = r.openInputStream();
+		try {
+			p.load(in);
+		}
+		finally {
+			in.close();
+		}
+		Attrs map = classpathExports.get(packageRef);
+		if (map == null) {
+			classpathExports.put(packageRef, map = new Attrs());
+		}
+		for (@SuppressWarnings("unchecked")
+		Enumeration<String> t = (Enumeration<String>) p.propertyNames(); t.hasMoreElements();) {
+			String key = t.nextElement();
+			String value = map.get(key);
+			if (value == null) {
+				value = p.getProperty(key);
+
+				// Messy, to allow directives we need to
+				// allow the value to start with a ':' since we cannot
+				// encode this in a property name
+
+				if (value.startsWith(":")) {
+					key = key + ":";
+					value = value.substring(1);
+				}
+				map.put(key, value);
+			}
+		}
+	}
+
+	public void close() {
+		if (diagnostics) {
+			PrintStream out = System.err;
+			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];
+				//$FALL-THROUGH$
+			case 2 :
+				regexp = args[1];
+		}
+		StringBuilder sb = new StringBuilder();
+		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(entry.getKey(), 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(Collection< ? > jars) throws IOException {
+		for (Object jar : jars) {
+			if (jar instanceof Jar)
+				addClasspath((Jar) jar);
+			else
+				if (jar instanceof File)
+					addClasspath((File) jar);
+				else
+					if (jar instanceof String)
+						addClasspath(getFile((String) jar));
+					else
+						error("Cannot convert to JAR to add to classpath %s. Not a File, Jar, or String",
+								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;
+	}
+
+	private void analyzeBundleClasspath() throws Exception {
+		Parameters bcp = getBundleClasspath();
+
+		if (bcp.isEmpty()) {
+			analyzeJar(dot, "", true);
+		}
+		else {
+			boolean okToIncludeDirs = true;
+
+			for (String path : bcp.keySet()) {
+				if (dot.getDirectories().containsKey(path)) {
+					okToIncludeDirs = false;
+					break;
+				}
+			}
+
+			for (String path : bcp.keySet()) {
+				Attrs info = bcp.get(path);
+
+				if (path.equals(".")) {
+					analyzeJar(dot, "", okToIncludeDirs);
+					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, "", 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 (bcp.containsKey("."))
+							warning("Bundle-ClassPath uses a directory '%s' as well as '.'. This means bnd does not know if a directory is a package.",
+									path, path);
+						analyzeJar(dot, Processor.appendPath(path) + "/", true);
+					}
+					else {
+						if (!"optional".equals(info.get(RESOLUTION_DIRECTIVE)))
+							warning("No sub JAR or directory " + path);
+					}
+				}
+			}
+
+		}
+	}
+
+	/**
+	 * 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 boolean analyzeJar(Jar jar, String prefix, boolean okToIncludeDirs) throws Exception {
+		Map<String, Clazz> mismatched = new HashMap<String, Clazz>();
+
+		next: for (String path : jar.getResources().keySet()) {
+			if (path.startsWith(prefix)) {
+
+				String relativePath = path.substring(prefix.length());
+
+				if (okToIncludeDirs) {
+					int n = relativePath.lastIndexOf('/');
+					if (n < 0)
+						n = relativePath.length();
+					String relativeDir = relativePath.substring(0, n);
+
+					PackageRef packageRef = getPackageRef(relativeDir);
+					if (!packageRef.isMetaData() && !contained.containsKey(packageRef)) {
+						contained.put(packageRef);
+
+						// For each package we encounter for the first
+						// time. Unfortunately we can only do this once
+						// we found a class since the bcp has a tendency
+						// to overlap
+						if (!packageRef.isMetaData()) {
+							Resource pinfo = jar.getResource(prefix + packageRef.getPath()
+									+ "/packageinfo");
+							setPackageInfo(packageRef, pinfo, classpathExports);
+						}
+					}
+				}
+
+				// Check class resources, we need to analyze them
+				if (path.endsWith(".class")) {
+					Resource resource = jar.getResource(path);
+					Clazz clazz;
+					Attrs info = null;
+
+					try {
+						InputStream in = resource.openInputStream();
+						clazz = new Clazz(this, path, resource);
+						try {
+							// Check if we have a package-info
+							if (relativePath.endsWith("/package-info.class")) {
+								// package-info can contain an Export annotation
+								info = new Attrs();
+								parsePackageInfoClass(clazz, info);
+							}
+							else {
+								// Otherwise we just parse it simply
+								clazz.parseClassFile();
+							}
+						}
+						finally {
+							in.close();
+						}
+					}
+					catch (Throwable e) {
+						error("Invalid class file %s (%s)", e, relativePath, e);
+						e.printStackTrace();
+						continue next;
+					}
+
+					String calculatedPath = clazz.getClassName().getPath();
+					if (!calculatedPath.equals(relativePath)) {
+						// If there is a mismatch we
+						// warning
+						if (okToIncludeDirs) // assume already reported
+							mismatched.put(clazz.getAbsolutePath(), clazz);
+					}
+					else {
+						classspace.put(clazz.getClassName(), clazz);
+						PackageRef packageRef = clazz.getClassName().getPackageRef();
+
+						if (!contained.containsKey(packageRef)) {
+							contained.put(packageRef);
+							if (!packageRef.isMetaData()) {
+								Resource pinfo = jar.getResource(prefix + packageRef.getPath()
+										+ "/packageinfo");
+								setPackageInfo(packageRef, pinfo, classpathExports);
+							}
+						}
+						if (info != null)
+							contained.merge(packageRef, false, info);
+
+						Set<PackageRef> set = Create.set();
+
+						// Look at the referred packages
+						// and copy them to our baseline
+						for (PackageRef p : clazz.getReferred()) {
+							referred.put(p);
+							set.add(p);
+						}
+						set.remove(packageRef);
+						uses.addAll(packageRef, set);
+					}
+				}
+			}
+		}
+
+		if (mismatched.size() > 0) {
+			error("Classes found in the wrong directory: %s", mismatched);
+			return false;
+		}
+		return true;
+	}
+
+	static Pattern	OBJECT_REFERENCE	= Pattern.compile("L([^/]+/)*([^;]+);");
+
+	private void parsePackageInfoClass(final Clazz clazz, final Attrs info) throws Exception {
+		clazz.parseClassFileWithCollector(new ClassDataCollector() {
+			@Override
+			public void annotation(Annotation a) {
+				String name = a.name.getFQN();
+				if (aQute.bnd.annotation.Version.class.getName().equals(name)) {
+
+					// 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 annotation 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.getClassName().getFQN());
+							}
+						}
+						catch (Exception e) {
+							// Ignore
+						}
+					}
+				}
+				else
+					if (name.equals(Export.class.getName())) {
+
+						// Check mandatory attributes
+						Attrs 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()) {
+				StringBuilder result = new StringBuilder();
+				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(StringBuilder 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);
+		}
+	}
+
+	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)) {
+				String s = args[++i];
+				instr = new Instruction(s);
+			}
+			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<TypeRef, 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(TypeRef typeRef) throws Exception {
+		Clazz c = classspace.get(typeRef);
+		if (c != null)
+			return c;
+
+		c = importedClassesCache.get(typeRef);
+		if (c != null)
+			return c;
+
+		Resource r = findResource(typeRef.getPath());
+		if (r == null) {
+			getClass().getClassLoader();
+			URL url = ClassLoader.getSystemResource(typeRef.getPath());
+			if (url != null)
+				r = new URLResource(url);
+		}
+		if (r != null) {
+			c = new Clazz(this, typeRef.getPath(), r);
+			c.parseClassFile();
+			importedClassesCache.put(typeRef, 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(TypeRef ref) {
+		PackageRef pack = ref.getPackageRef();
+		if (!referred.containsKey(pack))
+			referred.put(pack, new Attrs());
+	}
+
+	public void referToByBinaryName(String binaryClassName) {
+		TypeRef ref = descriptors.getTypeRef(binaryClassName);
+		referTo(ref);
+	}
+
+	/**
+	 * Ensure that we are running on the correct bnd.
+	 */
+	void doRequireBnd() {
+		Attrs 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);
+			}
+		}
+	}
+
+	/**
+	 * md5 macro
+	 */
+
+	static String	_md5Help	= "${md5;path}";
+
+	public String _md5(String args[]) throws Exception {
+		Macro.verifyCommand(args, _md5Help,
+				new Pattern[] {null, null, Pattern.compile("base64|hex")}, 2, 3);
+
+		Digester<MD5> digester = MD5.getDigester();
+		Resource r = dot.getResource(args[1]);
+		if (r == null)
+			throw new FileNotFoundException("From " + digester + ", not found " + args[1]);
+
+		IO.copy(r.openInputStream(), digester);
+		boolean hex = args.length > 2 && args[2].equals("hex");
+		if (hex)
+			return Hex.toHexString(digester.digest().digest());
+		else
+			return Base64.encodeBase64(digester.digest().digest());
+	}
+
+	/**
+	 * SHA1 macro
+	 */
+
+	static String	_sha1Help	= "${sha1;path}";
+
+	public String _sha1(String args[]) throws Exception {
+		Macro.verifyCommand(args, _sha1Help,
+				new Pattern[] {null, null, Pattern.compile("base64|hex")}, 2, 3);
+		Digester<SHA1> digester = SHA1.getDigester();
+		Resource r = dot.getResource(args[1]);
+		if (r == null)
+			throw new FileNotFoundException("From sha1, not found " + args[1]);
+
+		IO.copy(r.openInputStream(), digester);
+		return Base64.encodeBase64(digester.digest().digest());
+	}
+
+	public Descriptor getDescriptor(String descriptor) {
+		return descriptors.getDescriptor(descriptor);
+	}
+
+	public TypeRef getTypeRef(String binaryClassName) {
+		return descriptors.getTypeRef(binaryClassName);
+	}
+
+	public PackageRef getPackageRef(String binaryName) {
+		return descriptors.getPackageRef(binaryName);
+	}
+
+	public TypeRef getTypeRefFromFQN(String fqn) {
+		return descriptors.getTypeRefFromFQN(fqn);
+	}
+
+	public TypeRef getTypeRefFromPath(String path) {
+		return descriptors.getTypeRefFromPath(path);
+	}
+
+	public boolean isImported(PackageRef packageRef) {
+		return imports.containsKey(packageRef);
+	}
+
+	/**
+	 * Merge the attributes of two maps, where the first map can contain
+	 * wildcarded names. The idea is that the first map contains instructions
+	 * (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.
+	 * @param source the actual found packages, contains no duplicates
+	 * 
+	 * @return Only the packages that were filtered by the given instructions
+	 */
+
+	Packages filter(Instructions instructions, Packages source, Set<Instruction> nomatch) {
+		Packages result = new Packages();
+		List<PackageRef> refs = new ArrayList<PackageRef>(source.keySet());
+		Collections.sort(refs);
+
+		List<Instruction> filters = new ArrayList<Instruction>(instructions.keySet());
+		if (nomatch == null)
+			nomatch = Create.set();
+
+		for (Instruction instruction : filters) {
+			boolean match = false;
+
+			for (Iterator<PackageRef> i = refs.iterator(); i.hasNext();) {
+				PackageRef packageRef = i.next();
+
+				if (packageRef.isMetaData()) {
+					i.remove(); // no use checking it again
+					continue;
+				}
+
+				String packageName = packageRef.getFQN();
+
+				if (instruction.matches(packageName)) {
+					match = true;
+					if (!instruction.isNegated()) {
+						result.merge(packageRef, instruction.isDuplicate(), source.get(packageRef),
+								instructions.get(instruction));
+					}
+					i.remove(); // Can never match again for another pattern
+				}
+			}
+			if (!match && !instruction.isAny())
+				nomatch.add(instruction);
+		}
+
+		/*
+		 * Tricky. If we have umatched instructions they might indicate that we
+		 * want to have multiple decorators for the same package. So we check
+		 * the unmatched against the result list. If then then match and have
+		 * actually interesting properties then we merge them
+		 */
+
+		for (Iterator<Instruction> i = nomatch.iterator(); i.hasNext();) {
+			Instruction instruction = i.next();
+
+			// We assume the user knows what he is
+			// doing and inserted a literal. So
+			// we ignore any not matched literals
+			if (instruction.isLiteral()) {
+				result.merge(getPackageRef(instruction.getLiteral()), true,
+						instructions.get(instruction));
+				i.remove();
+				continue;
+			}
+
+			// Not matching a negated instruction looks
+			// like an error ...
+			if (instruction.isNegated()) {
+				continue;
+			}
+
+			// An optional instruction should not generate
+			// an error
+			if (instruction.isOptional()) {
+				i.remove();
+				continue;
+			}
+
+			// boolean matched = false;
+			// Set<PackageRef> prefs = new HashSet<PackageRef>(result.keySet());
+			// for (PackageRef ref : prefs) {
+			// if (instruction.matches(ref.getFQN())) {
+			// result.merge(ref, true, source.get(ref),
+			// instructions.get(instruction));
+			// matched = true;
+			// }
+			// }
+			// if (matched)
+			// i.remove();
+		}
+		return result;
+	}
+
+	public void setDiagnostics(boolean b) {
+		diagnostics = b;
+	}
+
+	public Clazz.JAVA getLowestEE() {
+		if (ees.isEmpty())
+			return Clazz.JAVA.JDK1_4;
+
+		return ees.first();
+	}
+
+	public String _ee(String args[]) {
+		return getLowestEE().getEE();
+	}
+
+	/**
+	 * Calculate the output file for the given target. The strategy is:
+	 * 
+	 * <pre>
+	 * parameter given if not null and not directory
+	 * if directory, this will be the output directory
+	 * based on bsn-version.jar
+	 * name of the source file if exists
+	 * Untitled-[n]
+	 * </pre>
+	 * 
+	 * @param output may be null, otherwise a file path relative to base
+	 */
+	public File getOutputFile(String output) {
+
+		if (output == null)
+			output = get(Constants.OUTPUT);
+
+		File outputDir;
+
+		if (output != null) {
+			File outputFile = getFile(output);
+			if (outputFile.isDirectory())
+				outputDir = outputFile;
+			else
+				return outputFile;
+		}
+		else
+			outputDir = getBase();
+
+		if (getBundleSymbolicName() != null) {
+			String bsn = getBundleSymbolicName();
+			String version = getBundleVersion();
+			Version v = Version.parseVersion(version);
+			String outputName = bsn + "-" + v.getWithoutQualifier()
+					+ Constants.DEFAULT_JAR_EXTENSION;
+			return new File(outputDir, outputName);
+		}
+
+		File source = getJar().getSource();
+		if (source != null) {
+			String outputName = source.getName();
+			return new File(outputDir, outputName);
+		}
+
+		error("Cannot establish an output name from %s, nor bsn, nor source file name, using Untitled",
+				output);
+		int n = 0;
+		File f = getFile(outputDir, "Untitled");
+		while (f.isFile()) {
+			f = getFile(outputDir, "Untitled-" + n++);
+		}
+		return f;
+	}
+
+	/**
+	 * Utility function to carefully save the file. Will create a backup if the
+	 * source file has the same path as the output. It will also only save if
+	 * the file was modified or the force flag is true
+	 * 
+	 * @param output the output file, if null {@link #getOutputFile(String)} is
+	 *        used.
+	 * @param force if it needs to be overwritten
+	 * @throws Exception
+	 */
+
+	public boolean save(File output, boolean force) throws Exception {
+		if (output == null)
+			output = getOutputFile(null);
+
+		Jar jar = getJar();
+		File source = jar.getSource();
+
+		trace("check for modified build=%s file=%s, diff=%s", jar.lastModified(),
+				output.lastModified(), jar.lastModified() - output.lastModified());
+
+		if (!output.exists() || output.lastModified() <= jar.lastModified() || force) {
+			output.getParentFile().mkdirs();
+			if (source != null && output.getCanonicalPath().equals(source.getCanonicalPath())) {
+				File bak = new File(source.getParentFile(), source.getName() + ".bak");
+				if (!source.renameTo(bak)) {
+					error("Could not create backup file %s", bak);
+				}
+				else
+					source.delete();
+			}
+			try {
+				trace("Saving jar to %s", output);
+				getJar().write(output);
+			}
+			catch (Exception e) {
+				output.delete();
+				error("Cannot write JAR file to %s due to %s", e, output, e.getMessage());
+			}
+			return true;
+		}
+		else {
+			trace("Not modified %s", output);
+			return false;
+		}
+	}
+
+	/**
+	 * Set default import and export instructions if none are set
+	 */
+	public void setDefaults(String bsn, Version version) {
+		if (getExportPackage() == null)
+			setExportPackage("*");
+		if (getImportPackage() == null)
+			setExportPackage("*");
+		if (bsn != null && getBundleSymbolicName() == null)
+			setBundleSymbolicName(bsn);
+		if (version != null && getBundleVersion() == null)
+			setBundleVersion(version);
+	}
+}
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..86f8caa
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Annotation.java
@@ -0,0 +1,74 @@
+package aQute.lib.osgi;
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import aQute.bnd.annotation.metatype.*;
+import aQute.lib.osgi.Descriptors.TypeRef;
+
+@SuppressWarnings("unchecked") public class Annotation {
+	TypeRef				name;
+	Map<String, Object>	elements;
+	ElementType			member;
+	RetentionPolicy		policy;
+
+	public Annotation(TypeRef 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 TypeRef getName() {
+		return name;
+	}
+
+	public ElementType getElementType() {
+		return member;
+	}
+	
+	public RetentionPolicy getRetentionPolicy() {
+		return policy;
+	}
+	
+	public String toString() {
+		return name + ":" + member + ":" + policy + ":" + elements;
+	}
+
+	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);
+	}
+
+	public Set<String> keySet() {
+		if (elements == null)
+			return Collections.emptySet();
+		
+		return elements.keySet();
+	}
+	public <T extends java.lang.annotation.Annotation> T getAnnotation() throws Exception {
+		String cname = name.getFQN();
+		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 = name.getFQN();
+		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 100755
index 0000000..3126056
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
@@ -0,0 +1,1558 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.jar.*;
+import java.util.regex.*;
+import java.util.zip.*;
+
+import aQute.bnd.component.*;
+import aQute.bnd.differ.*;
+import aQute.bnd.differ.Baseline.Info;
+import aQute.bnd.make.*;
+import aQute.bnd.make.component.*;
+import aQute.bnd.make.metatype.*;
+import aQute.bnd.maven.*;
+import aQute.bnd.service.*;
+import aQute.bnd.service.diff.*;
+import aQute.lib.collections.*;
+import aQute.lib.osgi.Descriptors.PackageRef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.libg.generics.*;
+import aQute.libg.header.*;
+
+/**
+ * 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 {
+	static Pattern					IR_PATTERN			= Pattern
+																.compile("[{]?-?@?(?:[^=]+=)?\\s*([^}!]+).*");
+	private final DiffPluginImpl	differ				= new DiffPluginImpl();
+	private 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;
+	private final List<File>		sourcePath			= new ArrayList<File>();
+	private final Make				make				= new Make(this);
+
+	public Builder(Processor parent) {
+		super(parent);
+	}
+
+	public Builder() {
+	}
+
+	public Jar build() throws Exception {
+		trace("build");
+		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");
+
+		Jar dot = new Jar("dot");
+		try {
+			long modified = Long.parseLong(getProperty("base.modified"));
+			dot.updateModified(modified, "Base modified");
+		}
+		catch (Exception e) {
+			// Ignore
+		}
+		setJar(dot);
+
+		doExpand(dot);
+		doIncludeResources(dot);
+		doWab(dot);
+
+		// 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())
+			warning("The JAR is empty: The instructions for the JAR named %s did not cause any content to be included, this is likely wrong",
+					getBsn());
+
+		dot.updateModified(lastModified(), "Last Modified Processor");
+		dot.setName(getBsn());
+
+		sign(dot);
+		doDigests(dot);
+		doSaveManifest(dot);
+
+		doDiff(dot); // check if need to diff this bundle
+		doBaseline(dot); // check for a baseline
+		return dot;
+	}
+
+	/**
+	 * Check if we need to calculate any checksums.
+	 * 
+	 * @param dot
+	 * @throws Exception
+	 */
+	private void doDigests(Jar dot) throws Exception {
+		Parameters ps = OSGiHeader.parseHeader(getProperty(DIGESTS));
+		if (ps.isEmpty())
+			return;
+		trace("digests %s", ps);
+		String[] digests = ps.keySet().toArray(new String[ps.size()]);
+		dot.calcChecksums(digests);
+	}
+
+	/**
+	 * Allow any local initialization by subclasses before we build.
+	 */
+	public void init() throws Exception {
+		begin();
+		doRequireBnd();
+
+		// Check if we have sensible setup
+
+		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");
+
+	}
+
+	/**
+	 * 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;
+
+		trace("wab %s %s", wab, wablib);
+		setBundleClasspath(append("WEB-INF/classes", getProperty(BUNDLE_CLASSPATH)));
+
+		Set<String> paths = new HashSet<String>(dot.getResources().keySet());
+
+		for (String path : paths) {
+			if (path.indexOf('/') > 0 && !Character.isUpperCase(path.charAt(0))) {
+				trace("wab: moving: %s", path);
+				dot.rename(path, "WEB-INF/classes/" + path);
+			}
+		}
+
+		Parameters clauses = parseHeader(getProperty(WABLIB));
+		for (String key : clauses.keySet()) {
+			File f = getFile(key);
+			addWabLib(dot, f);
+		}
+		doIncludeResource(dot, wab);
+		return dot;
+	}
+
+	/**
+	 * 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);
+
+		Parameters infos = parseHeader(signing);
+		for (Entry<String, Attrs> entry : infos.entrySet()) {
+			for (SignerPlugin signer : signers) {
+				signer.sign(this, entry.getKey());
+			}
+		}
+	}
+
+	public boolean hasSources() {
+		return isTrue(getProperty(SOURCES));
+	}
+
+	/**
+	 * Answer extra packages. In this case we implement conditional package. Any
+	 */
+	protected Jar getExtra() throws Exception {
+		Parameters conditionals = getParameters(CONDITIONAL_PACKAGE);
+		if (conditionals.isEmpty())
+			return null;
+		Instructions instructions = new Instructions(conditionals);
+
+		Collection<PackageRef> referred = instructions.select(getReferred().keySet(), false);
+		referred.removeAll(getContained().keySet());
+
+		Jar jar = new Jar("conditional-import");
+		addClose(jar);
+		for (PackageRef pref : referred) {
+			for (Jar cpe : getClasspath()) {
+				Map<String, Resource> map = cpe.getDirectories().get(pref.getPath());
+				if (map != null) {
+					jar.addDirectory(map, false);
+					break;
+				}
+			}
+		}
+		if (jar.getDirectories().size() == 0)
+			return null;
+		return jar;
+	}
+
+	/**
+	 * 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(getImports(), null);
+		cleanupVersion(getExports(), 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(Packages packages, String defaultVersion) {
+		for (Map.Entry<PackageRef, Attrs> entry : packages.entrySet()) {
+			Attrs 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<PackageRef> packages = Create.set();
+
+		for (TypeRef typeRef : getClassspace().keySet()) {
+			PackageRef packageRef = typeRef.getPackageRef();
+			String sourcePath = typeRef.getSourcePath();
+			String packagePath = packageRef.getPath();
+
+			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();
+
+				// TODO should use bcp?
+
+				File f = getFile(root, sourcePath);
+				if (f.exists()) {
+					found = true;
+					if (!packages.contains(packageRef)) {
+						packages.add(packageRef);
+						File bdir = getFile(root, packagePath);
+						for (int j = 0; j < fixed.length; j++) {
+							File ff = getFile(bdir, fixed[j]);
+							if (ff.isFile()) {
+								String name = "OSGI-OPT/src/" + packagePath + "/" + fixed[j];
+								dot.putResource(name, new FileResource(ff));
+							}
+						}
+					}
+					if (packageRef.isDefaultPackage())
+						System.err.println("Duh?");
+					dot.putResource("OSGI-OPT/src/" + sourcePath, new FileResource(f));
+				}
+			}
+			if (!found) {
+				for (Jar jar : getClasspath()) {
+					Resource resource = jar.getResource(sourcePath);
+					if (resource != null) {
+						dot.putResource("OSGI-OPT/src/" + sourcePath, resource);
+					}
+					else {
+						resource = jar.getResource("OSGI-OPT/src/" + sourcePath);
+						if (resource != null) {
+							dot.putResource("OSGI-OPT/src/" + sourcePath, 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;
+	private Tree	tree;
+
+	public Collection<File> getSourcePath() {
+		if (firstUse) {
+			firstUse = false;
+			String sp = getProperty(SOURCEPATH);
+			if (sp != null) {
+				Parameters 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(this);
+		// Give the verifier the benefit of our analysis
+		// prevents parsing the files twice
+		verifier.verify();
+		getInfo(verifier);
+	}
+
+	private void doExpand(Jar dot) throws IOException {
+
+		// Build an index of the class path that we can then
+		// use destructively
+		MultiMap<String, Jar> packages = new MultiMap<String, Jar>();
+		for (Jar srce : getClasspath()) {
+			for (Entry<String, Map<String, Resource>> e : srce.getDirectories().entrySet()) {
+				if (e.getValue() != null)
+					packages.add(e.getKey(), srce);
+			}
+		}
+
+		Parameters privatePackages = getPrivatePackage();
+		if (isTrue(getProperty(Constants.UNDERTEST))) {
+			String h = getProperty(Constants.TESTPACKAGES, "test;presence:=optional");
+			privatePackages.putAll(parseHeader(h));
+		}
+
+		if (!privatePackages.isEmpty()) {
+			Instructions privateFilter = new Instructions(privatePackages);
+			Set<Instruction> unused = doExpand(dot, packages, privateFilter);
+
+			if (!unused.isEmpty()) {
+				warning("Unused Private-Package instructions, no such package(s) on the class path: %s",
+						unused);
+			}
+		}
+
+		Parameters exportedPackage = getExportPackage();
+		if (!exportedPackage.isEmpty()) {
+			Instructions exportedFilter = new Instructions(exportedPackage);
+
+			// We ignore unused instructions for exports, they should show
+			// up as errors during analysis. Otherwise any overlapping
+			// packages with the private packages should show up as
+			// unused
+
+			doExpand(dot, packages, exportedFilter);
+		}
+	}
+
+	/**
+	 * Destructively filter the packages from the build up index. This index is
+	 * used by the Export Package as well as the Private Package
+	 * 
+	 * @param jar
+	 * @param name
+	 * @param instructions
+	 */
+	private Set<Instruction> doExpand(Jar jar, MultiMap<String, Jar> index, Instructions filter) {
+		Set<Instruction> unused = Create.set();
+
+		for (Entry<Instruction, Attrs> e : filter.entrySet()) {
+			Instruction instruction = e.getKey();
+			if (instruction.isDuplicate())
+				continue;
+
+			Attrs directives = e.getValue();
+
+			// We can optionally filter on the
+			// source of the package. We assume
+			// they all match but this can be overridden
+			// on the instruction
+			Instruction from = new Instruction(directives.get(FROM_DIRECTIVE, "*"));
+
+			boolean used = false;
+
+			for (Iterator<Entry<String, List<Jar>>> entry = index.entrySet().iterator(); entry
+					.hasNext();) {
+				Entry<String, List<Jar>> p = entry.next();
+
+				String directory = p.getKey();
+				PackageRef packageRef = getPackageRef(directory);
+
+				// Skip * and meta data, we're talking packages!
+				if (packageRef.isMetaData() && instruction.isAny())
+					continue;
+
+				if (!instruction.matches(packageRef.getFQN()))
+					continue;
+
+				// Ensure it is never matched again
+				entry.remove();
+
+				// ! effectively removes it from consideration by others (this
+				// includes exports)
+				if (instruction.isNegated())
+					continue;
+
+				// Do the from: directive, filters on the JAR type
+				List<Jar> providers = filterFrom(from, p.getValue());
+				if (providers.isEmpty())
+					continue;
+
+				int splitStrategy = getSplitStrategy(directives.get(SPLIT_PACKAGE_DIRECTIVE));
+				copyPackage(jar, providers, directory, splitStrategy);
+
+				used = true;
+			}
+
+			if (!used && !isTrue(directives.get("optional:")))
+				unused.add(instruction);
+		}
+		return unused;
+	}
+
+	/**
+	 * @param from
+	 * @return
+	 */
+	private List<Jar> filterFrom(Instruction from, List<Jar> providers) {
+		if (from.isAny())
+			return providers;
+
+		List<Jar> np = new ArrayList<Jar>();
+		for (Iterator<Jar> i = providers.iterator(); i.hasNext();) {
+			Jar j = i.next();
+			if (from.matches(j.getName())) {
+				np.add(j);
+			}
+		}
+		return np;
+	}
+
+	/**
+	 * Copy the package from the providers based on the split package strategy.
+	 * 
+	 * @param dest
+	 * @param providers
+	 * @param directory
+	 * @param splitStrategy
+	 */
+	private void copyPackage(Jar dest, List<Jar> providers, String path, int splitStrategy) {
+		switch (splitStrategy) {
+			case SPLIT_MERGE_LAST :
+				for (Jar srce : providers) {
+					copy(dest, srce, path, true);
+				}
+				break;
+
+			case SPLIT_MERGE_FIRST :
+				for (Jar srce : providers) {
+					copy(dest, srce, path, false);
+				}
+				break;
+
+			case SPLIT_ERROR :
+				error(diagnostic(path, providers));
+				break;
+
+			case SPLIT_FIRST :
+				copy(dest, providers.get(0), path, false);
+				break;
+
+			default :
+				if (providers.size() > 1)
+					warning("%s", diagnostic(path, providers));
+				for (Jar srce : providers) {
+					copy(dest, srce, path, false);
+				}
+				break;
+		}
+	}
+
+	/**
+	 * Cop
+	 * 
+	 * @param dest
+	 * @param srce
+	 * @param path
+	 * @param overwriteResource
+	 */
+	private void copy(Jar dest, Jar srce, String path, boolean overwrite) {
+		dest.copy(srce, path, overwrite);
+
+		String key = path + "/bnd.info";
+		Resource r = dest.getResource(key);
+		if (r != null)
+			dest.putResource(key, new PreprocessResource(this, r));
+
+		if (hasSources()) {
+			String srcPath = "OSGI-OPT/src/" + path;
+			Map<String, Resource> srcContents = srce.getDirectories().get(srcPath);
+			if (srcContents != null) {
+				dest.addDirectory(srcContents, overwrite);
+			}
+		}
+	}
+
+	/**
+	 * Analyze the classpath for a split package
+	 * 
+	 * @param pack
+	 * @param classpath
+	 * @param source
+	 * @return
+	 */
+	private String diagnostic(String pack, List<Jar> culprits) {
+		// Default is like merge-first, but with a warning
+		return "Split package, multiple jars provide the same package:"
+				+ pack
+				+ "\nUse Import/Export Package directive -split-package:=(merge-first|merge-last|error|first) to get rid of this warning\n"
+				+ "Package found in   " + culprits + "\n" //
+				+ "Class path         " + getClasspath();
+	}
+
+	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 unused 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(Instructions instructions, String pack, Set<Instruction> unused,
+			String source) {
+		for (Entry<Instruction, Attrs> 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 = new Instruction(from);
+				if (!f.matches(source) || f.isNegated())
+					continue;
+			}
+
+			// Now do the normal
+			// matching
+			if (pattern.matches(pack)) {
+				if (unused != null)
+					unused.remove(pattern);
+				return pattern;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * 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 {
+		Parameters clauses = parseHeader(includes);
+		doIncludeResource(jar, clauses);
+	}
+
+	private void doIncludeResource(Jar jar, Parameters clauses) throws ZipException, IOException,
+			Exception {
+		for (Entry<String, Attrs> 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;
+		boolean absentIsOk = 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("-")) {
+			source = source.substring(1);
+			absentIsOk = true;
+		}
+
+		if (source.startsWith("@")) {
+			extractFromJar(jar, source.substring(1), parts.length == 1 ? "" : destination,
+					absentIsOk);
+		}
+		else
+			if (extra.containsKey("cmd")) {
+				doCommand(jar, source, destination, extra, preprocess, absentIsOk);
+			}
+			else
+				if (extra.containsKey("literal")) {
+					String literal = extra.get("literal");
+					Resource r = new EmbeddedResource(literal.getBytes("UTF-8"), 0);
+					String x = 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()) {
+						if (absentIsOk)
+							return;
+
+						noSuchFile(jar, name, extra, source, destinationPath);
+					}
+					else
+						copy(jar, destinationPath, sourceFile, preprocess, extra);
+				}
+	}
+
+	/**
+	 * It is possible in Include-Resource to use a system command that generates
+	 * the contents, this is indicated with {@code cmd} attribute. The command
+	 * can be repeated for a number of source files with the {@code for}
+	 * attribute which indicates a list of repetitions, often down with the
+	 * {@link Macro#_lsa(String[])} or {@link Macro#_lsb(String[])} macro. The
+	 * repetition will repeat the given command for each item. The @} macro can
+	 * be used to replace the current item. If no {@code for} is given, the
+	 * source is used as the only item.
+	 * 
+	 * If the destination contains a macro, each iteration will create a new
+	 * file, otherwise the destination name is used.
+	 * 
+	 * The execution of the command is delayed until the JAR is actually written
+	 * to the file system for performance reasons.
+	 * 
+	 * @param jar
+	 * @param source
+	 * @param destination
+	 * @param extra
+	 * @param preprocess
+	 * @param absentIsOk
+	 */
+	private void doCommand(Jar jar, String source, String destination, Map<String, String> extra,
+			boolean preprocess, boolean absentIsOk) {
+		String repeat = extra.get("for"); // TODO constant
+		if (repeat == null)
+			repeat = source;
+
+		Collection<String> requires = split(extra.get("requires"));
+		long lastModified = 0;
+		for (String required : requires) {
+			File file = getFile(required);
+			if (!file.isFile()) {
+				error("Include-Resource.cmd for %s, requires %s, but no such file %s", source,
+						required, file.getAbsoluteFile());
+			}
+			else
+				lastModified = Math.max(lastModified, file.lastModified());
+		}
+
+		String cmd = extra.get("cmd");
+
+		Collection<String> items = Processor.split(repeat);
+
+		CombinedResource cr = null;
+
+		if (!destination.contains("${@}")) {
+			cr = new CombinedResource();
+		}
+		trace("last modified requires %s", lastModified);
+		
+		for (String item : items) {
+			setProperty("@", item);
+			try {
+				String path = getReplacer().process(destination);
+				String command = getReplacer().process(cmd);
+				File file = getFile(item);
+
+				Resource r = new CommandResource(command, this, Math.max(lastModified,
+						file.exists() ? file.lastModified():0L));
+
+				if (preprocess)
+					r = new PreprocessResource(this, r);
+
+				if (cr == null)
+					jar.putResource(path, r);
+				else
+					cr.addResource(r);
+			}
+			finally {
+				unsetProperty("@");
+			}
+		}
+		
+		// Add last so the correct modification date is used
+		// to update the modified time.
+		if ( cr != null)
+			jar.putResource(destination, cr);
+	}
+
+	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);
+		}
+
+		Instruction.Filter iFilter = null;
+		if (filter != null) {
+			iFilter = new Instruction.Filter(new Instruction(filter), recursive, getDoNotCopy());
+		}
+		else {
+			iFilter = new Instruction.Filter(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) {
+			// Do not touch the manifest so this also
+			// works for signed files.
+			src.setDoNotTouchManifest();
+			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, boolean absentIsOk)
+			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 = new Instruction(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) {
+			if (absentIsOk)
+				return;
+
+			error("Can not find JAR file " + source);
+		}
+		else {
+			addAll(jar, sub, instr, destination);
+		}
+	}
+
+	/**
+	 * 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 to, Jar sub, Instruction filter) {
+		return addAll(to, 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 to, 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 |= to.putResource(Processor.appendPath(destination, name),
+						sub.getResource(name), true);
+		}
+		return dupl;
+	}
+
+	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);
+			}
+		}
+	}
+
+	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) {
+			Parameters 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 = 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;
+
+		Parameters 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();
+			}
+		}
+
+		Instructions instructions = new Instructions(subsMap);
+
+		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 = instructions.keySet().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 (PackageRef imp : getImports().keySet()) {
+					if (!imp.isJava()) {
+						sb.append("(org.osgi.framework.PackagePermission \"");
+						sb.append(imp);
+						sb.append("\" \"import\")\r\n");
+					}
+				}
+				for (PackageRef 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.
+	 * 
+	 * @param f
+	 * @return
+	 */
+	public boolean isInScope(Collection<File> resources) throws Exception {
+		Parameters 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")));
+		}
+
+		Collection<String> ir = getIncludedResourcePrefixes();
+
+		Instructions instructions = new Instructions(clauses);
+
+		for (File r : resources) {
+			String cpEntry = getClasspathEntrySuffix(r);
+			if (cpEntry != null) {
+				String pack = Descriptors.getPackage(cpEntry);
+				Instruction i = matches(instructions, pack, null, r.getName());
+				if (i != null)
+					return !i.isNegated();
+			}
+
+			// Check if this resource starts with one of the I-C header
+			// paths.
+			String path = r.getAbsolutePath();
+			for (String p : ir) {
+				if (path.startsWith(p))
+					return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Extra the paths for the directories and files that are used in the
+	 * Include-Resource header.
+	 * 
+	 * @return
+	 */
+	private Collection<String> getIncludedResourcePrefixes() {
+		List<String> prefixes = new ArrayList<String>();
+		Parameters includeResource = getIncludeResource();
+		for (Entry<String, Attrs> p : includeResource.entrySet()) {
+			if (p.getValue().containsKey("literal"))
+				continue;
+
+			Matcher m = IR_PATTERN.matcher(p.getKey());
+			if (m.matches()) {
+				File f = getFile(m.group(1));
+				prefixes.add(f.getAbsolutePath());
+			}
+		}
+		return prefixes;
+	}
+
+	/**
+	 * 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 this bundle to another bundle for the given packages.
+	 * 
+	 * @throws Exception
+	 */
+
+	public void doDiff(Jar dot) throws Exception {
+		Parameters diffs = parseHeader(getProperty("-diff"));
+		if (diffs.isEmpty())
+			return;
+
+		trace("diff %s", diffs);
+
+		if (tree == null)
+			tree = differ.tree(this);
+
+		for (Entry<String, Attrs> entry : diffs.entrySet()) {
+			String path = entry.getKey();
+			File file = getFile(path);
+			if (!file.isFile()) {
+				error("Diffing against %s that is not a file", file);
+				continue;
+			}
+
+			boolean full = entry.getValue().get("--full") != null;
+			boolean warning = entry.getValue().get("--warning") != null;
+
+			Tree other = differ.tree(file);
+			Diff api = tree.diff(other).get("<api>");
+			Instructions instructions = new Instructions(entry.getValue().get("--pack"));
+
+			trace("diff against %s --full=%s --pack=%s --warning=%s", file, full, instructions);
+			for (Diff p : api.getChildren()) {
+				String pname = p.getName();
+				if (p.getType() == Type.PACKAGE && instructions.matches(pname)) {
+					if (p.getDelta() != Delta.UNCHANGED) {
+
+						if (!full)
+							if (warning)
+								warning("Differ %s", p);
+							else
+								error("Differ %s", p);
+						else {
+							if (warning)
+								warning("Diff found a difference in %s for packages %s", file,
+										instructions);
+							else
+								error("Diff found a difference in %s for packages %s", file,
+										instructions);
+							show(p, "", warning);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Show the diff recursively
+	 * 
+	 * @param p
+	 * @param i
+	 */
+	private void show(Diff p, String indent, boolean warning) {
+		Delta d = p.getDelta();
+		if (d == Delta.UNCHANGED)
+			return;
+
+		if (warning)
+			warning("%s%s", indent, p);
+		else
+			error("%s%s", indent, p);
+
+		indent = indent + " ";
+		switch (d) {
+			case CHANGED :
+			case MAJOR :
+			case MINOR :
+			case MICRO :
+				break;
+
+			default :
+				return;
+		}
+		for (Diff c : p.getChildren())
+			show(c, indent, warning);
+	}
+
+	/**
+	 * Base line against a previous version
+	 * 
+	 * @throws Exception
+	 */
+
+	private void doBaseline(Jar dot) throws Exception {
+		Parameters diffs = parseHeader(getProperty("-baseline"));
+		if (diffs.isEmpty())
+			return;
+
+		System.err.printf("baseline %s%n", diffs);
+
+		Baseline baseline = new Baseline(this, differ);
+
+		for (Entry<String, Attrs> entry : diffs.entrySet()) {
+			String path = entry.getKey();
+			File file = getFile(path);
+			if (!file.isFile()) {
+				error("Diffing against %s that is not a file", file);
+				continue;
+			}
+			Jar other = new Jar(file);
+			Set<Info> infos = baseline.baseline(dot, other, null);
+			for (Info info : infos) {
+				if (info.mismatch) {
+					error("%s %-50s %-10s %-10s %-10s %-10s %-10s\n", info.mismatch ? '*' : ' ',
+							info.packageName, info.packageDiff.getDelta(), info.newerVersion,
+							info.olderVersion, info.suggestedVersion,
+							info.suggestedIfProviders == null ? "-" : info.suggestedIfProviders);
+				}
+			}
+		}
+	}
+
+	public void addSourcepath(Collection<File> sourcepath) {
+		for (File f : sourcepath) {
+			addSourcepath(f);
+		}
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/BundleId.java b/bundleplugin/src/main/java/aQute/lib/osgi/BundleId.java
new file mode 100644
index 0000000..e500e53
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/BundleId.java
@@ -0,0 +1,44 @@
+package aQute.lib.osgi;
+
+
+/**
+ * Holds the bundle bsn + version pair
+ * 
+ */
+public class BundleId implements Comparable<BundleId> {
+	final String	bsn;
+	final String	version;
+
+	public BundleId(String bsn, String version) {
+		this.bsn = bsn.trim();
+		this.version = version.trim();
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	public String getBsn() {
+		return bsn;
+	}
+
+	public boolean isValid() {
+		return Verifier.isVersion(version) && Verifier.isBsn(bsn);
+	}
+
+	public boolean equals(Object o) {
+		return this == o || ((o instanceof BundleId) && compareTo((BundleId) o) == 0);
+	}
+	
+	public int hashCode() {
+		return bsn.hashCode() ^ version.hashCode();
+	}
+
+	public int compareTo(BundleId other) {
+		int result = bsn.compareTo(other.bsn);
+		if ( result != 0)
+			return result;
+		
+		return version.compareTo(other.version);
+	}
+}
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..c878665
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/ClassDataCollector.java
@@ -0,0 +1,91 @@
+package aQute.lib.osgi;
+
+import aQute.lib.osgi.Descriptors.TypeRef;
+
+public class ClassDataCollector {
+    public void classBegin(int access, TypeRef name) {
+    }
+
+    public boolean classStart(int access, TypeRef className) {
+        classBegin(access,className);
+        return true;
+    }
+
+    public void extendsClass(TypeRef zuper) throws Exception {
+    }
+
+    public void implementsInterfaces(TypeRef[] interfaces) throws Exception {
+    }
+
+    public void addReference(TypeRef ref) {
+    }
+
+    public void annotation(Annotation annotation) {
+    }
+
+    public void parameter(int p) {
+    }
+
+    public void method(Clazz.MethodDef defined) {
+    }
+
+    public void field(Clazz.FieldDef defined) {
+    }
+
+    public void reference(Clazz.MethodDef referenced) {
+    }
+
+    public void reference(Clazz.FieldDef referenced) {
+    }
+
+    public void classEnd() throws Exception {
+    }
+
+    public void deprecated() throws Exception {
+    }
+
+
+    /**
+     * 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(TypeRef 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 
+	 * @throws Exception 
+	 */
+	public void innerClass(TypeRef innerClass, TypeRef outerClass, String innerName,
+			int innerClassAccessFlags) throws Exception {		
+	}
+
+	public void signature(String signature) {
+	}
+
+	public void constant(Object object) {
+	}
+
+	public void memberEnd() {
+	}
+
+	public void version(int minor, int major) {
+		// TODO Auto-generated method stub
+		
+	}
+
+	public void referenceMethod(int access, TypeRef className, String method, String descriptor) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}
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 100755
index 0000000..e182e1f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Clazz.java
@@ -0,0 +1,1645 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.lang.annotation.*;
+import java.lang.reflect.*;
+import java.nio.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.lib.osgi.Descriptors.Descriptor;
+import aQute.lib.osgi.Descriptors.PackageRef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.libg.generics.*;
+
+public class Clazz {
+
+	static Pattern	METHOD_DESCRIPTOR	= Pattern.compile("\\((.*)\\)(.+)");
+
+	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 {
+		JDK1_1(45, "JRE-1.1"), JDK1_2(46, "J2SE-1.2"), //
+		JDK1_3(47, "J2SE-1.3"), //
+		JDK1_4(48, "J2SE-1.4"), //
+		J2SE5(49, "J2SE-1.5"), //
+		J2SE6(50, "JavaSE-1.6"), //
+		OpenJDK7(51, "JavaSE-1.7"), //
+		UNKNOWN(Integer.MAX_VALUE, "<>")//
+		;
+
+		final int		major;
+		final String	ee;
+
+		JAVA(int major, String ee) {
+			this.major = major;
+			this.ee = ee;
+		}
+
+		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 JAVA getJava(int major, int minor) {
+			for (JAVA j : JAVA.values()) {
+				if (j.major == major)
+					return j;
+			}
+			return UNKNOWN;
+		}
+
+		public String getEE() {
+			return ee;
+		}
+	}
+
+	public static enum QUERY {
+		IMPLEMENTS, EXTENDS, IMPORTS, NAMED, ANY, VERSION, CONCRETE, ABSTRACT, PUBLIC, ANNOTATED, RUNTIMEANNOTATIONS, CLASSANNOTATIONS;
+
+	}
+
+	public final static EnumSet<QUERY>	HAS_ARGUMENT	= EnumSet.of(QUERY.IMPLEMENTS,
+																QUERY.EXTENDS, QUERY.IMPORTS,
+																QUERY.NAMED, QUERY.VERSION,
+																QUERY.ANNOTATED);
+
+	/**
+	 * <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
+
+	// a thing not in the source code
+	final static int					ACC_SYNTHETIC	= 0x1000;
+	final static int					ACC_ANNOTATION	= 0x2000;
+	final static int					ACC_ENUM		= 0x4000;
+
+	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;
+	}
+
+	public class Def {
+		final int		access;
+		Set<TypeRef>	annotations;
+
+		public Def(int access) {
+			this.access = access;
+		}
+
+		public int getAccess() {
+			return access;
+		}
+
+		public boolean isEnum() {
+			return (access & ACC_ENUM) != 0;
+		}
+
+		public boolean isPublic() {
+			return Modifier.isPublic(access);
+		}
+
+		public boolean isAbstract() {
+			return Modifier.isAbstract(access);
+		}
+
+		public boolean isProtected() {
+			return Modifier.isProtected(access);
+		}
+
+		public boolean isFinal() {
+			return Modifier.isFinal(access) || Clazz.this.isFinal();
+		}
+
+		public boolean isStatic() {
+			return Modifier.isStatic(access);
+		}
+
+		public boolean isPrivate() {
+			return Modifier.isPrivate(access);
+		}
+
+		public boolean isNative() {
+			return Modifier.isNative(access);
+		}
+
+		public boolean isTransient() {
+			return Modifier.isTransient(access);
+		}
+
+		public boolean isVolatile() {
+			return Modifier.isVolatile(access);
+		}
+
+		public boolean isInterface() {
+			return Modifier.isInterface(access);
+		}
+
+		public boolean isSynthetic() {
+			return (access & ACC_SYNTHETIC) != 0;
+		}
+
+		void addAnnotation(Annotation a) {
+			if (annotations == null)
+				annotations = Create.set();
+			annotations.add(analyzer.getTypeRef(a.name.getBinary()));
+		}
+
+		public Collection<TypeRef> getAnnotations() {
+			return annotations;
+		}
+	}
+
+	public class FieldDef extends Def {
+		final String		name;
+		final Descriptor	descriptor;
+		String				signature;
+		Object				constant;
+		boolean				deprecated;
+
+		public boolean isDeprecated() {
+			return deprecated;
+		}
+
+		public void setDeprecated(boolean deprecated) {
+			this.deprecated = deprecated;
+		}
+
+		public FieldDef(int access, String name, String descriptor) {
+			super(access);
+			this.name = name;
+			this.descriptor = analyzer.getDescriptor(descriptor);
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public String toString() {
+			return getName();
+		}
+
+		public TypeRef getType() {
+			return descriptor.getType();
+		}
+
+		public TypeRef getContainingClass() {
+			return getClassName();
+		}
+
+		public Descriptor getDescriptor() {
+			return descriptor;
+		}
+
+		public void setConstant(Object o) {
+			this.constant = o;
+		}
+
+		public Object getConstant() {
+			return this.constant;
+		}
+
+		// TODO change to use proper generics
+		public String getGenericReturnType() {
+			String use = descriptor.toString();
+			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 getSignature() {
+			return signature;
+		}
+
+	}
+
+	public class MethodDef extends FieldDef {
+		public MethodDef(int access, String method, String descriptor) {
+			super(access, method, descriptor);
+		}
+
+		public boolean isConstructor() {
+			return name.equals("<init>") || name.equals("<clinit>");
+		}
+
+		public TypeRef[] getPrototype() {
+			return descriptor.getPrototype();
+		}
+
+	}
+
+	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
+			-1, // 13 Not defined
+			-1, // 14 Not defined
+			3, // 15 CONSTANT_MethodHandle
+			2, // 16 CONSTANT_MethodType
+			-1, // 17 Not defined
+			4, // 18 CONSTANT_InvokeDynamic
+									};
+
+	boolean				hasRuntimeAnnotations;
+	boolean				hasClassAnnotations;
+
+	TypeRef				className;
+	Object				pool[];
+	int					intPool[];
+	Set<PackageRef>		imports		= Create.set();
+	String				path;
+	int					minor		= 0;
+	int					major		= 0;
+	int					innerAccess	= -1;
+	int					accessx		= 0;
+	String				sourceFile;
+	Set<TypeRef>		xref;
+	Set<Integer>		classes;
+	Set<Integer>		descriptors;
+	Set<TypeRef>		annotations;
+	int					forName		= 0;
+	int					class$		= 0;
+	TypeRef[]			interfaces;
+	TypeRef				zuper;
+	ClassDataCollector	cd			= null;
+	Resource			resource;
+	FieldDef			last		= null;
+	boolean				deprecated;
+
+	final Analyzer		analyzer;
+
+	public Clazz(Analyzer analyzer, String path, Resource resource) {
+		this.path = path;
+		this.resource = resource;
+		this.analyzer = analyzer;
+	}
+
+	public Set<TypeRef> parseClassFile() throws Exception {
+		return parseClassFileWithCollector(null);
+	}
+
+	public Set<TypeRef> parseClassFile(InputStream in) throws Exception {
+		return parseClassFile(in, null);
+	}
+
+	public Set<TypeRef> parseClassFileWithCollector(ClassDataCollector cd) throws Exception {
+		InputStream in = resource.openInputStream();
+		try {
+			return parseClassFile(in, cd);
+		} finally {
+			in.close();
+		}
+	}
+
+	public Set<TypeRef> parseClassFile(InputStream in, ClassDataCollector cd) throws Exception {
+		DataInputStream din = new DataInputStream(in);
+		try {
+			this.cd = cd;
+			return parseClassFile(din);
+		} finally {
+			cd = null;
+			din.close();
+		}
+	}
+
+	Set<TypeRef> parseClassFile(DataInputStream in) throws Exception {
+		xref = new HashSet<TypeRef>();
+		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
+		if (cd != null)
+			cd.version(minor, major);
+		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
+		 */
+
+		accessx = in.readUnsignedShort(); // access
+
+		int this_class = in.readUnsignedShort();
+		className = analyzer.getTypeRef((String) pool[intPool[this_class]]);
+
+		try {
+
+			if (cd != null) {
+				if (!cd.classStart(accessx, className))
+					return null;
+			}
+
+			int super_class = in.readUnsignedShort();
+			String superName = (String) pool[intPool[super_class]];
+			if (superName != null) {
+				zuper = analyzer.getTypeRef(superName);
+			}
+
+			if (zuper != null) {
+				referTo(zuper);
+				if (cd != null)
+					cd.extendsClass(zuper);
+			}
+
+			int interfacesCount = in.readUnsignedShort();
+			if (interfacesCount > 0) {
+				interfaces = new TypeRef[interfacesCount];
+				for (int i = 0; i < interfacesCount; i++)
+					interfaces[i] = analyzer.getTypeRef((String) pool[intPool[in
+							.readUnsignedShort()]]);
+				if (cd != null)
+					cd.implementsInterfaces(interfaces);
+			}
+
+			int fieldsCount = in.readUnsignedShort();
+			for (int i = 0; i < fieldsCount; i++) {
+				int 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, name, pool[descriptor_index]
+							.toString()));
+				descriptors.add(Integer.valueOf(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.getBinary(), "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.getBinary(), "class$",
+							"(Ljava/lang/String;)Ljava/lang/Class;");
+				}
+			}
+			
+			// There are some serious changes in the
+			// class file format. So we do not do any crawling
+			// it has also become less important
+			if ( major >= JAVA.OpenJDK7.major )
+				crawl = false;
+
+			//
+			// Handle the methods
+			//
+			int methodCount = in.readUnsignedShort();
+			for (int i = 0; i < methodCount; i++) {
+				int access_flags = in.readUnsignedShort();
+				int name_index = in.readUnsignedShort();
+				int descriptor_index = in.readUnsignedShort();
+				descriptors.add(Integer.valueOf(descriptor_index));
+				String name = pool[name_index].toString();
+				String descriptor = pool[descriptor_index].toString();
+				if (cd != null) {
+					MethodDef mdef = new MethodDef(access_flags, name, descriptor);
+					last = mdef;
+					cd.method(mdef);
+				}
+
+				if ("<init>".equals(name)) {
+					doAttributes(in, ElementType.CONSTRUCTOR, crawl);
+				} else {
+					doAttributes(in, ElementType.METHOD, crawl);
+				}
+			}
+			if (cd != null)
+				cd.memberEnd();
+
+			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 descr = (String) pool[n];
+
+				TypeRef clazz = analyzer.getTypeRef(descr);
+				referTo(clazz);
+			}
+
+			//
+			// 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<TypeRef> 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(Integer.valueOf(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(Integer.valueOf(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();
+		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 Exception
+	 */
+	private void doAttributes(DataInputStream in, ElementType member, boolean crawl)
+			throws Exception {
+		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 Exception
+	 */
+	private void doAttribute(DataInputStream in, ElementType member, boolean crawl)
+			throws Exception {
+		int attribute_name_index = in.readUnsignedShort();
+		String attributeName = (String) pool[attribute_name_index];
+		long attribute_length = in.readInt();
+		attribute_length &= 0xFFFFFFFF;
+		if ("Deprecated".equals(attributeName)) {
+			if (cd != null)
+				cd.deprecated();
+		} else 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];
+			TypeRef cName = analyzer.getTypeRef((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 Exception
+	 */
+	private void doInnerClasses(DataInputStream in) throws Exception {
+		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) {
+				TypeRef innerClass = null;
+				TypeRef outerClass = null;
+				String innerName = null;
+
+				if (inner_class_info_index != 0) {
+					int nameIndex = intPool[inner_class_info_index];
+					innerClass = analyzer.getTypeRef((String) pool[nameIndex]);
+				}
+
+				if (outer_class_info_index != 0) {
+					int nameIndex = intPool[outer_class_info_index];
+					outerClass = analyzer.getTypeRef((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];
+
+		// s.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 Exception
+	 */
+	private void doCode(DataInputStream in) throws Exception {
+		/* 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)
+					getMethodDef(0, mref);
+				break;
+			}
+
+			case OpCodes.invokevirtual: {
+				int mref = 0xFFFF & bb.getShort();
+				if (cd != null)
+					getMethodDef(0, mref);
+				break;
+			}
+
+			case OpCodes.invokeinterface: {
+				int mref = 0xFFFF & bb.getShort();
+				if (cd != null)
+					getMethodDef(0, mref);
+				break;
+			}
+
+			case OpCodes.invokestatic: {
+				int methodref = 0xFFFF & bb.getShort();
+				if (cd != null)
+					getMethodDef(0, methodref);
+
+				if ((methodref == forName || methodref == class$) && lastReference != -1
+						&& pool[intPool[lastReference]] instanceof String) {
+					String fqn = (String) pool[intPool[lastReference]];
+					if (!fqn.equals("class") && fqn.indexOf('.') > 0) {
+						TypeRef clazz = analyzer.getTypeRefFromFQN(fqn);
+						referTo(clazz);
+					}
+					lastReference = -1;
+				}
+				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();
+				try {
+					bb.position(bb.position() + (high - low + 1) * 4);
+				} catch (Exception e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+				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<TypeRef>();
+
+		TypeRef tr = analyzer.getTypeRef(pool[type_index].toString());
+		annotations.add(tr);
+
+		if (policy == RetentionPolicy.RUNTIME) {
+			descriptors.add(Integer.valueOf(type_index));
+			hasRuntimeAnnotations = true;
+		} else {
+			hasClassAnnotations = true;
+		}
+		TypeRef name = analyzer.getTypeRef((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(Integer.valueOf(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(Integer.valueOf(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 packageRef
+	 *            A '.' delimited package name
+	 */
+	void referTo(TypeRef typeRef) {
+		if (xref != null)
+			xref.add(typeRef);
+		if (typeRef.isPrimitive())
+			return;
+
+		PackageRef packageRef = typeRef.getPackageRef();
+		if (packageRef.isPrimitivePackage())
+			return;
+
+		imports.add(packageRef);
+	}
+
+	/**
+	 * 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 ...
+		int rover = 0;
+		if (descriptor.charAt(0) == '<') {
+			rover = parseFormalTypeParameters(descriptor, rover);
+		}
+
+		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) {
+		int r = rover;
+		while (r < descriptor.length() && descriptor.charAt(r) != delimiter) {
+			r = parseReference(descriptor, r);
+		}
+		return r;
+	}
+
+	/**
+	 * 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) {
+		int r = rover;
+		char c = descriptor.charAt(r);
+		while (c == '[')
+			c = descriptor.charAt(++r);
+
+		if (c == '<') {
+			r = parseReferences(descriptor, r + 1, '>');
+		} else if (c == 'T') {
+			// Type variable name
+			r++;
+			while (descriptor.charAt(r) != ';')
+				r++;
+		} else if (c == 'L') {
+			StringBuilder sb = new StringBuilder();
+			r++;
+			while ((c = descriptor.charAt(r)) != ';') {
+				if (c == '<') {
+					r = parseReferences(descriptor, r + 1, '>');
+				} else
+					sb.append(c);
+				r++;
+			}
+			TypeRef ref = analyzer.getTypeRef(sb.toString());
+			if (cd != null)
+				cd.addReference(ref);
+
+			referTo(ref);
+		} else {
+			if ("+-*BCDFIJSZV".indexOf(c) < 0)
+				;// System.err.println("Should not skip: " + c);
+		}
+
+		// this skips a lot of characters
+		// [, *, +, -, B, etc.
+
+		return r + 1;
+	}
+
+	/**
+	 * FormalTypeParameters
+	 * 
+	 * @param descriptor
+	 * @param index
+	 * @return
+	 */
+	private int parseFormalTypeParameters(String descriptor, int index) {
+		index++;
+		while (descriptor.charAt(index) != '>') {
+			// Skip IDENTIFIER
+			index = descriptor.indexOf(':', index) + 1;
+			if (index == 0)
+				throw new IllegalArgumentException("Expected IDENTIFIER: " + descriptor);
+
+			// ClassBound? InterfaceBounds
+
+			char c = descriptor.charAt(index);
+
+			// Class Bound?
+			if (c == 'L' || c == 'T') {
+				index = parseReference(descriptor, index); // class reference
+				c = descriptor.charAt(index);
+			}
+
+			// Interface Bounds
+			while (c == ':') {
+				index++;
+				index = parseReference(descriptor, index);
+				c = descriptor.charAt(index);
+			} // for each interface
+
+		} // for each formal parameter
+		return index + 1; // skip >
+	}
+
+	public Set<PackageRef> getReferred() {
+		return imports;
+	}
+
+	public String getAbsolutePath() {
+		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().getDottedOnly()))
+				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].getDottedOnly()))
+					return !instr.isNegated();
+			}
+			break;
+
+		case EXTENDS:
+			if (zuper == null)
+				return false;
+
+			if (instr.matches(zuper.getDottedOnly()))
+				return !instr.isNegated();
+			break;
+
+		case PUBLIC:
+			return Modifier.isPublic(accessx);
+
+		case CONCRETE:
+			return !Modifier.isAbstract(accessx);
+
+		case ANNOTATED:
+			if (annotations == null)
+				return false;
+
+			for (TypeRef annotation : annotations) {
+				if (instr.matches(annotation.getFQN()))
+					return !instr.isNegated();
+			}
+
+			return false;
+
+		case RUNTIMEANNOTATIONS:
+			return hasClassAnnotations;
+		case CLASSANNOTATIONS:
+			return hasClassAnnotations;
+
+		case ABSTRACT:
+			return Modifier.isAbstract(accessx);
+
+		case IMPORTS:
+			for (PackageRef imp : imports) {
+				if (instr.matches(imp.getFQN()))
+					return !instr.isNegated();
+			}
+		}
+
+		if (zuper == null)
+			return false;
+
+		Clazz clazz = analyzer.findClass(zuper);
+		if (clazz == null)
+			return false;
+
+		return clazz.is(query, instr, analyzer);
+	}
+
+	public String toString() {
+		return className.getFQN();
+	}
+
+	/**
+	 * Called when crawling the byte code and a method reference is found
+	 * 
+	 */
+	void getMethodDef(int access, int methodRefPoolIndex) {
+		if ( methodRefPoolIndex == 0)
+			return;
+		
+		Object o = pool[methodRefPoolIndex];
+		if (o != null && o instanceof Assoc) {
+			Assoc assoc = (Assoc) o;
+			if (assoc.tag == 10) {
+				int string_index = intPool[assoc.a];
+				TypeRef className = analyzer.getTypeRef((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];
+					cd.referenceMethod(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 boolean isPublic() {
+		return Modifier.isPublic(accessx);
+	}
+
+	public boolean isProtected() {
+		return Modifier.isProtected(accessx);
+	}
+
+	public boolean isEnum() {
+		return zuper != null && zuper.getBinary().equals("java/lang/Enum");
+	}
+
+	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 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();
+	}
+
+	public boolean isInterface() {
+		return Modifier.isInterface(accessx);
+	}
+
+	public boolean isAbstract() {
+		return Modifier.isAbstract(accessx);
+	}
+
+	public int getAccess() {
+		if (innerAccess == -1)
+			return accessx;
+		else
+			return innerAccess;
+	}
+
+	public TypeRef getClassName() {
+		return className;
+	}
+
+	/**
+	 * To provide an enclosing instance
+	 * 
+	 * @param access
+	 * @param name
+	 * @param descriptor
+	 * @return
+	 */
+	public MethodDef getMethodDef(int access, String name, String descriptor) {
+		return new MethodDef(access, name, descriptor);
+	}
+
+	public TypeRef getSuper() {
+		return zuper;
+	}
+
+	public String getFQN() {
+		return className.getFQN();
+	}
+
+	public TypeRef[] getInterfaces() {
+		return interfaces;
+	}
+
+	public void setInnerAccess(int access) {
+		innerAccess = access;
+	}
+
+	public boolean isFinal() {
+		return Modifier.isFinal(accessx);
+	}
+
+	public void setDeprecated(boolean b) {
+		deprecated = b;
+	}
+
+	public boolean isDeprecated() {
+		return deprecated;
+	}
+
+	public boolean isAnnotation() {
+		return (accessx & ACC_ANNOTATION) != 0;
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/CombinedResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/CombinedResource.java
new file mode 100644
index 0000000..e8566db
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/CombinedResource.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.*;
+
+public class CombinedResource extends WriteResource {
+	final List<Resource> resources = new ArrayList<Resource>();
+	long lastModified = 0;
+	
+	@Override
+	public void write(final OutputStream out) throws IOException, Exception {
+		OutputStream unclosable = new FilterOutputStream(out) {
+			public void close() {
+				// Ignore
+			}
+		};
+		for ( Resource r : resources ) {
+			r.write(unclosable);
+			unclosable.flush();
+		}
+	}
+
+	@Override
+	public long lastModified() {
+		return lastModified;
+	}
+
+	public void addResource(Resource r) {
+		lastModified = Math.max(lastModified, r.lastModified());
+		resources.add(r);
+	}
+
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/CommandResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/CommandResource.java
new file mode 100644
index 0000000..c9e3c8a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/CommandResource.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) OSGi Alliance (2012). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package aQute.lib.osgi;
+
+import java.io.*;
+
+import aQute.libg.command.*;
+
+public class CommandResource extends WriteResource {
+	final long lastModified;
+	final Builder domain;
+	final String command;
+	
+	public CommandResource(String command, Builder domain, long lastModified) {
+		this.lastModified = lastModified;
+		this.domain = domain;
+		this.command = command;
+	}
+
+	@Override
+	public void write(OutputStream out) throws IOException, Exception {
+		StringBuilder errors = new StringBuilder();
+		StringBuilder stdout = new StringBuilder();
+		try {
+			domain.trace("executing command %s", command);
+			Command cmd = new Command("sh -l");
+			cmd.inherit();
+			String oldpath = cmd.var("PATH");
+			
+			String path = domain.getProperty("-PATH");
+			if (path != null) {
+				path = path.replaceAll("\\s*,\\s*",File.pathSeparator);
+				path = path.replaceAll("\\$\\{@\\}", oldpath);
+				cmd.var("PATH", path);
+				domain.trace("PATH: %s", path);
+			}
+			OutputStreamWriter osw = new OutputStreamWriter(out);
+			int result = cmd.execute(command,stdout, errors);
+			osw.append(stdout);
+			osw.flush();
+			if ( result != 0) {
+				domain.error("executing command failed %s %s", command, stdout + "\n" + errors);
+			}
+		} catch( Exception e) {
+			domain.error("executing command failed %s %s", command, e.getMessage());
+		}
+	}
+
+	@Override
+	public long lastModified() {
+		return lastModified;
+	}
+
+}
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..b196a1c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Constants.java
@@ -0,0 +1,300 @@
+package aQute.lib.osgi;
+
+import java.nio.charset.*;
+import java.util.*;
+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								PROVIDE_CAPABILITY							= "Provide-Capability";
+	String								REQUIRE_BUNDLE								= "Require-Bundle";
+	String								REQUIRE_CAPABILITY							= "Require-Capability";
+	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, REQUIRE_CAPABILITY, PROVIDE_CAPABILITY															};
+
+	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								DIGESTS									= "-digests";
+	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								NAMESECTION									= "-namesection";
+	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								PLUGINPATH									= "-pluginpath";
+	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								OUTPUT										= "-output";
+
+	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, NAMESECTION, DIGESTS										};
+
+	// 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, REQUIRE_CAPABILITY, PROVIDE_CAPABILITY											};
+
+	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";
+	String								PROVIDER_TYPE_DIRECTIVE						= "x-provider-type:";
+
+	/**
+	 * Component constants
+	 */
+	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));
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Descriptors.java b/bundleplugin/src/main/java/aQute/lib/osgi/Descriptors.java
new file mode 100644
index 0000000..366ca57
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Descriptors.java
@@ -0,0 +1,548 @@
+package aQute.lib.osgi;
+
+import java.util.*;
+
+import aQute.libg.generics.*;
+
+public class Descriptors {
+	Map<String, TypeRef>	typeRefCache	= Create.map();
+	Map<String, Descriptor>	descriptorCache	= Create.map();
+	Map<String, PackageRef>	packageCache	= Create.map();
+
+	// MUST BE BEFORE PRIMITIVES, THEY USE THE DEFAULT PACKAGE!!
+	final static PackageRef	DEFAULT_PACKAGE	= new PackageRef();
+	final static PackageRef	PRIMITIVE_PACKAGE	= new PackageRef();
+	
+	final static TypeRef	VOID			= new ConcreteRef("V", "void", PRIMITIVE_PACKAGE);
+	final static TypeRef	BOOLEAN			= new ConcreteRef("Z", "boolean", PRIMITIVE_PACKAGE);
+	final static TypeRef	BYTE			= new ConcreteRef("B", "byte", PRIMITIVE_PACKAGE);
+	final static TypeRef	CHAR			= new ConcreteRef("C", "char", PRIMITIVE_PACKAGE);
+	final static TypeRef	SHORT			= new ConcreteRef("S", "short", PRIMITIVE_PACKAGE);
+	final static TypeRef	INTEGER			= new ConcreteRef("I", "int", PRIMITIVE_PACKAGE);
+	final static TypeRef	LONG			= new ConcreteRef("J", "long", PRIMITIVE_PACKAGE);
+	final static TypeRef	DOUBLE			= new ConcreteRef("D", "double", PRIMITIVE_PACKAGE);
+	final static TypeRef	FLOAT			= new ConcreteRef("F", "float", PRIMITIVE_PACKAGE);
+
+
+	{
+		packageCache.put("", DEFAULT_PACKAGE);
+	}
+
+	public interface TypeRef extends Comparable<TypeRef>{
+		String getBinary();
+
+		String getFQN();
+
+		String getPath();
+
+		boolean isPrimitive();
+
+		TypeRef getComponentTypeRef();
+
+		TypeRef getClassRef();
+
+		PackageRef getPackageRef();
+
+		String getShortName();
+
+		boolean isJava();
+
+		boolean isObject();
+
+		String getSourcePath();
+
+		String getDottedOnly();
+
+	}
+
+	public static class PackageRef implements Comparable<PackageRef>{
+		final String	binaryName;
+		final String	fqn;
+		final boolean	java;
+
+		private PackageRef(String binaryName) {
+			this.binaryName = fqnToBinary(binaryName);
+			this.fqn = binaryToFQN(binaryName);
+			this.java = this.fqn.startsWith("java.") ; // && !this.fqn.equals("java.sql)"
+			
+			// For some reason I excluded java.sql but the classloader will
+			// delegate anyway. So lost the understanding why I did it??
+		}
+
+		private PackageRef() {
+			this.binaryName = "";
+			this.fqn=".";
+			this.java = false;
+		}
+
+		public PackageRef getDuplicate() {
+			return new PackageRef(binaryName+Constants.DUPLICATE_MARKER);
+		}
+		public String getFQN() {
+			return fqn;
+		}
+
+		public String getBinary() {
+			return binaryName;
+		}
+
+		public String getPath() {
+			return binaryName;
+		}
+
+		public boolean isJava() {
+			return java;
+		}
+
+		public String toString() {
+			return fqn;
+		}
+		
+		boolean isDefaultPackage() {
+			return this.fqn.equals(".");
+		}
+
+		boolean isPrimitivePackage() {
+			return this == PRIMITIVE_PACKAGE;
+		}
+
+		public int compareTo(PackageRef other) {
+			return fqn.compareTo(other.fqn);
+		}
+		
+		public boolean equals(Object o) {
+			assert o instanceof PackageRef;
+			return o == this;
+		}
+		
+		public int hashCode() {
+			return super.hashCode();
+		}
+		
+		/**
+		 * Decide if the package is a metadata package.
+		 * 
+		 * @param pack
+		 * @return
+		 */
+		public boolean isMetaData() {
+			if (isDefaultPackage())
+				return true;
+			
+			for (int i = 0; i < Constants.METAPACKAGES.length; i++) {
+				if (fqn.startsWith(Constants.METAPACKAGES[i]))
+					return true;
+			}
+			return false;
+		}
+
+	}
+
+	// We "intern" the
+	private static class ConcreteRef implements TypeRef {
+		final String		binaryName;
+		final String		fqn;
+		final boolean		primitive;
+		final PackageRef	packageRef;
+
+		ConcreteRef(PackageRef packageRef, String binaryName) {
+			if ( packageRef.getFQN().length() < 2 )
+				System.err.println("in default pack? " + binaryName);
+			this.binaryName = binaryName;
+			this.fqn = binaryToFQN(binaryName);
+			this.primitive = false;
+			this.packageRef = packageRef;
+		}
+
+		ConcreteRef(String binaryName, String fqn, PackageRef pref) {
+			this.binaryName = binaryName;
+			this.fqn = fqn;
+			this.primitive = true;
+			this.packageRef = pref;
+		}
+
+		public String getBinary() {
+			return binaryName;
+		}
+
+		public String getPath() {
+			return binaryName + ".class";
+		}
+
+		public String getSourcePath() {
+			return binaryName + ".java";
+		}
+
+		public String getFQN() {
+			return fqn;
+		}
+
+		public String getDottedOnly() {
+			return fqn.replace('$', '.');
+		}
+
+		public boolean isPrimitive() {
+			return primitive;
+		}
+
+		public TypeRef getComponentTypeRef() {
+			return null;
+		}
+
+		public TypeRef getClassRef() {
+			return this;
+		}
+
+		public PackageRef getPackageRef() {
+			return packageRef;
+		}
+
+		public String getShortName() {
+			int n = binaryName.lastIndexOf('/');
+			return binaryName.substring(n + 1);
+		}
+
+		public boolean isJava() {
+			return packageRef.isJava();
+		}
+
+		public String toString() {
+			return fqn;
+		}
+
+		public boolean isObject() {
+			return fqn.equals("java.lang.Object");
+		}
+
+		public boolean equals(Object other) {
+			assert other instanceof TypeRef;
+			return this == other;
+		}
+
+		public int compareTo(TypeRef other) {
+			if ( this == other)
+				return 0;
+			return fqn.compareTo(other.getFQN());
+		}
+		
+	}
+
+	private static class ArrayRef implements TypeRef {
+		final TypeRef	component;
+
+		ArrayRef(TypeRef component) {
+			this.component = component;
+		}
+
+		public String getBinary() {
+			return "[" + component.getBinary();
+		}
+
+		public String getFQN() {
+			return component.getFQN() + "[]";
+		}
+
+		public String getPath() {
+			return component.getPath();
+		}
+
+		public String getSourcePath() {
+			return component.getSourcePath();
+		}
+		
+		public boolean isPrimitive() {
+			return false;
+		}
+
+		public TypeRef getComponentTypeRef() {
+			return component;
+		}
+
+		public TypeRef getClassRef() {
+			return component.getClassRef();
+		}
+
+		public boolean equals(Object other) {
+			if (other == null || other.getClass() != getClass())
+				return false;
+
+			return component.equals(((ArrayRef) other).component);
+		}
+
+		public PackageRef getPackageRef() {
+			return component.getPackageRef();
+		}
+
+		public String getShortName() {
+			return component.getShortName() + "[]";
+		}
+
+		public boolean isJava() {
+			return component.isJava();
+		}
+
+		public String toString() {
+			return component.toString() + "[]";
+		}
+
+		public boolean isObject() {
+			return false;
+		}
+
+		public String getDottedOnly() {
+			return component.getDottedOnly();
+		}
+
+		public int compareTo(TypeRef other) {
+			if ( this == other)
+				return 0;
+			
+			return getFQN().compareTo(other.getFQN());
+		}
+
+	}
+
+	public TypeRef getTypeRef(String binaryClassName) {		
+		assert !binaryClassName.endsWith(".class");
+		
+		TypeRef ref = typeRefCache.get(binaryClassName);
+		if (ref != null)
+			return ref;
+
+		if (binaryClassName.startsWith("[")) {
+			ref = getTypeRef(binaryClassName.substring(1));
+			ref = new ArrayRef(ref);
+		} else {
+			if (binaryClassName.length() >= 1) {
+				switch (binaryClassName.charAt(0)) {
+				case 'V':
+					return VOID;
+				case 'B':
+					return BYTE;
+				case 'C':
+					return CHAR;
+				case 'I':
+					return INTEGER;
+				case 'S':
+					return SHORT;
+				case 'D':
+					return DOUBLE;
+				case 'F':
+					return FLOAT;
+				case 'J':
+					return LONG;
+				case 'Z':
+					return BOOLEAN;
+				case 'L':
+					binaryClassName = binaryClassName.substring(1, binaryClassName.length() - 1);
+					break;
+				}
+				// falls trough for other 1 letter class names
+			}
+			ref = typeRefCache.get(binaryClassName);
+			if ( ref != null)
+				return ref;
+			
+			PackageRef pref;
+			int n = binaryClassName.lastIndexOf('/');
+			if (n < 0)
+				pref = DEFAULT_PACKAGE;
+			else
+				pref = getPackageRef(binaryClassName.substring(0, n));
+
+			ref = new ConcreteRef(pref, binaryClassName);
+		}
+		
+		typeRefCache.put(binaryClassName, ref);
+		return ref;
+	}
+
+	public PackageRef getPackageRef(String binaryPackName) {
+		if (binaryPackName.indexOf('.') >= 0 ) {
+			binaryPackName = binaryPackName.replace('.', '/');
+		}
+		PackageRef ref = packageCache.get(binaryPackName);
+		if (ref != null)
+			return ref;
+
+		ref = new PackageRef(binaryPackName);
+		packageCache.put(binaryPackName, ref);
+		return ref;
+	}
+
+	public Descriptor getDescriptor(String descriptor) {
+		Descriptor d = descriptorCache.get(descriptor);
+		if (d != null)
+			return d;
+		d = new Descriptor(descriptor);
+		descriptorCache.put(descriptor, d);
+		return d;
+	}
+
+	public class Descriptor {
+		final TypeRef	type;
+		final TypeRef[]	prototype;
+		final String	descriptor;
+
+		private Descriptor(String descriptor) {
+			this.descriptor = descriptor;
+			int index = 0;
+			List<TypeRef> types = Create.list();
+			if (descriptor.charAt(index) == '(') {
+				index++;
+				while (descriptor.charAt(index) != ')') {
+					index = parse(types, descriptor, index);
+				}
+				index++; // skip )
+				prototype = types.toArray(new TypeRef[types.size()]);
+				types.clear();
+			} else
+				prototype = null;
+
+			index = parse(types, descriptor, index);
+			type = types.get(0);
+		}
+
+		int parse(List<TypeRef> types, String descriptor, int index) {
+			char c;
+			StringBuilder sb = new StringBuilder();
+			while ((c = descriptor.charAt(index++)) == '[') {
+				sb.append('[');
+			}
+
+			switch (c) {
+			case 'L':
+				while ((c = descriptor.charAt(index++)) != ';') {
+					// TODO
+					sb.append(c);
+				}
+				break;
+
+			case 'V':
+			case 'B':
+			case 'C':
+			case 'I':
+			case 'S':
+			case 'D':
+			case 'F':
+			case 'J':
+			case 'Z':
+				sb.append(c);
+				break;
+
+			default:
+				throw new IllegalArgumentException("Invalid type in descriptor: " + c + " from "
+						+ descriptor + "[" + index + "]");
+			}
+			types.add(getTypeRef(sb.toString()));
+			return index;
+		}
+
+		public TypeRef getType() {
+			return type;
+		}
+
+		public TypeRef[] getPrototype() {
+			return prototype;
+		}
+
+		public boolean equals(Object other) {
+			if (other == null || other.getClass() != getClass())
+				return false;
+
+			return Arrays.equals(prototype, ((Descriptor) other).prototype)
+					&& type == ((Descriptor) other).type;
+		}
+
+		public int hashCode() {
+			return prototype == null ? type.hashCode() : type.hashCode()
+					^ Arrays.hashCode(prototype);
+		}
+
+		public String toString() {
+			return descriptor;
+		}
+	}
+
+	/**
+	 * Return the short name of a FQN
+	 */
+
+	public static String getShortName(String fqn) {
+		assert fqn.indexOf('/') < 0;
+		
+		int n = fqn.lastIndexOf('.');
+		if (n >= 0) {
+			return fqn.substring(n + 1);
+		}
+		return fqn;
+	}
+
+	public static String binaryToFQN(String binary) {
+		StringBuilder sb = new StringBuilder();
+		for ( int i=0, l=binary.length(); i<l; i++) {
+			char c = binary.charAt(i);
+			
+			if ( c == '/')
+				sb.append('.');
+			else
+				sb.append(c);
+		}
+		String result = sb.toString();
+		assert result.length() > 0;
+		return result;
+	}
+
+	public static String fqnToBinary(String binary) {
+		return binary.replace('.', '/');
+	}
+
+	public static String getPackage(String binaryNameOrFqn) {
+		int n = binaryNameOrFqn.lastIndexOf('/');
+		if (n >= 0)
+			return binaryNameOrFqn.substring(0, n).replace('/', '.');
+
+		n = binaryNameOrFqn.lastIndexOf(".");
+		if (n >= 0)
+			return binaryNameOrFqn.substring(0, n);
+
+		return ".";
+	}
+
+	public static String fqnToPath(String s) {
+		return fqnToBinary(s) + ".class";
+	}
+
+	public TypeRef getTypeRefFromFQN(String fqn) {
+		if ( fqn.equals("boolean"))
+			return BOOLEAN;
+		
+		if ( fqn.equals("byte"))
+			return BOOLEAN;
+		
+		if ( fqn.equals("char"))
+			return CHAR;
+		
+		if ( fqn.equals("short"))
+			return SHORT;
+		
+		if ( fqn.equals("int"))
+			return INTEGER;
+		
+		if ( fqn.equals("long"))
+			return LONG;
+		
+		if ( fqn.equals("float"))
+			return FLOAT;
+		
+		if ( fqn.equals("double"))
+			return DOUBLE;
+		
+		return getTypeRef(fqnToBinary(fqn));
+	}
+
+	public TypeRef getTypeRefFromPath(String path) {
+		assert path.endsWith(".class");
+		return getTypeRef(path.substring(0,path.length()-6));
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Domain.java b/bundleplugin/src/main/java/aQute/lib/osgi/Domain.java
new file mode 100644
index 0000000..b6ef379
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Domain.java
@@ -0,0 +1,256 @@
+package aQute.lib.osgi;
+
+import static aQute.lib.osgi.Constants.*;
+
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.libg.header.*;
+import aQute.libg.reporter.*;
+import aQute.libg.version.*;
+
+/**
+ * This class abstracts domains that have properties holding OSGi meta data. It
+ * provides access to the keys, the set method and the get method. It then
+ * provides convenient methods to access these properties via semantic methods.
+ * 
+ */
+public abstract class Domain implements Iterable<String> {
+
+	public abstract String get(String key);
+
+	public String get(String key, String deflt) {
+		String result = get(key);
+		if (result != null)
+			return result;
+		return deflt;
+	}
+
+	public abstract void set(String key, String value);
+
+	public abstract Iterator<String> iterator();
+
+	public static Domain domain(final Manifest manifest) {
+		Attributes attrs = manifest.getMainAttributes();
+		return domain(attrs);
+	}
+
+	public static Domain domain(final Attributes attrs) {
+		return new Domain() {
+
+			@Override public String get(String key) {
+				return attrs.getValue(key);
+			}
+
+			@Override public void set(String key, String value) {
+				attrs.putValue(key, value);
+			}
+
+			@Override public Iterator<String> iterator() {
+				final Iterator<Object> it = attrs.keySet().iterator();
+
+				return new Iterator<String>() {
+
+					public boolean hasNext() {
+						return it.hasNext();
+					}
+
+					public String next() {
+						return it.next().toString();
+					}
+
+					public void remove() {
+						it.remove();
+					}
+				};
+			}
+		};
+	}
+
+	public static Domain domain(final Processor processor) {
+		return new Domain() {
+
+			@Override public String get(String key) {
+				return processor.getProperty(key);
+			}
+
+			@Override public String get(String key, String deflt) {
+				return processor.getProperty(key, deflt);
+			}
+
+			@Override public void set(String key, String value) {
+				processor.setProperty(key, value);
+			}
+
+			@Override public Iterator<String> iterator() {
+				final Iterator<String> it = processor.getPropertyKeys(true).iterator();
+
+				return new Iterator<String>() {
+					String	current;
+
+					public boolean hasNext() {
+						return it.hasNext();
+					}
+
+					public String next() {
+						return current = it.next().toString();
+					}
+
+					public void remove() {
+						processor.getProperties().remove(current);
+					}
+				};
+			}
+		};
+	}
+
+	public static Domain domain(final Map<String, String> map) {
+		return new Domain() {
+
+			@Override public String get(String key) {
+				return map.get(key);
+			}
+
+			@Override public void set(String key, String value) {
+				map.put(key, value);
+			}
+
+			@Override public Iterator<String> iterator() {
+				return map.keySet().iterator();
+			}
+		};
+	}
+
+	public Parameters getParameters(String key, Reporter reporter) {
+		return new Parameters(get(key), reporter);
+	}
+
+	public Parameters getParameters(String key) {
+		return new Parameters(get(key));
+	}
+
+	public Parameters getParameters(String key, String deflt) {
+		return new Parameters(get(key, deflt));
+	}
+
+	public Parameters getParameters(String key, String deflt, Reporter reporter) {
+		return new Parameters(get(key, deflt), reporter);
+	}
+
+	public Parameters getImportPackage() {
+		return getParameters(IMPORT_PACKAGE);
+	}
+
+	public Parameters getExportPackage() {
+		return getParameters(EXPORT_PACKAGE);
+	}
+
+	public Parameters getBundleClassPath() {
+		return getParameters(BUNDLE_CLASSPATH);
+	}
+
+	public Parameters getPrivatePackage() {
+		return getParameters(PRIVATE_PACKAGE);
+	}
+
+	public Parameters getIncludeResource() {
+		Parameters ic = getParameters(INCLUDE_RESOURCE);
+		ic.putAll( getParameters(INCLUDERESOURCE));
+		return ic;
+	}
+
+	public Parameters getDynamicImportPackage() {
+		return getParameters(DYNAMICIMPORT_PACKAGE);
+	}
+
+	public Parameters getExportContents() {
+		return getParameters(EXPORT_CONTENTS);
+	}
+
+	public String getBundleActivator() {
+		return get(BUNDLE_ACTIVATOR);
+	}
+
+	public void setPrivatePackage(String s) {
+		if (s != null)
+			set(PRIVATE_PACKAGE, s);
+	}
+
+	public void setIncludeResource(String s) {
+		if (s != null)
+			set(INCLUDE_RESOURCE, s);
+	}
+
+	public void setBundleActivator(String s) {
+		if (s != null)
+			set(BUNDLE_ACTIVATOR, s);
+	}
+
+	public void setExportPackage(String s) {
+		if (s != null)
+			set(EXPORT_PACKAGE, s);
+	}
+
+	public void setImportPackage(String s) {
+		if (s != null)
+			set(IMPORT_PACKAGE, s);
+	}
+
+	public void setBundleClasspath(String s) {
+		if (s != null)
+			set(BUNDLE_CLASSPATH, s);
+	}
+
+	public Parameters getBundleClasspath() {
+		return getParameters(BUNDLE_CLASSPATH);
+	}
+
+	public void setBundleRequiredExecutionEnvironment(String s) {
+		if (s != null)
+			set(BUNDLE_REQUIREDEXECUTIONENVIRONMENT, s);
+	}
+
+	public Parameters getBundleRequiredExecutionEnvironment() {
+		return getParameters(BUNDLE_REQUIREDEXECUTIONENVIRONMENT);
+	}
+
+	public void setSources(boolean b) {
+		if (b)
+			set(SOURCES, "true");
+		else
+			set(SOURCES, "false");
+	}
+
+	public boolean isSources() {
+		return Processor.isTrue(get(SOURCES));
+	}
+
+	public String getBundleSymbolicName() {
+		return get(BUNDLE_SYMBOLICNAME);
+	}
+
+	public void setBundleSymbolicName(String s) {
+		set(BUNDLE_SYMBOLICNAME, s);
+	}
+	
+	public String getBundleVersion() {
+		return get(BUNDLE_VERSION);
+	}
+
+	public void setBundleVersion(String version) {
+		Version v = new Version(version);
+		set(BUNDLE_VERSION,v.toString());
+	}
+
+	public void setBundleVersion(Version version) {
+		set(BUNDLE_VERSION,version.toString());
+	}
+
+	public void setFailOk(boolean b) {
+		set(FAIL_OK, b+"");
+	}
+	
+	public boolean isFailOk() {
+		return Processor.isTrue(get(FAIL_OK));
+	}
+}
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 100755
index 0000000..ebc93ee
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/EmbeddedResource.java
@@ -0,0 +1,98 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.zip.*;
+
+import aQute.lib.io.*;
+
+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();
+		}
+		IO.drain(in);
+		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();
+		try {
+			build(sub, in, resource.lastModified());
+		} catch( Exception e ) {
+			e.printStackTrace();
+		}
+		finally {
+			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 100755
index 0000000..b849878
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/FileResource.java
@@ -0,0 +1,85 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.regex.*;
+
+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;
+		jar.updateModified(directory.lastModified(), "Dir change");
+		
+		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 100755
index 0000000..4b81607
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java
@@ -0,0 +1,185 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.regex.*;
+
+public class Instruction {
+	
+	public static class Filter implements FileFilter {
+
+		private Instruction instruction;
+		private boolean recursive;
+		private Pattern doNotCopy;
+		
+		public Filter (Instruction instruction, boolean recursive, Pattern doNotCopy) {
+			this.instruction = instruction;
+			this.recursive = recursive;
+			this.doNotCopy = doNotCopy;
+		}
+		public Filter (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());
+		}
+	}
+
+	transient Pattern	pattern;
+	transient boolean	optional;
+
+	final String		input;
+	final String		match;
+	final boolean		negated;
+	final boolean		duplicate;
+	final boolean		literal;
+	final boolean		any;
+	
+	public Instruction(String input) {
+		this.input = input;
+			
+		String s = Processor.removeDuplicateMarker(input);
+		duplicate = !s.equals(input);
+		
+		if (s.startsWith("!")) {
+			negated = true;
+			s = s.substring(1);
+		} else
+			negated = false;
+
+		if ( input.equals("*")) {
+			any = true;
+			literal= false;
+			match= null;
+			return;
+		}
+		
+		any = false;
+		if (s.startsWith("=")) {
+			match = s.substring(1);
+			literal = true;
+		} else  {
+			boolean wildcards = false;
+			
+			StringBuilder sb = new StringBuilder();
+			loop: for (int c = 0; c < s.length(); c++) {
+				switch (s.charAt(c)) {
+				case '.':
+					// If we end in a wildcard .* then we need to
+					// also include the last full package. I.e.
+					// com.foo.* includes com.foo (unlike OSGi)
+					if ( c == s.length()-2 && '*'==s.charAt(c+1)) {
+						sb.append("(\\..*)?");
+						wildcards=true;
+						break loop;
+					}
+					else
+						sb.append("\\.");
+						
+					break;
+				case '*':
+					sb.append(".*");
+					wildcards=true;
+					break;
+				case '$':
+					sb.append("\\$");
+					break;
+				case '?':
+					sb.append(".?");
+					wildcards=true;
+					break;
+				case '|':
+					sb.append('|');
+					wildcards=true;
+					break;
+				default:
+					sb.append(s.charAt(c));
+					break;
+				}
+			}
+			
+			if ( !wildcards ) {
+				literal = true;
+				match = s;
+			} else {
+				literal = false;
+				match = sb.toString();
+			}
+		}
+
+		
+	}
+
+	public boolean matches(String value) {
+		if (any)
+			return true;
+		
+		if (literal )
+			return match.equals(value);
+		else
+			return getMatcher(value).matches();
+	}
+
+	public boolean isNegated() {
+		return negated;
+	}
+
+	public String getPattern() {
+		return match;
+	}
+
+	public String getInput() {
+		return input;
+	}
+
+	public String toString() {
+		return input;
+	}
+
+	public Matcher getMatcher(String value) {
+		if (pattern == null) {
+			pattern = Pattern.compile(match);
+		}
+		return pattern.matcher(value);
+	}
+
+	public void setOptional() {
+		optional = true;
+	}
+
+	public boolean isOptional() {
+		return optional;
+	}
+
+
+	public boolean isLiteral() {
+		return literal;
+	}
+
+	public String getLiteral() {
+		assert literal;
+		return match;
+	}
+
+	public boolean isDuplicate() {
+		return duplicate;
+	}
+
+	public boolean isAny() {
+		return any;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Instructions.java b/bundleplugin/src/main/java/aQute/lib/osgi/Instructions.java
new file mode 100644
index 0000000..e74150c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Instructions.java
@@ -0,0 +1,219 @@
+package aQute.lib.osgi;
+
+import java.util.*;
+
+import aQute.libg.header.*;
+
+public class Instructions implements Map<Instruction, Attrs> {
+	private LinkedHashMap<Instruction, Attrs>	map;
+	static Map<Instruction, Attrs>				EMPTY	= Collections.emptyMap();
+
+	public Instructions(Instructions other) {
+		if (other.map != null && !other.map.isEmpty()) {
+			map = new LinkedHashMap<Instruction, Attrs>(other.map);
+		}
+	}
+
+	public Instructions(Collection<String> other) {
+		if ( other != null)
+			for ( String s : other  ) {
+				put( new Instruction(s), null);
+			}
+	}
+
+	public Instructions() {
+	}
+
+	public Instructions(Parameters contained) {
+		append(contained);
+	}
+
+	public Instructions(String h) {
+		this(new Parameters(h));
+	}
+
+	public void clear() {
+		map.clear();
+	}
+
+	public boolean containsKey(Instruction name) {
+		if (map == null)
+			return false;
+
+		return map.containsKey(name);
+	}
+
+	@Deprecated public boolean containsKey(Object name) {
+		assert name instanceof Instruction;
+		if (map == null)
+			return false;
+
+		return map.containsKey((Instruction) name);
+	}
+
+	public boolean containsValue(Attrs value) {
+		if (map == null)
+			return false;
+
+		return map.containsValue(value);
+	}
+
+	@Deprecated public boolean containsValue(Object value) {
+		assert value instanceof Attrs;
+		if (map == null)
+			return false;
+
+		return map.containsValue((Attrs) value);
+	}
+
+	public Set<java.util.Map.Entry<Instruction, Attrs>> entrySet() {
+		if (map == null)
+			return EMPTY.entrySet();
+
+		return map.entrySet();
+	}
+
+	@Deprecated public Attrs get(Object key) {
+		assert key instanceof Instruction;
+		if (map == null)
+			return null;
+
+		return map.get((Instruction) key);
+	}
+
+	public Attrs get(Instruction key) {
+		if (map == null)
+			return null;
+
+		return map.get(key);
+	}
+
+	public boolean isEmpty() {
+		return map == null || map.isEmpty();
+	}
+
+	public Set<Instruction> keySet() {
+		if (map == null)
+			return EMPTY.keySet();
+
+		return map.keySet();
+	}
+
+	public Attrs put(Instruction key, Attrs value) {
+		if (map == null)
+			map = new LinkedHashMap<Instruction, Attrs>();
+
+		return map.put(key, value);
+	}
+
+	public void putAll(Map<? extends Instruction, ? extends Attrs> map) {
+		if (this.map == null)
+			if (map.isEmpty())
+				return;
+			else
+				this.map = new LinkedHashMap<Instruction, Attrs>();
+		this.map.putAll(map);
+	}
+
+	@Deprecated public Attrs remove(Object var0) {
+		assert var0 instanceof Instruction;
+		if (map == null)
+			return null;
+
+		return map.remove((Instruction) var0);
+	}
+
+	public Attrs remove(Instruction var0) {
+		if (map == null)
+			return null;
+		return map.remove(var0);
+	}
+
+	public int size() {
+		if (map == null)
+			return 0;
+		return map.size();
+	}
+
+	public Collection<Attrs> values() {
+		if (map == null)
+			return EMPTY.values();
+
+		return map.values();
+	}
+
+	public String toString() {
+		return map == null ? "{}" : map.toString();
+	}
+
+	public void append(Parameters other) {
+		for (Map.Entry<String, Attrs> e : other.entrySet()) {
+			put( new Instruction(e.getKey()), e.getValue());
+		}
+	}
+	public <T> Collection<T> select(Collection<T> set, boolean emptyIsAll) {
+		return select(set,null, emptyIsAll);
+	}
+	
+	public <T> Collection<T> select(Collection<T> set, Set<Instruction> unused, boolean emptyIsAll) {
+		List<T> input = new ArrayList<T>(set);
+		if ( emptyIsAll && isEmpty())
+			return input;
+		
+		List<T> result = new ArrayList<T>();
+
+		for (Instruction instruction : keySet()) {
+			boolean used = false;
+			for (Iterator<T> o = input.iterator(); o.hasNext();) {
+				T oo = o.next();
+				String s = oo.toString();
+				if (instruction.matches(s)) {
+					if (!instruction.isNegated())
+						result.add(oo);
+					o.remove();
+					used = true;
+				}
+			}
+			if ( !used && unused != null)
+				unused.add(instruction);
+		}
+		return result;
+	}
+
+
+	public <T> Collection<T> reject(Collection<T> set) {
+		List<T> input = new ArrayList<T>(set);
+		List<T> result = new ArrayList<T>();
+
+		for (Instruction instruction : keySet()) {
+			for (Iterator<T> o = input.iterator(); o.hasNext();) {
+				T oo = o.next();
+				String s = oo.toString();
+				if (instruction.matches(s)) {
+					if (instruction.isNegated())
+						result.add(oo);
+					o.remove();
+				} else
+					result.add(oo);
+					
+			}
+		}
+		return result;
+	}
+
+	public boolean matches(String value) {
+		if ( size() == 0)
+			return true;
+		
+		for ( Instruction i : keySet()) {
+			if ( i.matches(value)) {
+				if ( i.isNegated())
+					return false;		// we deny this one explicitly
+				else
+					return true;		// we allow it explicitly
+			}
+		}
+		return false;
+	}
+
+}
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 100755
index 0000000..497198b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
@@ -0,0 +1,783 @@
+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.lib.io.*;
+import aQute.libg.reporter.*;
+
+public class Jar implements Closeable {
+	public enum Compression {
+		DEFLATE, STORE
+	}
+
+	public static final Object[]				EMPTY_ARRAY	= new Jar[0];
+	final Map<String, Resource>					resources	= new TreeMap<String, Resource>();
+	final 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;
+	Compression									compression	= Compression.DEFLATE;
+	boolean										closed;
+
+	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) {
+		check();
+		return putResource(path, resource, true);
+	}
+
+	public boolean putResource(String path, Resource resource, boolean overwrite) {
+		check();
+		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) {
+		check();
+		if (resources == null)
+			return null;
+		return resources.get(path);
+	}
+
+	private String getDirectory(String path) {
+		check();
+		int n = path.lastIndexOf('/');
+		if (n < 0)
+			return "";
+
+		return path.substring(0, n);
+	}
+
+	public Map<String, Map<String, Resource>> getDirectories() {
+		check();
+		return directories;
+	}
+
+	public Map<String, Resource> getResources() {
+		check();
+		return resources;
+	}
+
+	public boolean addDirectory(Map<String, Resource> directory, boolean overwrite) {
+		check();
+		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, entry.getValue(), overwrite);
+			}
+		}
+		return duplicates;
+	}
+
+	public Manifest getManifest() throws Exception {
+		check();
+		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) {
+		check();
+		return resources.containsKey(path);
+	}
+
+	public void setManifest(Manifest manifest) {
+		check();
+		manifestFirst = true;
+		this.manifest = manifest;
+	}
+
+	public void setManifest(File file) throws IOException {
+		check();
+		FileInputStream fin = new FileInputStream(file);
+		try {
+			Manifest m = new Manifest(fin);
+			setManifest(m);
+		} finally {
+			fin.close();
+		}
+	}
+
+	public void write(File file) throws Exception {
+		check();
+		try {
+			OutputStream out = new FileOutputStream(file);
+			try {
+				write(out);
+			} finally {
+				IO.close(out);
+			}
+			return;
+
+		} catch (Exception t) {
+			file.delete();
+			throw t;
+		}
+	}
+
+	public void write(String file) throws Exception {
+		check();
+		write(new File(file));
+	}
+
+	public void write(OutputStream out) throws Exception {
+		check();
+		ZipOutputStream jout = nomanifest || doNotTouchManifest ? new ZipOutputStream(out)
+				: new JarOutputStream(out);
+
+		switch (compression) {
+		case STORE:
+			jout.setMethod(ZipOutputStream.DEFLATED);
+			break;
+
+		default:
+			// default is DEFLATED
+		}
+
+		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, entry.getKey(), entry.getValue());
+		}
+		jout.finish();
+	}
+
+	private void doManifest(Set<String> done, ZipOutputStream jout) throws Exception {
+		check();
+		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 {
+		check();
+		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);
+		}
+		out.flush();
+	}
+
+	/**
+	 * 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 + ": ");
+		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 {
+		int w = width;
+		for (int i = 0; i < bytes.length; i++) {
+			if (w >= 72) { // we need to add the \n\r!
+				out.write(CONTINUE);
+				w = 1;
+			}
+			out.write(bytes[i]);
+			w++;
+		}
+		return w;
+	}
+
+	/**
+	 * 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;
+
+		StringBuilder sb = new StringBuilder(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;
+		try {
+			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("UTF-8"));
+			jout.putNextEntry(ze);
+			resource.write(jout);
+			jout.closeEntry();
+		} catch (Exception e) {
+			throw new Exception("Problem writing resource " + path, e);
+		}
+	}
+
+	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) {
+		check();
+		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() {
+		this.closed = true;
+		if (zipFile != null)
+			try {
+				zipFile.close();
+			} catch (IOException e) {
+				// Ignore
+			}
+		resources.clear();
+		directories.clear();
+		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) {
+		check();
+		return directories.get(path) != null;
+	}
+
+	public List<String> getPackages() {
+		check();
+		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() {
+		check();
+		return source;
+	}
+
+	public boolean addAll(Jar src) {
+		check();
+		return addAll(src, null);
+	}
+
+	public boolean rename(String oldPath, String newPath) {
+		check();
+		Resource resource = remove(oldPath);
+		if (resource == null)
+			return false;
+
+		return putResource(newPath, resource);
+	}
+
+	public Resource remove(String path) {
+		check();
+		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 {
+		check();
+		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 {
+		check();
+		Manifest m = getManifest();
+		if (m == null)
+			return null;
+
+		String s = m.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
+		if (s == null)
+			return null;
+
+		Matcher matcher = BSN.matcher(s);
+		if (matcher.matches()) {
+			return matcher.group(1);
+		}
+		return null;
+	}
+
+	public String getVersion() throws Exception {
+		check();
+		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 {
+		check();
+		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();
+			IO.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();
+	}
+
+	/**
+	 * Answer if the manifest was the first entry
+	 */
+
+	public boolean isManifestFirst() {
+		return manifestFirst;
+	}
+
+	public void copy(Jar srce, String path, boolean overwrite) {
+		check();
+		addDirectory(srce.getDirectories().get(path), overwrite);
+	}
+
+	public void setCompression(Compression compression) {
+		this.compression = compression;
+	}
+
+	public Compression hasCompression() {
+		return this.compression;
+	}
+
+	void check() {
+		if (closed)
+			throw new RuntimeException("Already closed " + name);
+	}
+}
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 100755
index 0000000..0c0adcd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/JarResource.java
@@ -0,0 +1,34 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+
+public class JarResource extends WriteResource {
+	Jar		jar;
+	long	size	= -1;
+
+	public JarResource(Jar jar) {
+		this.jar = jar;
+	}
+
+	public long lastModified() {
+		return jar.lastModified();
+	}
+
+	public void write(OutputStream out) throws Exception {
+		try {
+			jar.write(out);
+		} catch (Exception e) {
+			e.printStackTrace();
+			throw e;
+		}
+	}
+
+	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 100755
index 0000000..4ddd625
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Macro.java
@@ -0,0 +1,1015 @@
+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.collections.*;
+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) {
+		StringBuilder sb = new StringBuilder();
+		process(line, 0, '\u0000', '\u0000', sb, link);
+		return sb.toString();
+	}
+
+	int process(CharSequence org, int index, char begin, char end, StringBuilder result, Link link) {
+		StringBuilder line = new StringBuilder(org);
+		int nesting = 1;
+
+		StringBuilder variable = new StringBuilder();
+		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;
+							}
+						}
+						else
+							if (c1 == '.' && index < line.length() && line.charAt(index) == '/') {
+								// Found the sequence ./
+								if (index == 1 || Character.isWhitespace(line.charAt(index - 2))) {
+									// make sure it is preceded by whitespace or starts at begin
+									index++;
+									variable.append(domain.getBase().getAbsolutePath());
+									variable.append('/');
+									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;
+
+				if (key.indexOf(';') < 0) {
+					Instruction ins = new Instruction(key);
+					if (!ins.isLiteral()) {
+						SortedList<String> sortedList = SortedList.fromIterator(domain.iterator());
+						StringBuilder sb = new StringBuilder();
+						String del = "";
+						for (String k : sortedList) {
+							if (ins.matches(k)) {
+								String v = replace(k, new Link(source, link, key));
+								if (v != null) {
+									sb.append(del);
+									del = ",";
+									sb.append(v);
+								}
+							}
+						}
+						return sb.toString();
+					}
+				}
+				while (value == null && source != null) {
+					value = source.getProperties().getProperty(key);
+					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 && !key.equals("@"))
+					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.err.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.equalsIgnoreCase("false"))
+			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 final 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*");
+		StringBuilder sb = new StringBuilder();
+		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 = Boolean.valueOf(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 = "";
+			StringBuilder sb = new StringBuilder();
+			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 = "";
+			StringBuilder sb = new StringBuilder();
+			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);
+
+		List<File> files = new ArrayList<File>(new SortedList<File>(dir.listFiles()));
+
+		for (int i = 2; i < args.length; i++) {
+			Instructions filters = new Instructions(args[i]);
+			filters.select(files, true);
+		}
+
+		List<String> result = new ArrayList<String>();
+		for (File file : files)
+			result.add(relative ? file.getName() : file.getAbsolutePath());
+
+		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]);
+		else {
+			String v = domain.getProperty("@");
+			if (v == null)
+				return null;
+			version = new Version(v);
+		}
+		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);
+
+		String left = version(version, floorMask);
+		String right = version(version, ceilingMask);
+		StringBuilder sb = new StringBuilder();
+		sb.append(floor);
+		sb.append(left);
+		sb.append(",");
+		sb.append(right);
+		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_internal(boolean allowFail, String args[]) throws Exception {
+		verifyCommand(args, "${" + (allowFail ? "system-allow-fail" : "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)
+			return exitValue + "";
+
+		if (!allowFail && (exitValue != 0)) {
+			domain.error("System command " + command + " failed with " + exitValue);
+		}
+		return s.trim();
+	}
+
+	public String _system(String args[]) throws Exception {
+		return system_internal(false, args);
+	}
+
+	public String _system_allow_fail(String args[]) throws Exception {
+		String result = "";
+		try {
+			result = system_internal(true, args);
+		}
+		catch (Throwable t) {
+			/* ignore */
+		}
+		return result;
+	}
+
+	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() {
+			StringBuilder sb = new StringBuilder();
+			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 final 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.err.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 100755
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/Packages.java b/bundleplugin/src/main/java/aQute/lib/osgi/Packages.java
new file mode 100644
index 0000000..09e8305
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Packages.java
@@ -0,0 +1,230 @@
+package aQute.lib.osgi;
+
+import java.util.*;
+
+import aQute.lib.osgi.Descriptors.PackageRef;
+import aQute.libg.header.*;
+
+public class Packages implements Map<PackageRef, Attrs> {
+	private LinkedHashMap<PackageRef, Attrs>	map;
+	static Map<PackageRef, Attrs>		EMPTY	= Collections.emptyMap();
+
+	public Packages(Packages other) {
+		if (other.map != null) {
+			map = new LinkedHashMap<Descriptors.PackageRef, Attrs>(other.map);
+		}
+	}
+
+	public Packages() {
+	}
+
+	public void clear() {
+		if(map!=null)
+			map.clear();
+	}
+
+	public boolean containsKey(PackageRef name) {
+		if (map == null)
+			return false;
+
+		return map.containsKey(name);
+	}
+
+	@Deprecated public boolean containsKey(Object name) {
+		assert name instanceof PackageRef;
+		if (map == null)
+			return false;
+
+		return map.containsKey((PackageRef) name);
+	}
+
+	public boolean containsValue(Attrs value) {
+		if (map == null)
+			return false;
+
+		return map.containsValue(value);
+	}
+
+	@Deprecated public boolean containsValue(Object value) {
+		assert value instanceof Attrs;
+		if (map == null)
+			return false;
+
+		return map.containsValue((Attrs) value);
+	}
+
+	public Set<java.util.Map.Entry<PackageRef, Attrs>> entrySet() {
+		if (map == null)
+			return EMPTY.entrySet();
+
+		return map.entrySet();
+	}
+
+	@Deprecated public Attrs get(Object key) {
+		assert key instanceof PackageRef;
+		if (map == null)
+			return null;
+
+		return map.get((PackageRef) key);
+	}
+
+	public Attrs get(PackageRef key) {
+		if (map == null)
+			return null;
+
+		return map.get(key);
+	}
+
+	public boolean isEmpty() {
+		return map == null || map.isEmpty();
+	}
+
+	public Set<PackageRef> keySet() {
+		if (map == null)
+			return EMPTY.keySet();
+
+		return map.keySet();
+	}
+
+	public Attrs put(PackageRef ref) {
+		Attrs attrs = get(ref);
+		if (attrs != null)
+			return attrs;
+
+		attrs = new Attrs();
+		put(ref, attrs);
+		return attrs;
+	}
+
+	public Attrs put(PackageRef key, Attrs value) {
+		if (map == null)
+			map = new LinkedHashMap<PackageRef, Attrs>();
+
+		return map.put(key, value);
+	}
+
+	public void putAll(Map<? extends PackageRef, ? extends Attrs> map) {
+		if (this.map == null)
+			if (map.isEmpty())
+				return;
+			else
+				this.map = new LinkedHashMap<PackageRef, Attrs>();
+		this.map.putAll(map);
+	}
+
+	public void putAllIfAbsent(Map<PackageRef, ? extends Attrs> map) {
+		for(Map.Entry<PackageRef, ? extends Attrs> entry : map.entrySet() ) {
+			if ( !containsKey(entry.getKey()))
+				put(entry.getKey(), entry.getValue());
+		}
+	}
+	
+	@Deprecated public Attrs remove(Object var0) {
+		assert var0 instanceof PackageRef;
+		if (map == null)
+			return null;
+
+		return map.remove((PackageRef) var0);
+	}
+
+	public Attrs remove(PackageRef var0) {
+		if (map == null)
+			return null;
+		return map.remove(var0);
+	}
+
+	public int size() {
+		if (map == null)
+			return 0;
+		return map.size();
+	}
+
+	public Collection<Attrs> values() {
+		if (map == null)
+			return EMPTY.values();
+
+		return map.values();
+	}
+
+	public Attrs getByFQN(String s) {
+		if (map == null)
+			return null;
+
+		for (Map.Entry<PackageRef, Attrs> pr : map.entrySet()) {
+			if (pr.getKey().getFQN().equals(s))
+				return pr.getValue();
+		}
+		return null;
+	}
+
+	public Attrs getByBinaryName(String s) {
+		if (map == null)
+			return null;
+
+		for (Map.Entry<PackageRef, Attrs> pr : map.entrySet()) {
+			if (pr.getKey().getBinary().equals(s))
+				pr.getValue();
+		}
+		return null;
+	}
+
+	public boolean containsFQN(String s) {
+		return getByFQN(s) != null;
+	}
+
+	public boolean containsBinaryName(String s) {
+		return getByFQN(s) != null;
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		append(sb);
+		return sb.toString();
+	}
+
+	public void append(StringBuilder sb) {
+		String del = "";
+		for (Map.Entry<PackageRef, Attrs> s : entrySet()) {
+			sb.append(del);
+			sb.append(s.getKey());
+			if (!s.getValue().isEmpty()) {
+				sb.append(';');
+				s.getValue().append(sb);
+			}
+			del = ",";
+		}
+	}
+
+	public void merge(PackageRef ref, boolean unique, Attrs... attrs) {
+		if ( unique ) {
+			while ( containsKey(ref))
+				ref = ref.getDuplicate();
+		}
+		
+		Attrs org = put(ref);
+		for (Attrs a : attrs) {
+			if (a != null)
+				org.putAll(a);
+		}
+	}
+
+	public Attrs get(PackageRef packageRef, Attrs deflt) {
+		Attrs mine = get(packageRef);
+		if ( mine!=null)
+			return mine;
+		
+		return deflt;
+	}
+
+
+	@Deprecated
+	public boolean equals(Object other) {
+		return super.equals(other);
+	}
+	
+	@Deprecated
+	public int hashCode() {
+		return super.hashCode();
+	}
+	
+}
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..f003abc
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/PreprocessResource.java
@@ -0,0 +1,44 @@
+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;
+        setExtra(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 = null;
+        BufferedReader rdr = null;
+        try {
+			in = resource.openInputStream();
+            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 {
+			if (rdr != null) {
+				rdr.close();
+			}
+			if (in != null) {
+				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 100755
index 0000000..655ce4d
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java
@@ -0,0 +1,1587 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.collections.*;
+import aQute.lib.io.*;
+import aQute.libg.generics.*;
+import aQute.libg.header.*;
+import aQute.libg.reporter.*;
+
+public class Processor extends Domain 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 final 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>();
+	private 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;
+	List<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(Reporter processor, String prefix) {
+		if (isFailOk())
+			addAll(warnings, processor.getErrors(), prefix);
+		else
+			addAll(errors, processor.getErrors(), prefix);
+		addAll(warnings, processor.getWarnings(), prefix);
+
+		processor.getErrors().clear();
+		processor.getWarnings().clear();
+	}
+
+	public void getInfo(Reporter 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 = formatArrays(string, args);
+		if (!p.warnings.contains(s))
+			p.warnings.add(s);
+		p.signal();
+	}
+
+	public void error(String string, Object... args) {
+		Processor p = current();
+		if (p.isFailOk())
+			p.warning(string, args);
+		else {
+			String s = formatArrays(string, args);
+			if (!p.errors.contains(s))
+				p.errors.add(s);
+		}
+		p.signal();
+	}
+
+	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 = formatArrays(string, args);
+			if (!p.errors.contains(s))
+				p.errors.add(s);
+		}
+		if (p.exceptions)
+			t.printStackTrace();
+
+		p.signal();
+	}
+
+	public void signal() {
+	}
+
+	public List<String> getWarnings() {
+		return warnings;
+	}
+
+	public List<String> getErrors() {
+		return errors;
+	}
+
+	/**
+	 * Standard OSGi header parser.
+	 * 
+	 * @param value
+	 * @return
+	 */
+	static public Parameters parseHeader(String value, Processor logger) {
+		return new Parameters(value, logger);
+	}
+
+	public Parameters parseHeader(String value) {
+		return new Parameters(value, this);
+	}
+
+	public void addClose(Closeable jar) {
+		assert jar != null;
+		toBeClosed.add(jar);
+	}
+
+	public void removeClose(Closeable jar) {
+		assert jar != null;
+		toBeClosed.remove(jar);
+	}
+
+	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 void use(Processor reporter) {
+		setPedantic(reporter.isPedantic());
+		setTrace(reporter.isTrace());
+		setBase(reporter.getBase());
+		setFailOk(reporter.isFailOk());
+	}
+
+	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>();
+
+			String pluginPath = getProperty(PLUGINPATH);
+			loadPlugins(list, spe, pluginPath);
+		}
+
+		return this.plugins = list;
+	}
+
+	/**
+	 * @param list
+	 * @param spe
+	 */
+	protected void loadPlugins(Set<Object> list, String spe, String pluginPath) {
+		Parameters plugins = new Parameters(spe);
+		CL loader = getLoader();
+
+		// First add the plugin-specific paths from their path: directives
+		for (Entry<String, Attrs> entry : plugins.entrySet()) {
+			String key = removeDuplicateMarker(entry.getKey());
+			String path = entry.getValue().get(PATH_DIRECTIVE);
+			if (path != null) {
+				String parts[] = path.split("\\s*,\\s*");
+				try {
+					for (String p : parts) {
+						File f = getFile(p).getAbsoluteFile();
+						loader.add(f.toURI().toURL());
+					}
+				} catch (Exception e) {
+					error("Problem adding path %s to loader for plugin %s. Exception: (%s)", path,
+							key, e);
+				}
+			}
+		}
+
+		// Next add -pluginpath entries
+		if (pluginPath != null && pluginPath.length() > 0) {
+			StringTokenizer tokenizer = new StringTokenizer(pluginPath, ",");
+			while (tokenizer.hasMoreTokens()) {
+				String path = tokenizer.nextToken().trim();
+				try {
+					File f = getFile(path).getAbsoluteFile();
+					loader.add(f.toURI().toURL());
+				} catch (Exception e) {
+					error("Problem adding path %s from global plugin path. Exception: %s", path, e);
+				}
+			}
+		}
+
+		// Load the plugins
+		for (Entry<String, Attrs> entry : plugins.entrySet()) {
+			String key = entry.getKey();
+
+			try {
+				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: %s exception: (%s)", key, 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, Attrs 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.err.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 LinkedHashMap<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 void addProperties(Map<?, ?> properties) {
+		for (Entry<?, ?> entry : properties.entrySet()) {
+			setProperty(entry.getKey().toString(), entry.getValue() + "");
+		}
+	}
+
+	public synchronized void addIncluded(File file) {
+		if (included == null)
+			included = new ArrayList<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 = new Parameters(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 {
+		doIncludeFile(file, overwrite, target, null);
+	}
+
+	/**
+	 * @param file
+	 * @param parent
+	 * @param done
+	 * @param overwrite
+	 * @param extensionName
+	 * @throws FileNotFoundException
+	 * @throws IOException
+	 */
+	public void doIncludeFile(File file, boolean overwrite, Properties target, String extensionName) 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);
+			try {
+				Properties sub;
+				if (file.getName().toLowerCase().endsWith(".mf")) {
+					sub = getManifestAsProperties(in);
+				} else
+					sub = loadProperties(in, file.getAbsolutePath());
+
+				doIncludes(file.getParentFile(), sub);
+				// make sure we do not override properties
+				for (Map.Entry<?, ?> entry : sub.entrySet()) {
+					String key = (String) entry.getKey();
+					String value = (String) entry.getValue();
+					
+					if (overwrite || !target.containsKey(key)) {
+						target.setProperty(key, value);
+					} else if (extensionName != null) {
+						String extensionKey = extensionName + "." + key;
+						if (!target.containsKey(extensionKey))
+							target.setProperty(extensionKey, value);
+					}
+				}
+			} finally {
+				IO.close(in);
+			}
+		}
+	}
+
+	public void unsetProperty(String string) {
+		getProperties().remove(string);
+
+	}
+
+	public boolean refresh() {
+		plugins = null; // We always refresh our plugins
+
+		if (propertiesFile == null)
+			return false;
+
+		boolean changed = updateModified(propertiesFile.lastModified(), "properties file");
+		if (included != null) {
+			for (File file : included) {
+				if (changed)
+					break;
+
+				changed |= !file.exists()
+						|| updateModified(file.lastModified(), "include file: " + file);
+			}
+		}
+
+		if (changed) {
+			forceRefresh();
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * 
+	 */
+	public void forceRefresh() {
+		included = null;
+		properties.clear();
+		setProperties(propertiesFile, base);
+		propertiesChanged();
+	}
+
+	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.err.println("Loading properties " + propertiesFile);
+				long modified = propertiesFile.lastModified();
+				if (modified > System.currentTimeMillis() + 100) {
+					System.err.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 without preprocessing it with a proper default
+	 * 
+	 * @param headerName
+	 * @param deflt
+	 * @return
+	 */
+	
+	public String getUnprocessedProperty(String key, String deflt) {
+		return getProperties().getProperty(key, deflt);
+	}
+	
+	/**
+	 * Get a property with preprocessing it with a proper default
+	 * 
+	 * @param headerName
+	 * @param deflt
+	 * @return
+	 */
+	public String getProperty(String key, String deflt) {
+		String value = null;
+
+		Instruction ins = new Instruction(key);
+		if (!ins.isLiteral()) {
+			// Handle a wildcard key, make sure they're sorted
+			// for consistency
+			SortedList<String> sortedList = SortedList.fromIterator(iterator());
+			StringBuilder sb = new StringBuilder();
+			String del = "";
+			for (String k : sortedList) {
+				if (ins.matches(k)) {
+					String v = getProperty(k, null);
+					if (v != null) {
+						sb.append(del);
+						del = ",";
+						sb.append(v);
+					}
+				}
+			}
+			if (sb.length() == 0)
+				return deflt;
+
+			return sb.toString();
+		}
+
+		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);
+		try {
+			Properties p = loadProperties(in, file.getAbsolutePath());
+			return p;
+		} finally {
+			in.close();
+		}
+	}
+
+	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;
+	}
+
+	/**
+	 * Print a standard Map based OSGi header.
+	 * 
+	 * @param exports
+	 *            map { name => Map { attribute|directive => value } }
+	 * @return the clauses
+	 * @throws IOException
+	 */
+	public static String printClauses(Map<?, ? extends Map<?, ?>> exports) throws IOException {
+		return printClauses(exports, false);
+	}
+
+	public static String printClauses(Map<?, ? extends Map<?, ?>> exports,
+			boolean checkMultipleVersions) throws IOException {
+		StringBuilder sb = new StringBuilder();
+		String del = "";
+		for (Entry<?, ? extends Map<?, ?>> entry : exports.entrySet()) {
+			String name = entry.getKey().toString();
+			Map<?, ?> clause = entry.getValue();
+
+			// 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<?, ?> map, StringBuilder sb) throws IOException {
+
+		for (Entry<?, ?> entry : map.entrySet()) {
+			Object key = entry.getKey();
+			// 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) entry.getValue()).trim();
+			sb.append(";");
+			sb.append(key);
+			sb.append("=");
+
+			quote(sb, value);
+		}
+	}
+
+	/**
+	 * @param sb
+	 * @param value
+	 * @return
+	 * @throws IOException
+	 */
+	public static boolean quote(Appendable sb, String value) throws IOException {
+		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("\"");
+		return clean;
+	}
+
+	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();
+
+	}
+
+	/**
+	 * Return all inherited property keys
+	 * 
+	 * @return
+	 */
+	public Set<String> getPropertyKeys(boolean inherit) {
+		Set<String> result;
+		if (parent == null || !inherit) {
+			result = Create.set();
+		} else
+			result = parent.getPropertyKeys(inherit);
+		for (Object o : properties.keySet())
+			result.add(o.toString());
+
+		return result;
+	}
+
+	public boolean updateModified(long time, String reason) {
+		if (time > lastModified) {
+			lastModified = time;
+			return true;
+		}
+		return false;
+	}
+
+	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 = "";
+		if (list != null) {
+			for (Collection<?> l : list) {
+				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 check(String... pattern) throws IOException {
+		Set<String> missed = Create.set();
+
+		if (pattern != null) {
+			for (String p : pattern) {
+				boolean match = false;
+				Pattern pat = Pattern.compile(p);
+				for (Iterator<String> i = errors.iterator(); i.hasNext();) {
+					if (pat.matcher(i.next()).find()) {
+						i.remove();
+						match = true;
+					}
+				}
+				for (Iterator<String> i = warnings.iterator(); i.hasNext();) {
+					if (pat.matcher(i.next()).find()) {
+						i.remove();
+						match = true;
+					}
+				}
+				if (!match)
+					missed.add(p);
+
+			}
+		}
+		if (missed.isEmpty() && isPerfect())
+			return true;
+
+		if (!missed.isEmpty())
+			System.err
+					.println("Missed the following patterns in the warnings or errors: " + missed);
+
+		report(System.err);
+		return false;
+	}
+
+	protected void report(Appendable out) throws IOException {
+		if (errors.size() > 0) {
+			out.append("-----------------\nErrors\n");
+			for (int i = 0; i < errors.size(); i++) {
+				out.append(String.format("%03d: %s\n", i, errors.get(i)));
+			}
+		}
+		if (warnings.size() > 0) {
+			out.append(String.format("-----------------\nWarnings\n"));
+			for (int i = 0; i < warnings.size(); i++) {
+				out.append(String.format("%03d: %s\n", i, warnings.get(i)));
+			}
+		}
+	}
+
+	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 Attrs doAttrbutes(Object[] attrs, Clazz clazz, Macro macro) {
+		Attrs map = new Attrs();
+
+		if (attrs == null || attrs.length == 0)
+			return map;
+
+		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(formatArrays(
+						"Invalid attribute on package-info.java in %s , %s. Must be <key>=<name> ",
+						clazz, attr));
+		}
+		return map;
+	}
+
+	/**
+	 * This method is the same as String.format but it makes sure that any
+	 * arrays are transformed to strings.
+	 * 
+	 * @param string
+	 * @param parms
+	 * @return
+	 */
+	public static String formatArrays(String string, Object... parms) {
+		Object[] parms2 = parms;
+		Object[] output = new Object[parms.length];
+		for (int i = 0; i < parms.length; i++) {
+			output[i] = makePrintable(parms[i]);
+		}
+		return String.format(string, parms2);
+	}
+
+	/**
+	 * Check if the object is an array and turn it into a string if it is,
+	 * otherwise unchanged.
+	 * 
+	 * @param object
+	 *            the object to make printable
+	 * @return a string if it was an array or the original object
+	 */
+	public static Object makePrintable(Object object) {
+		if (object == null)
+			return object;
+
+		if (object.getClass().isArray()) {
+			Object[] array = (Object[]) object;
+			Object[] output = new Object[array.length];
+			for (int i = 0; i < array.length; i++) {
+				output[i] = makePrintable(array[i]);
+			}
+			return Arrays.toString(output);
+		}
+		return object;
+	}
+
+	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.");
+			}
+		}
+
+		synchronized (Processor.class) {
+			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);
+	}
+
+	public List<File> getIncluded() {
+		return included;
+	}
+
+	/**
+	 * Overrides for the Domain class
+	 */
+	@Override public String get(String key) {
+		return getProperty(key);
+	}
+
+	@Override public String get(String key, String deflt) {
+		return getProperty(key, deflt);
+	}
+
+	@Override public void set(String key, String value) {
+		getProperties().setProperty(key, value);
+	}
+
+	@Override public Iterator<String> iterator() {
+		Set<String> keys = keySet();
+		final Iterator<String> it = keys.iterator();
+
+		return new Iterator<String>() {
+			String	current;
+
+			public boolean hasNext() {
+				return it.hasNext();
+			}
+
+			public String next() {
+				return current = it.next().toString();
+			}
+
+			public void remove() {
+				getProperties().remove(current);
+			}
+		};
+	}
+
+	public Set<String> keySet() {
+		Set<String> set;
+		if (parent == null)
+			set = Create.set();
+		else
+			set = parent.keySet();
+
+		for (Object o : properties.keySet())
+			set.add(o.toString());
+
+		return set;
+	}
+
+	/**
+	 * Printout of the status of this processor for toString()
+	 */
+
+	public String toString() {
+		try {
+			StringBuilder sb = new StringBuilder();
+			report(sb);
+			return sb.toString();
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	/**
+	 * Utiltity to replace an extension
+	 * 
+	 * @param s
+	 * @param extension
+	 * @param newExtension
+	 * @return
+	 */
+	public String replaceExtension(String s, String extension, String newExtension) {
+		if (s.endsWith(extension))
+			s = s.substring(0, s.length() - extension.length());
+
+		return s + newExtension;
+	}
+}
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 100755
index 0000000..f7df287
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Resource.java
@@ -0,0 +1,12 @@
+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();
+	long size() throws Exception;
+}
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..0318427
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/TagResource.java
@@ -0,0 +1,30 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+
+import aQute.lib.tag.*;
+
+public class TagResource extends WriteResource {
+	final Tag	tag;
+
+	public TagResource(Tag tag) {
+		this.tag = tag;
+	}
+
+
+	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;
+	}
+
+}
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 100755
index 0000000..6e96f23
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/URLResource.java
@@ -0,0 +1,82 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.net.*;
+
+import aQute.lib.io.*;
+
+public class URLResource implements Resource {
+	URL		url;
+	String	extra;
+	long	size	= -1;
+
+	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 {
+		IO.copy(this.openInputStream(), out);
+	}
+
+	public long lastModified() {
+		return -1;
+	}
+
+	public String getExtra() {
+		return extra;
+	}
+
+	public void setExtra(String extra) {
+		this.extra = extra;
+	}
+
+	public long size() throws Exception {
+		if (size >= 0)
+			return size;
+
+		try {
+			if (url.getProtocol().equals("file:")) {
+				File file = new File(url.getPath());
+				if ( file.isFile())
+					return size = file.length();
+			} else {
+				URLConnection con = url.openConnection();
+				if (con instanceof HttpURLConnection) {
+					HttpURLConnection http = (HttpURLConnection) con;
+					http.setRequestMethod("HEAD");
+					http.connect();
+					String l = http.getHeaderField("Content-Length");
+					if (l != null) {
+						return size = Long.parseLong(l);
+					}
+				}
+			}
+		} catch (Exception e) {
+			// Forget this exception, we do it the hard way
+		}
+		InputStream in = openInputStream();
+		DataInputStream din = null;
+		try {
+			din = new DataInputStream(in);
+			long result = din.skipBytes(Integer.MAX_VALUE);
+			while( in.read() >= 0) {
+				result += din.skipBytes(Integer.MAX_VALUE);
+			}
+			size = result;
+		} finally {
+			if (din != null) {
+				din.close();
+			}
+		}
+		return size;
+	}
+
+}
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 100755
index 0000000..89bd7f0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Verifier.java
@@ -0,0 +1,938 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.jar.*;
+import java.util.regex.*;
+
+import aQute.lib.base64.*;
+import aQute.lib.io.*;
+import aQute.lib.osgi.Descriptors.PackageRef;
+import aQute.lib.osgi.Descriptors.TypeRef;
+import aQute.libg.cryptography.*;
+import aQute.libg.header.*;
+import aQute.libg.qtokens.*;
+
+public class Verifier extends Processor {
+
+	private final Jar		dot;
+	private final Manifest	manifest;
+	private final Domain	main;
+
+	private boolean			r3;
+	private boolean			usesRequire;
+
+	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;
+	final static int		V1_8	= 52;
+
+	static class EE {
+		String	name;
+		int		target;
+
+		EE(String name, int source, int target) {
+			this.name = name;
+			this.target = target;
+		}
+
+		public String toString() {
+			return name + "(" + 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("JavaSE-1.7", V1_7, V1_7), //
+			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		CARDINALITY_PATTERN				= Pattern
+																		.compile("single|multiple");
+	final static Pattern		RESOLUTION_PATTERN				= Pattern
+																		.compile("optional|mandatory");
+	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	PACKAGEPATTERN					= Pattern
+																		.compile("\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*");
+	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",											};
+
+	final Analyzer				analyzer;
+	private Instructions		dynamicImports;
+
+	public Verifier(Jar jar) throws Exception {
+		this.analyzer = new Analyzer(this);
+		this.analyzer.use(this);
+		addClose(analyzer);
+		this.analyzer.setJar(jar);
+		this.manifest = this.analyzer.calcManifest();
+		this.main = Domain.domain(manifest);
+		this.dot = jar;
+		getInfo(analyzer);
+	}
+
+	public Verifier(Analyzer analyzer) throws Exception {
+		this.analyzer = analyzer;
+		this.dot = analyzer.getJar();
+		this.manifest = dot.getManifest();
+		this.main = Domain.domain(manifest);
+	}
+
+	private void verifyHeaders() {
+		for (String h : main) {
+			if (!HEADER_PATTERN.matcher(h).matches())
+				error("Invalid Manifest header: " + h + ", pattern=" + HEADER_PATTERN);
+		}
+	}
+
+	/*
+	 * Bundle-NativeCode ::= nativecode ( ',' nativecode )* ( ’,’ optional) ?
+	 * nativecode ::= path ( ';' path )* // See 1.4.2 ( ';' parameter )+
+	 * optional ::= ’*’
+	 */
+	public void verifyNative() {
+		String nc = get("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) {
+		String s = validateFilter(value);
+		if (s == null)
+			return true;
+
+		error(s);
+		return false;
+	}
+
+	public static String validateFilter(String value) {
+		try {
+			verifyFilter(value, 0);
+			return null;
+		} catch (Exception e) {
+			return "Not a valid filter: " + value + e.getMessage();
+		}
+	}
+
+	private void verifyActivator() throws Exception {
+		String bactivator = main.get("Bundle-Activator");
+		if (bactivator != null) {
+			TypeRef ref = analyzer.getTypeRefFromFQN(bactivator);
+			if (analyzer.getClassspace().containsKey(ref))
+				return;
+
+			PackageRef packageRef = ref.getPackageRef();
+			if (packageRef.isDefaultPackage())
+				error("The Bundle Activator is not in the bundle and it is in the default package ");
+			else if (!analyzer.isImported(packageRef)) {
+				error("Bundle-Activator not found on the bundle class path nor in imports: "
+						+ bactivator);
+			}
+		}
+	}
+
+	private void verifyComponent() {
+		String serviceComponent = main.get("Service-Component");
+		if (serviceComponent != null) {
+			Parameters 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 ...
+				}
+			}
+		}
+	}
+
+	/**
+	 * Check for unresolved imports. These are referrals that are not imported
+	 * by the manifest and that are not part of our bundle class path. The are
+	 * calculated by removing all the imported packages and contained from the
+	 * referred packages.
+	 */
+	private void verifyUnresolvedReferences() {
+		Set<PackageRef> unresolvedReferences = new TreeSet<PackageRef>(analyzer.getReferred()
+				.keySet());
+		unresolvedReferences.removeAll(analyzer.getImports().keySet());
+		unresolvedReferences.removeAll(analyzer.getContained().keySet());
+
+		// Remove any java.** packages.
+		for (Iterator<PackageRef> p = unresolvedReferences.iterator(); p.hasNext();) {
+			PackageRef pack = p.next();
+			if (pack.isJava())
+				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 : analyzer.getClassspace().values()) {
+				if (hasOverlap(unresolvedReferences, clazz.getReferred()))
+					culprits.add(clazz.getAbsolutePath());
+			}
+
+			error("Unresolved references to %s by class(es) %s on the Bundle-Classpath: %s",
+					unresolvedReferences, culprits, analyzer.getBundleClasspath().keySet());
+		}
+	}
+
+	/**
+	 * @param p
+	 * @param pack
+	 */
+	private boolean isDynamicImport(PackageRef pack) {
+		if (dynamicImports == null)
+			dynamicImports = new Instructions(main.getDynamicImportPackage());
+
+		return dynamicImports.matches(pack.getFQN());
+	}
+
+	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 {
+		verifyHeaders();
+		verifyDirectives("Export-Package",
+				"uses:|mandatory:|include:|exclude:|" + IMPORT_DIRECTIVE, PACKAGEPATTERN, "package");
+		verifyDirectives("Import-Package", "resolution:", PACKAGEPATTERN, "package");
+		verifyDirectives("Require-Bundle", "visibility:|resolution:", SYMBOLICNAME, "bsn");
+		verifyDirectives("Fragment-Host", "extension:", SYMBOLICNAME, "bsn");
+		verifyDirectives("Provide-Capability", "effective:|uses:", null, null);
+		verifyDirectives("Require-Capability", "effective:|resolution:|filter:", null,null);
+		verifyDirectives("Bundle-SymbolicName", "singleton:|fragment-attachment:|mandatory:",
+				SYMBOLICNAME,"bsn");
+
+		verifyManifestFirst();
+		verifyActivator();
+		verifyActivationPolicy();
+		verifyComponent();
+		verifyNative();
+		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");
+			}
+		}
+
+		verifyRequirements();
+		verifyCapabilities();
+	}
+
+	private void verifyRequirements() {
+		Parameters map = parseHeader(manifest.getMainAttributes().getValue(
+				Constants.REQUIRE_CAPABILITY));
+		for (String key : map.keySet()) {
+			Attrs attrs = map.get(key);
+			verify(attrs, "filter:", FILTERPATTERN, false, "Requirement %s filter not correct", key);
+			verify(attrs, "cardinality:", CARDINALITY_PATTERN, false,
+					"Requirement %s cardinality not correct", key);
+			verify(attrs, "resolution:", RESOLUTION_PATTERN, false,
+					"Requirement %s resolution not correct", key);
+
+			if (key.equals("osgi.extender")) {
+				// No requirements on extender
+			} else if (key.equals("osgi.serviceloader")) {
+				verify(attrs, "register:", PACKAGEPATTERN, false,
+						"Service Loader extender register: directive not a fully qualified Java name");
+			} else if (key.equals("osgi.contract")) {
+
+			} else if (key.equals("osgi.service")) {
+
+			} else if (key.equals("osgi.ee")) {
+
+			} else if (key.startsWith("osgi.wiring.") || key.startsWith("osgi.identity")) {
+				error("osgi.wiring.* namespaces must not be specified with generic requirements/capabilities");
+			}
+
+			verifyAttrs(attrs);
+
+			if (attrs.containsKey("mandatory:"))
+				error("mandatory: directive is intended for Capabilities, not Requirement %s", key);
+
+			if (attrs.containsKey("uses:"))
+				error("uses: directive is intended for Capabilities, not Requirement %s", key);
+		}
+	}
+
+	/**
+	 * @param attrs
+	 */
+	void verifyAttrs(Attrs attrs) {
+		for (String a : attrs.keySet()) {
+			String v = attrs.get(a);
+
+			if (!a.endsWith(":")) {
+				Attrs.Type t = attrs.getType(a);
+				if ("version".equals(a)) {
+					if (t != Attrs.Type.VERSION)
+						error("Version attributes should always be of type version, it is %s", t);
+				} else
+					verifyType(t, v);
+			}
+		}
+	}
+
+	private void verifyCapabilities() {
+		Parameters map = parseHeader(manifest.getMainAttributes().getValue(
+				Constants.PROVIDE_CAPABILITY));
+		for (String key : map.keySet()) {
+			Attrs attrs = map.get(key);
+			verify(attrs, "cardinality:", CARDINALITY_PATTERN, false,
+					"Requirement %s cardinality not correct", key);
+			verify(attrs, "resolution:", RESOLUTION_PATTERN, false,
+					"Requirement %s resolution not correct", key);
+
+			if (key.equals("osgi.extender")) {
+				verify(attrs, "osgi.extender", SYMBOLICNAME, true,
+						"Extender %s must always have the osgi.extender attribute set", key);
+				verify(attrs, "version", VERSION, true, "Extender %s must always have a version",
+						key);
+			} else if (key.equals("osgi.serviceloader")) {
+				verify(attrs, "register:", PACKAGEPATTERN, false,
+						"Service Loader extender register: directive not a fully qualified Java name");
+			} else if (key.equals("osgi.contract")) {
+				verify(attrs, "osgi.contract", SYMBOLICNAME, true,
+						"Contracts %s must always have the osgi.contract attribute set", key);
+
+			} else if (key.equals("osgi.service")) {
+				verify(attrs, "objectClass", PACKAGEPATTERN, true,
+						"osgi.service %s must have the objectClass attribute set", key);
+
+			} else if (key.equals("osgi.ee")) {
+				// TODO
+			} else if (key.startsWith("osgi.wiring.") || key.startsWith("osgi.identity")) {
+				error("osgi.wiring.* namespaces must not be specified with generic requirements/capabilities");
+			}
+
+			verifyAttrs(attrs);
+
+			if (attrs.containsKey("filter:"))
+				error("filter: directive is intended for Requirements, not Capability %s", key);
+			if (attrs.containsKey("cardinality:"))
+				error("cardinality: directive is intended for Requirements, not Capability %s", key);
+			if (attrs.containsKey("resolution:"))
+				error("resolution: directive is intended for Requirements, not Capability %s", key);
+		}
+	}
+
+	private void verify(Attrs attrs, String ad, Pattern pattern, boolean mandatory, String msg,
+			String... args) {
+		String v = attrs.get(ad);
+		if (v == null) {
+			if (mandatory)
+				error("Missing required attribute/directive %s", ad);
+		} else {
+			Matcher m = pattern.matcher(v);
+			if (!m.matches())
+				error(msg, (Object[]) args);
+		}
+	}
+
+	private void verifyType(Attrs.Type type, String string) {
+
+	}
+
+	/**
+	 * Verify if the header does not contain any other directives
+	 * 
+	 * @param header
+	 * @param directives
+	 */
+	private void verifyDirectives(String header, String directives, Pattern namePattern, String type) {
+		Pattern pattern = Pattern.compile(directives);
+		Parameters map = parseHeader(manifest.getMainAttributes().getValue(header));
+		for (Entry<String, Attrs> entry : map.entrySet()) {
+			String pname = removeDuplicateMarker(entry.getKey());
+
+			if (namePattern != null) {
+				if (!namePattern.matcher(pname).matches())
+					if (isPedantic())
+						error("Invalid %s name: '%s'", type, pname);
+					else
+						warning("Invalid %s name: '%s'", type, pname);
+			}
+			
+			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() {
+		// Set<String> uses = Create.set();
+		// for ( Map<String,String> attrs : analyzer.getExports().values()) {
+		// if ( attrs.containsKey(Constants.USES_DIRECTIVE)) {
+		// String s = attrs.get(Constants.USES_DIRECTIVE);
+		// uses.addAll( split(s));
+		// }
+		// }
+		// uses.removeAll(analyzer.getExports().keySet());
+		// uses.removeAll(analyzer.getImports().keySet());
+		// if ( !uses.isEmpty())
+		// warning("Export-Package uses: directive contains packages that are not imported nor exported: %s",
+		// uses);
+	}
+
+	public boolean verifyActivationPolicy() {
+		String policy = main.get(Constants.BUNDLE_ACTIVATIONPOLICY);
+		if (policy == null)
+			return true;
+
+		return verifyActivationPolicy(policy);
+	}
+
+	public boolean verifyActivationPolicy(String policy) {
+		Parameters 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() {
+		Parameters bcp = main.getBundleClassPath();
+		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 = get("DynamicImport-Package");
+		if (dynamicImportPackage == null)
+			return;
+
+		Parameters map = main.getDynamicImportPackage();
+		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.isManifestFirst()) {
+			error("Invalid JAR stream: Manifest should come first to be compatible with JarInputStream, it was not");
+		}
+	}
+
+	private void verifySymbolicName() {
+		Parameters bsn = parseHeader(main.get(Analyzer.BUNDLE_SYMBOLICNAME));
+		if (!bsn.isEmpty()) {
+			if (bsn.size() > 1)
+				error("More than one BSN specified " + bsn);
+
+			String name = bsn.keySet().iterator().next();
+			if (!isBsn(name)) {
+				error("Symbolic Name has invalid format: " + name);
+			}
+		}
+	}
+
+	/**
+	 * @param name
+	 * @return
+	 */
+	public static boolean isBsn(String name) {
+		return SYMBOLICNAME.matcher(name).matches();
+	}
+
+	/**
+	 * <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) {
+		StringBuilder sb = new StringBuilder();
+		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 StringBuilder();
+		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 StringBuilder();
+		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 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(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;
+
+		Parameters 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 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;
+	}
+
+	/**
+	 * Verify checksums
+	 */
+	/**
+	 * Verify the checksums from the manifest against the real thing.
+	 * 
+	 * @param all
+	 *            if each resources must be digested
+	 * @return true if ok
+	 * @throws Exception
+	 */
+
+	public void verifyChecksums(boolean all) throws Exception {
+		Manifest m = dot.getManifest();
+		if (m == null || m.getEntries().isEmpty()) {
+			if (all)
+				error("Verify checksums with all but no digests");
+			return;
+		}
+
+		List<String> missingDigest = new ArrayList<String>();
+
+		for (String path : dot.getResources().keySet()) {
+			if (path.equals("META-INF/MANIFEST.MF"))
+				continue;
+
+			Attributes a = m.getAttributes(path);
+			String digest = a.getValue("SHA1-Digest");
+			if (digest == null) {
+				if (!path.matches(""))
+					missingDigest.add(path);
+			} else {
+				byte[] d = Base64.decodeBase64(digest);
+				SHA1 expected = new SHA1(d);
+				Digester<SHA1> digester = SHA1.getDigester();
+				InputStream in = dot.getResource(path).openInputStream();
+				IO.copy(in, digester);
+				digester.digest();
+				if (!expected.equals(digester.digest())) {
+					error("Checksum mismatch %s, expected %s, got %s", path, expected,
+							digester.digest());
+				}
+			}
+		}
+		if (missingDigest.size() > 0) {
+			error("Entries in the manifest are missing digests: %s", missingDigest);
+		}
+	}
+}
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..2acbe95
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/WriteResource.java
@@ -0,0 +1,68 @@
+package aQute.lib.osgi;
+
+import java.io.*;
+
+public abstract class WriteResource implements Resource {
+	String	extra;
+	volatile long size = -1;
+	
+	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);
+                    pout.flush();
+                } 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;
+	}
+	
+	static class CountingOutputStream extends OutputStream {
+		long size;
+
+		@Override public void write(int var0) throws IOException {
+			size++;
+		}
+		
+		@Override public void write(byte[] buffer) throws IOException {
+			size+=buffer.length;
+		}
+		
+		@Override public void write(byte [] buffer, int start, int length) throws IOException {
+			size+=length;
+		}
+	}
+	
+	public long size() throws IOException, Exception {
+		if ( size == -1 ) {
+			CountingOutputStream cout = new CountingOutputStream();
+			write(cout);
+			size = cout.size;
+		}
+		return size;
+	}
+}
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 100755
index 0000000..126faba
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/ZipResource.java
@@ -0,0 +1,88 @@
+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) throws UnsupportedEncodingException {
+        this.zip = zip;
+        this.entry = entry;
+        this.lastModified = lastModified;
+        byte[] data = entry.getExtra();
+        if (data != null)
+            this.extra = new String(data, "UTF-8");
+    }
+
+    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;
+    }
+
+    
+    public long size() {
+    	return entry.getSize();
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/bnd.info b/bundleplugin/src/main/java/aQute/lib/osgi/bnd.info
new file mode 100644
index 0000000..b1706a5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/bnd.info
@@ -0,0 +1,2 @@
+modified=${currenttime}
+version=${Bundle-Version}
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 100755
index 0000000..6e01ddc
--- /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 = 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..084a0d4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/packageinfo
@@ -0,0 +1 @@
+version 2.0.0
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..d9c60cd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java
@@ -0,0 +1,24 @@
+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 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..0109ad4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/SpringComponent.java
@@ -0,0 +1,99 @@
+package aQute.lib.spring;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.*;
+
+import javax.xml.transform.*;
+import javax.xml.transform.stream.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.lib.osgi.Descriptors.PackageRef;
+import aQute.libg.header.*;
+
+/**
+ * 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;
+	}
+
+    public boolean analyzeJar(Analyzer analyzer) throws Exception {
+	    Jar jar = analyzer.getJar();
+	    Map<String, Resource> dir = jar.getDirectories().get("META-INF/spring");
+		if ( dir == null || dir.isEmpty())
+			return false;
+		
+		for (Iterator<Entry<String, Resource>> i = dir.entrySet().iterator(); i.hasNext();) {
+			Entry<String, Resource> entry = i.next();
+			String path = entry.getKey();
+			Resource resource = entry.getValue();
+			if (SPRING_SOURCE.matcher(path).matches()) {
+				try {
+				InputStream in = resource.openInputStream();
+				Set<CharSequence> set = analyze(in);
+				in.close();
+				for (Iterator<CharSequence> r = set.iterator(); r.hasNext();) {
+					PackageRef pack = analyzer.getPackageRef((String) r.next());
+					if ( !QN.matcher(pack.getFQN()).matches())
+					    analyzer.warning("Package does not seem a package in spring resource ("+path+"): " + pack );
+					if (!analyzer.getReferred().containsKey(pack))
+						analyzer.getReferred().put(pack, new Attrs());
+				}
+				} 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..60eb922
--- /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", "OSGI-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..f7c6b33
--- /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.*;
+import aQute.lib.osgi.Descriptors.PackageRef;
+
+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();) {
+                PackageRef pack = analyzer.getPackageRef(r.next());
+                if (!QN.matcher(pack.getFQN()).matches())
+                    analyzer
+                            .warning("Package does not seem a package in spring resource ("
+                                    + path + "): " + pack);
+                if (!analyzer.getReferred().containsKey(pack))
+                    analyzer.getReferred().put(pack);
+            }
+        } 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..6ae0e7e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/spring/XMLTypeProcessor.java
@@ -0,0 +1,34 @@
+package aQute.lib.spring;
+
+import java.util.*;
+
+import aQute.bnd.service.*;
+import aQute.lib.osgi.*;
+import aQute.libg.header.*;
+
+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 {
+        
+        Parameters 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/spring/extract.xsl b/bundleplugin/src/main/java/aQute/lib/spring/extract.xsl
new file mode 100644
index 0000000..efad6cd
--- /dev/null
+++ b/bundleplugin/src/main/java/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/java/aQute/lib/spring/hibernate.xsl b/bundleplugin/src/main/java/aQute/lib/spring/hibernate.xsl
new file mode 100644
index 0000000..1f0a1c6
--- /dev/null
+++ b/bundleplugin/src/main/java/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/java/aQute/lib/spring/jpa.xsl b/bundleplugin/src/main/java/aQute/lib/spring/jpa.xsl
new file mode 100644
index 0000000..43bba60
--- /dev/null
+++ b/bundleplugin/src/main/java/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>
+
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 100755
index 0000000..5ec25a0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/tag/Tag.java
@@ -0,0 +1,471 @@
+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
+	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 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() {
+		StringBuilder sb = new StringBuilder();
+		getContentsAsString(sb);
+		return sb.toString();
+	}
+
+	/**
+	 * convenient method to get the contents in a StringBuilder.
+	 */
+	public void getContentsAsString(StringBuilder 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("=\"");
+			pw.print(value);
+			pw.print("\"");
+		}
+
+		if (content.size() == 0)
+			pw.print('/');
+		else {
+			pw.print('>');
+			for (Object c : content) {
+				if (c instanceof String) {
+					if (cdata) {
+						pw.print("<![CDATA[");
+						String s = (String) c;
+						s = s.replaceAll("]]>", "] ]>");
+						pw.print(s);
+						pw.print("]]>");
+					} else
+						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) {
+		StringBuilder sb = new StringBuilder();
+		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("&quot;");
+				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));
+		}
+		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);
+		StringBuilder sb = new StringBuilder();
+		for (Tag tag : tags) {
+			if (attribute == null)
+				tag.getContentsAsString(sb);
+			else
+				sb.append(tag.getAttribute(attribute));
+		}
+		return sb.toString();
+	}
+
+	public String getStringContent() {
+		StringBuilder sb = new StringBuilder();
+		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);
+		}
+		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/asn1/BER.java b/bundleplugin/src/main/java/aQute/libg/asn1/BER.java
new file mode 100644
index 0000000..4416dd4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/asn1/BER.java
@@ -0,0 +1,472 @@
+package aQute.libg.asn1;
+
+import java.io.*;
+import java.text.*;
+import java.util.*;
+
+public class BER implements Types {
+    DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss\\Z");
+    
+    final DataInputStream xin;
+    long                  position;
+
+    public BER(InputStream in) {
+        this.xin = new DataInputStream(in);
+    }
+
+    public void dump(PrintStream out) throws Exception {
+        int type = readByte();
+        long length = readLength();
+        if (type == -1 || length == -1)
+            throw new EOFException("Empty file");
+        dump(out, type, length, "");
+    }
+
+    void dump(PrintStream out, int type, long length, String indent)
+            throws Exception {
+        int clss = type >> 6;
+        int nmbr = type & 0x1F;
+        boolean cnst = (type & 0x20) != 0;
+
+        String tag = "[" + nmbr + "]";
+        if (clss == 0)
+            tag = TAGS[nmbr];
+
+        if (cnst) {
+            System.err.printf("%5d %s %s %s%n", length, indent, CLASSES[clss],
+                    tag);
+            while (length > 1) {
+                long atStart = getPosition();
+                int t2 = read();
+                long l2 = readLength();
+                dump(out, t2, l2, indent + "  ");
+                length -= getPosition() - atStart;
+            }
+        } else {
+            assert length < Integer.MAX_VALUE;
+            assert length >= 0;
+            byte[] data = new byte[(int) length];
+            readFully(data);
+            String summary;
+
+            switch (nmbr) {
+            case BOOLEAN:
+                assert length == 1;
+                summary = data[0] != 0 ? "true" : "false";
+                break;
+
+            case INTEGER:
+                long n = toLong(data);
+                summary = n + "";
+                break;
+
+            case UTF8_STRING:
+            case IA5STRING:
+            case VISIBLE_STRING:
+            case UNIVERSAL_STRING:
+            case PRINTABLE_STRING:
+            case UTCTIME:
+                summary = new String(data, "UTF-8");
+                break;
+
+            case OBJECT_IDENTIFIER:
+                summary = readOID(data);
+                break;
+
+            case GENERALIZED_TIME:
+            case GRAPHIC_STRING:
+            case GENERAL_STRING:
+            case CHARACTER_STRING:
+
+            case REAL:
+            case EOC:
+            case BIT_STRING:
+            case OCTET_STRING:
+            case NULL:
+            case OBJECT_DESCRIPTOR:
+            case EXTERNAL:
+            case ENUMERATED:
+            case EMBEDDED_PDV:
+            case RELATIVE_OID:
+            case NUMERIC_STRING:
+            case T61_STRING:
+            case VIDEOTEX_STRING:
+            case BMP_STRING:
+            default:
+                StringBuilder sb = new StringBuilder();
+                for (int i = 0; i < 10 && i < data.length; i++) {
+                    sb.append(Integer.toHexString(data[i]));
+                }
+                if (data.length > 10) {
+                    sb.append("...");
+                }
+                summary = sb.toString();
+                break;
+            }
+            out.printf("%5d %s %s %s %s\n", length, indent, CLASSES[clss], tag,
+                    summary);
+        }
+    }
+
+    long toLong(byte[] data) {
+        if (data[0] < 0) {
+            for (int i = 0; i < data.length; i++)
+                data[i] = (byte) (0xFF ^ data[i]);
+
+            return -(toLong(data) + 1);
+        }
+        long n = 0;
+        for (int i = 0; i < data.length; i++) {
+            n = n * 256 + data[i];
+        }
+        return n;
+    }
+
+    /**
+     * 8.1.3.3 For the definite form, the length octets shall consist of one or
+     * more octets, and shall represent the number of octets in the contents
+     * octets using either the short form (see 8.1.3.4) or the long form (see
+     * 8.1.3.5) as a sender's option. NOTE – The short form can only be used if
+     * the number of octets in the contents octets is less than or equal to 127.
+     * 8.1.3.4 In the short form, the length octets shall consist of a single
+     * octet in which bit 8 is zero and bits 7 to 1 encode the number of octets
+     * in the contents octets (which may be zero), as an unsigned binary integer
+     * with bit 7 as the most significant bit. EXAMPLE L = 38 can be encoded as
+     * 001001102 8.1.3.5 In the long form, the length octets shall consist of an
+     * initial octet and one or more subsequent octets. The initial octet shall
+     * be encoded as follows: a) bit 8 shall be one; b) bits 7 to 1 shall encode
+     * the number of subsequent octets in the length octets, as an unsigned
+     * binary integer with bit 7 as the most significant bit; c) the value
+     * 111111112 shall not be used. ISO/IEC 8825-1:2003 (E) NOTE 1 – This
+     * restriction is introduced for possible future extension. Bits 8 to 1 of
+     * the first subsequent octet, followed by bits 8 to 1 of the second
+     * subsequent octet, followed in turn by bits 8 to 1 of each further octet
+     * up to and including the last subsequent octet, shall be the encoding of
+     * an unsigned binary integer equal to the number of octets in the contents
+     * octets, with bit 8 of the first subsequent octet as the most significant
+     * bit. EXAMPLE L = 201 can be encoded as: 100000012 110010012 NOTE 2 – In
+     * the long form, it is a sender's option whether to use more length octets
+     * than the minimum necessary. 8.1.3.6 For the indefinite form, the length
+     * octets indicate that the contents octets are terminated by
+     * end-of-contents octets (see 8.1.5), and shall consist of a single octet.
+     * 8.1.3.6.1 The single octet shall have bit 8 set to one, and bits 7 to 1
+     * set to zero. 8.1.3.6.2 If this form of length is used, then
+     * end-of-contents octets (see 8.1.5) shall be present in the encoding
+     * following the contents octets. 8.1.4 Contents octets The contents octets
+     * shall consist of zero, one or more octets, and shall encode the data
+     * value as specified in subsequent clauses. NOTE – The contents octets
+     * depend on the type of the data value; subsequent clauses follow the same
+     * sequence as the definition of types in ASN.1. 8.1.5 End-of-contents
+     * octets The end-of-contents octets shall be present if the length is
+     * encoded as specified in 8.1.3.6, otherwise they shall not be present. The
+     * end-of-contents octets shall consist of two zero octets. NOTE – The
+     * end-of-contents octets can be considered as the encoding of a value whose
+     * tag is universal class, whose form is primitive, whose number of the tag
+     * is zero, and whose contents are absent, thus:
+     * 
+     * End-of-contents Length Contents 0016 0016 Absent
+     * 
+     * @return
+     */
+    private long readLength() throws IOException {
+        long n = readByte();
+        if (n > 0) {
+            // short form
+            return n;
+        }
+		// long form
+		int count = (int) (n & 0x7F);
+		if (count == 0) {
+		    // indefinite form
+		    return 0;
+		}
+		n = 0;
+		while (count-- > 0) {
+		    n = n * 256 + read();
+		}
+		return n;
+    }
+
+    private int readByte() throws IOException {
+        position++;
+        return xin.readByte();
+    }
+
+    private void readFully(byte[] data) throws IOException {
+        position += data.length;
+        xin.readFully(data);
+    }
+
+    private long getPosition() {
+        return position;
+    }
+
+    private int read() throws IOException {
+        position++;
+        return xin.read();
+    }
+
+    String readOID(byte[] data) {
+        StringBuilder sb = new StringBuilder();
+        sb.append((0xFF & data[0]) / 40);
+        sb.append(".");
+        sb.append((0xFF & data[0]) % 40);
+
+        int i = 0;
+        while (++i < data.length) {
+            int n = 0;
+            while (data[i] < 0) {
+                n = n * 128 + (0x7F & data[i]);
+                i++;
+            }
+            n = n * 128 + data[i];
+            sb.append(".");
+            sb.append(n);
+        }
+
+        return sb.toString();
+    }
+
+    int getPayloadLength(PDU pdu) throws Exception {
+        switch (pdu.getTag() & 0x1F) {
+        case EOC:
+            return 1;
+
+        case BOOLEAN:
+            return 1;
+
+        case INTEGER:
+            return size(pdu.getInt());
+
+        case UTF8_STRING:
+            String s = pdu.getString();
+            byte[] encoded = s.getBytes("UTF-8");
+            return encoded.length;
+
+        case IA5STRING:
+        case VISIBLE_STRING:
+        case UNIVERSAL_STRING:
+        case PRINTABLE_STRING:
+        case GENERALIZED_TIME:
+        case GRAPHIC_STRING:
+        case GENERAL_STRING:
+        case CHARACTER_STRING:
+        case UTCTIME:
+        case NUMERIC_STRING: {
+            String str = pdu.getString();
+            encoded = str.getBytes("ASCII");
+            return encoded.length;
+        }
+
+        case OBJECT_IDENTIFIER:
+        case REAL:
+        case BIT_STRING:
+            return pdu.getBytes().length;
+
+        case OCTET_STRING:
+        case NULL:
+        case OBJECT_DESCRIPTOR:
+        case EXTERNAL:
+        case ENUMERATED:
+        case EMBEDDED_PDV:
+        case RELATIVE_OID:
+        case T61_STRING:
+        case VIDEOTEX_STRING:
+        case BMP_STRING:
+            return pdu.getBytes().length;
+
+        default:
+            throw new IllegalArgumentException("Invalid type: " + pdu);
+        }
+    }
+
+    int size(long value) {
+        if (value < 128)
+            return 1;
+
+        if (value <= 0xFF)
+            return 2;
+
+        if (value <= 0xFFFF)
+            return 3;
+
+        if (value <= 0xFFFFFF)
+            return 4;
+
+        if (value <= 0xFFFFFFFF)
+            return 5;
+
+        if (value <= 0xFFFFFFFFFFL)
+            return 6;
+
+        if (value <= 0xFFFFFFFFFFFFL)
+            return 7;
+
+        if (value <= 0xFFFFFFFFFFFFFFL)
+            return 8;
+
+        if (value <= 0xFFFFFFFFFFFFFFFFL)
+            return 9;
+
+        throw new IllegalArgumentException("length too long");
+    }
+
+    public void write(OutputStream out, PDU pdu) throws Exception {
+        byte id = 0;
+
+        switch (pdu.getClss()) {
+        case UNIVERSAL:
+            id |= 0;
+            break;
+        case APPLICATION:
+            id |= 0x40;
+            break;
+        case CONTEXT:
+            id |= 0x80;
+            break;
+        case PRIVATE:
+            id |= 0xC0;
+            break;
+        }
+
+        if (pdu.isConstructed())
+            id |= 0x20;
+
+        int tag = pdu.getTag();
+        if (tag >= 0 && tag < 31) {
+            id |= tag;
+        } else {
+            throw new UnsupportedOperationException("Cant do tags > 30");
+        }
+
+        out.write(id);
+
+        int length = getPayloadLength(pdu);
+        int size = size(length);
+        if (size == 1) {
+            out.write(length);
+        } else {
+            out.write(size);
+            while (--size >= 0) {
+                byte data = (byte) ((length >> (size * 8)) & 0xFF);
+                out.write(data);
+            }
+        }
+        writePayload(out, pdu);
+    }
+
+    void writePayload(OutputStream out, PDU pdu) throws Exception {
+        switch (pdu.getTag()) {
+        case EOC:
+            out.write(0);
+            break;
+
+        case BOOLEAN:
+            if (pdu.getBoolean())
+                out.write(-1);
+            else
+                out.write(0);
+            break;
+
+        case ENUMERATED:
+        case INTEGER: {
+            long value = pdu.getInt();
+            int size = size(value);
+            for (int i = size; i >= 0; i--) {
+                byte b = (byte) ((value >> (i * 8)) & 0xFF);
+                out.write(b);
+            }
+        }
+
+        case BIT_STRING: {
+            byte bytes[] = pdu.getBytes();
+            int unused = bytes[0];
+            assert unused <= 7;
+            int[] mask = { 0xFF, 0x7F, 0x3F, 0x1F, 0xF, 0x7, 0x3, 0x1 };
+            bytes[bytes.length - 1] &= (byte) mask[unused];
+            out.write(bytes);
+            break;
+        }
+
+        case RELATIVE_OID:
+        case OBJECT_IDENTIFIER: {
+            int[] oid = pdu.getOID();
+            assert oid.length > 2;
+            assert oid[0] < 4;
+            assert oid[1] < 40;
+            byte top = (byte) (oid[0] * 40 + oid[1]);
+            out.write(top);
+            for (int i = 2; i < oid.length; i++) {
+                putOid(out,oid[i]);
+            }
+            break;
+        }
+
+        case OCTET_STRING: {
+            byte bytes[] = pdu.getBytes();
+            out.write(bytes);
+            break;
+        }
+
+        case NULL:
+            break;
+
+        case BMP_STRING:
+        case GRAPHIC_STRING:
+        case VISIBLE_STRING:
+        case GENERAL_STRING:
+        case UNIVERSAL_STRING:
+        case CHARACTER_STRING:
+        case NUMERIC_STRING:
+        case PRINTABLE_STRING:
+        case VIDEOTEX_STRING:
+        case T61_STRING:
+        case REAL:
+        case EMBEDDED_PDV:
+        case EXTERNAL:
+            throw new UnsupportedEncodingException("dont know real, embedded PDV or external");
+            
+        case UTF8_STRING: {
+            String s = pdu.getString();
+            byte [] data = s.getBytes("UTF-8");
+            out.write(data);
+            break;
+        }
+        
+        case OBJECT_DESCRIPTOR:
+        case IA5STRING:
+            String s = pdu.getString();
+            byte [] data = s.getBytes("ASCII");
+            out.write(data);
+            break;
+            
+            
+        case SEQUENCE:
+        case SET: {
+            PDU pdus[] = pdu.getChildren();
+            for ( PDU p : pdus ) {
+                write(out, p);
+            }
+        }
+            
+        
+        case UTCTIME:
+        case GENERALIZED_TIME:
+            Date date = pdu.getDate();
+            String ss= df.format(date);
+            byte d[] = ss.getBytes("ASCII");
+            out.write(d);
+            break;
+            
+        }
+    }
+    
+
+    private void putOid(OutputStream out, int i) throws IOException {
+        if (i > 127) {
+            putOid(out, i >> 7);
+            out.write(0x80 + (i & 0x7F));
+        } else
+            out.write(i & 0x7F);
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/asn1/PDU.java b/bundleplugin/src/main/java/aQute/libg/asn1/PDU.java
new file mode 100644
index 0000000..033928c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/asn1/PDU.java
@@ -0,0 +1,114 @@
+package aQute.libg.asn1;
+
+import java.util.*;
+
+public class PDU implements Types, Iterable<PDU> {
+    final int identifier;
+    final Object  payload;
+    byte data[] = new byte[100];
+
+
+    public PDU(int id, Object payload) {
+        identifier = id;
+        this.payload = payload;
+    }
+
+    public PDU(Date payload) {
+        identifier = UTCTIME;
+        this.payload = payload;
+    }
+
+    public PDU(int n) {
+        this(UNIVERSAL+INTEGER, n);
+    }
+
+    public PDU(boolean value) {
+        this(UNIVERSAL+BOOLEAN, value);
+    }
+
+    public PDU(String s) throws Exception {
+        this(UNIVERSAL+IA5STRING, s);
+    }
+    
+    public PDU(byte[] data) {
+        this(UNIVERSAL+OCTET_STRING, data);
+    }
+    
+    public PDU(BitSet bits) {
+        this(UNIVERSAL+BIT_STRING, bits);
+    }
+
+    public PDU(int top, int l1, int... remainder) {
+        identifier = UNIVERSAL+OBJECT_IDENTIFIER;
+        int[] ids = new int[remainder.length + 2];
+        ids[0] = top;
+        ids[1] = l1;
+        System.arraycopy(remainder, 0, ids, 2, remainder.length);
+        payload = ids;
+    }
+
+    public PDU(int tag, PDU... set) {
+        this(tag,(Object)set);
+    }
+
+    public PDU(PDU... set) {
+        this(SEQUENCE+CONSTRUCTED,set);
+    }
+
+
+    public int getTag() {
+        return identifier & TAGMASK;
+    }
+
+    int getClss() {
+        return identifier & CLASSMASK;
+    }
+
+    public boolean isConstructed() {
+        return (identifier & CONSTRUCTED) != 0;
+    }
+
+    public String getString() {
+        return (String) payload;
+    }
+
+    public Iterator<PDU> iterator() {
+        return Arrays.asList((PDU[]) payload).iterator();
+    }
+
+    
+    public int[] getOID() {
+        assert getTag() == OBJECT_IDENTIFIER;
+        return (int[]) payload;
+    }
+
+    public Boolean getBoolean() {
+        assert getTag() == BOOLEAN;
+        return (Boolean) payload;
+    }
+
+    public BitSet getBits() {
+        assert getTag() == BIT_STRING;
+        return (BitSet) payload;
+    }
+
+    public int getInt() {
+        assert getTag() == INTEGER || getTag() == ENUMERATED;
+        return (Integer) payload;
+    }
+
+    public byte[] getBytes() {
+        return (byte[]) payload;
+    }
+
+    public PDU[] getChildren() {
+        assert isConstructed();
+        return (PDU[]) payload;
+    }
+
+    public Date getDate() {
+        assert getTag() == UTCTIME || getTag() == GENERALIZED_TIME;
+        return (Date) payload;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/asn1/Types.java b/bundleplugin/src/main/java/aQute/libg/asn1/Types.java
new file mode 100644
index 0000000..630ed1c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/asn1/Types.java
@@ -0,0 +1,65 @@
+package aQute.libg.asn1;
+
+public interface Types {
+    int      UNIVERSAL         = 0x00000000;
+    int      APPLICATION       = 0x40000000;
+    int      CONTEXT           = 0x80000000;
+    int      PRIVATE           = 0xC0000000;
+    int      CLASSMASK         = 0xC0000000;
+    int      CONSTRUCTED       = 0x20000000;
+    int      TAGMASK           = 0x1FFFFFFF;
+
+    String [] CLASSES = {"U", "A", "C", "P"};
+    
+    // Payload Primitve
+    int      EOC               = 0;                                // null
+    // x
+    int      BOOLEAN           = 1;                                // Boolean
+    // x
+    int      INTEGER           = 2;                                // Long
+    // x
+    int      BIT_STRING        = 3;                                // byte
+    // [] -
+    int      OCTET_STRING      = 4;                                // byte
+    // [] -
+    int      NULL              = 5;                                // null
+    // x
+    int      OBJECT_IDENTIFIER = 6;                                // int[]
+    // x
+    int      OBJECT_DESCRIPTOR = 7;                                // 
+    int      EXTERNAL          = 8;                                //
+    int      REAL              = 9;                                // double
+    // x
+    int      ENUMERATED        = 10;                               // 
+    int      EMBEDDED_PDV      = 11;                               //
+    int      UTF8_STRING       = 12;                               // String
+    int      RELATIVE_OID      = 13;                               // 
+    int      SEQUENCE          = 16;                               // 
+    int      SET               = 17;
+    int      NUMERIC_STRING    = 18;                               // String
+    int      PRINTABLE_STRING  = 19;                               // String
+    int      T61_STRING        = 20;                               // String
+    int      VIDEOTEX_STRING   = 21;                               // String
+    int      IA5STRING         = 22;                               // String
+    int      UTCTIME           = 23;                               // Date
+    int      GENERALIZED_TIME  = 24;                               // Date
+    int      GRAPHIC_STRING    = 25;                               // String
+    int      VISIBLE_STRING    = 26;                               // String
+    int      GENERAL_STRING    = 27;                               // String
+    int      UNIVERSAL_STRING  = 28;                               // String
+    int      CHARACTER_STRING  = 29;                               // String
+    int      BMP_STRING        = 30;                               // byte[]
+
+    String[] TAGS              = { "EOC               ",
+            "BOOLEAN           ", "INTEGER           ", "BIT_STRING        ",
+            "OCTET_STRING      ", "NULL              ", "OBJECT_IDENTIFIER ",
+            "OBJECT_DESCRIPTOR ", "EXTERNAL          ", "REAL              ",
+            "ENUMERATED        ", "EMBEDDED_PDV      ", "UTF8_STRING       ",
+            "RELATIVE_OID      ", "?(14)             ", "?(15)             ",
+            "SEQUENCE          ", "SET               ", "NUMERIC_STRING    ",
+            "PRINTABLE_STRING  ", "T61_STRING        ", "VIDEOTEX_STRING   ",
+            "IA5STRING         ", "UTCTIME           ", "GENERALIZED_TIME  ",
+            "GRAPHIC_STRING    ", "VISIBLE_STRING    ", "GENERAL_STRING    ",
+            "UNIVERSAL_STRING  ", "CHARACTER_STRING  ", "BMP_STRING        ", };
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/asn1/algorithms b/bundleplugin/src/main/java/aQute/libg/asn1/algorithms
new file mode 100644
index 0000000..4fb6ab4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/asn1/algorithms
@@ -0,0 +1,22 @@
+---------------------------------------------------------------------------
+SignatureAlgorithm      digestAlgo        (I)  signatureAlgo (RFC 2630)
+                                          (II) digestEncrAlgo(PKCS#7)
+---------------------------------------------------------------------------
+(A) sha1WithRSA            1.3.14.3.2.26  (Ia)     1.2.840.113549.1.1.5
+   (1.2.840.113549.1.1.5)                 (Ib)     1.2.840.113549.1.1.1
+                                          (II)     1.2.840.113549.1.1.1
+
+
+(B) md5WithRSA           1.2.840.1x9.2.5  (Ia)     1.2.840.113549.1.1.4
+   (1.2.840.113549.1.1.4)                 (Ib)     1.2.840.113549.1.1.1
+                                          (II)     1.2.840.113549.1.1.1
+
+
+(C) ripeMD160WithRsa        1.3.36.3.2.1  (Ia)     1.3.36.3.3.1.2
+   (1.3.36.3.3.1.2)                       (Ib)     1.2.840.113549.1.1.1
+                                          (II)     1.2.840.113549.1.1.1
+
+
+(D) sha1WithDsa            1.3.14.3.2.26  (Ia)     1.2.840.10040.4.3
+   (1.2.840.10040.4.3)                    (Ib)     1.2.840.10040.4.1 (?)
+                                          (II)     1.2.840.10040.4.1
diff --git a/bundleplugin/src/main/java/aQute/libg/asn1/packageinfo b/bundleplugin/src/main/java/aQute/libg/asn1/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/asn1/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/cafs/CAFS.java b/bundleplugin/src/main/java/aQute/libg/cafs/CAFS.java
new file mode 100644
index 0000000..0bb8d7b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cafs/CAFS.java
@@ -0,0 +1,414 @@
+package aQute.libg.cafs;
+
+import static aQute.lib.io.IO.*;
+
+import java.io.*;
+import java.nio.channels.*;
+import java.security.*;
+import java.util.*;
+import java.util.concurrent.atomic.*;
+import java.util.zip.*;
+
+import aQute.lib.index.*;
+import aQute.libg.cryptography.*;
+
+/**
+ * CAFS implements a SHA-1 based file store. The basic idea is that every file
+ * in the universe has a unique SHA-1. Hard to believe but people smarter than
+ * me have come to that conclusion. This class maintains a compressed store of
+ * SHA-1 identified files. So if you have the SHA-1, you can get the contents.
+ * 
+ * This makes it easy to store a SHA-1 instead of the whole file or maintain a
+ * naming scheme. An added advantage is that it is always easy to verify you get
+ * the right stuff. The SHA-1 Content Addressable File Store is the core
+ * underlying idea in Git.
+ */
+public class CAFS implements Closeable, Iterable<SHA1> {
+	final static byte[]	CAFS			= "CAFS".getBytes();
+	final static byte[]	CAFE			= "CAFE".getBytes();
+	final static String	INDEXFILE		= "index.idx";
+	final static String	STOREFILE		= "store.cafs";
+	final static String	ALGORITHM		= "SHA-1";
+	final static int	KEYLENGTH		= 20;
+	final static int	HEADERLENGTH	= 4 // CAFS
+												+ 4 // flags
+												+ 4 // compressed length
+												+ 4 // uncompressed length
+												+ KEYLENGTH	// key
+												+ 2 // header checksum
+												;
+
+	final File			home;
+	Index				index;
+	RandomAccessFile	store;
+	FileChannel			channel;
+
+	/**
+	 * Constructor for a Content Addressable File Store
+	 * 
+	 * @param home
+	 * @param create
+	 * @throws Exception
+	 */
+	public CAFS(File home, boolean create) throws Exception {
+		this.home = home;
+		if (!home.isDirectory()) {
+			if (create) {
+				home.mkdirs();
+			} else
+				throw new IllegalArgumentException("CAFS requires a directory with create=false");
+		}
+
+		index = new Index(new File(home, INDEXFILE), KEYLENGTH);
+		store = new RandomAccessFile(new File(home, STOREFILE), "rw");
+		channel = store.getChannel();
+		if (store.length() < 0x100) {
+			if (create) {
+				store.write(CAFS);
+				for (int i = 1; i < 64; i++)
+					store.writeInt(0);
+				channel.force(true);
+			} else
+				throw new IllegalArgumentException("Invalid store file, length is too short "
+						+ store);
+			System.err.println(store.length());
+		}
+		store.seek(0);
+		if (!verifySignature(store, CAFS))
+			throw new IllegalArgumentException("Not a valid signature: CAFS at start of file");
+
+	}
+
+	/**
+	 * Store an input stream in the CAFS while calculating and returning the
+	 * SHA-1 code.
+	 * 
+	 * @param in
+	 *            The input stream to store.
+	 * @return The SHA-1 code.
+	 * @throws Exception
+	 *             if anything goes wrong
+	 */
+	public SHA1 write(InputStream in) throws Exception {
+
+		Deflater deflater = new Deflater();
+		MessageDigest md = MessageDigest.getInstance(ALGORITHM);
+		DigestInputStream din = new DigestInputStream(in, md);
+		ByteArrayOutputStream bout = new ByteArrayOutputStream();
+		DeflaterOutputStream dout = new DeflaterOutputStream(bout, deflater);
+		copy(din, dout);
+
+		synchronized (store) {
+			// First check if it already exists
+			SHA1 sha1 = new SHA1(md.digest());
+			
+			long search = index.search(sha1.digest());
+			if (search > 0)
+				return sha1;
+
+			byte[] compressed = bout.toByteArray();
+
+			// we need to append this file to our store,
+			// which requires a lock. However, we are in a race
+			// so others can get the lock between us getting
+			// the length and someone else getting the lock.
+			// So we must verify after we get the lock that the
+			// length was unchanged.
+			FileLock lock = null;
+			try {
+				long insertPoint;
+				int recordLength = compressed.length + HEADERLENGTH;
+
+				while (true) {
+					insertPoint = store.length();
+					lock = channel.lock(insertPoint, recordLength, false);
+
+					if (store.length() == insertPoint)
+						break;
+
+					// We got the wrong lock, someone else
+					// got in between reading the length
+					// and locking
+					lock.release();
+				}
+				int totalLength = deflater.getTotalIn();
+				store.seek(insertPoint);
+				update(sha1.digest(), compressed, totalLength);
+				index.insert(sha1.digest(), insertPoint);
+				return sha1;
+			} finally {
+				if (lock != null)
+					lock.release();
+			}
+		}
+	}
+
+	/**
+	 * Read the contents of a sha 1 key.
+	 * 
+	 * @param sha1
+	 *            The key
+	 * @return An Input Stream on the content or null of key not found
+	 * @throws Exception
+	 */
+	public InputStream read(final SHA1 sha1) throws Exception {
+		synchronized (store) {
+			long offset = index.search(sha1.digest());
+			if (offset < 0)
+				return null;
+
+			byte[] readSha1;
+			byte[] buffer;
+			store.seek(offset);
+			if (!verifySignature(store, CAFE))
+				throw new IllegalArgumentException("No signature");
+
+			int flags =store.readInt();
+			int compressedLength = store.readInt();
+			int uncompressedLength = store.readInt();
+			readSha1 = new byte[KEYLENGTH];
+			store.read(readSha1);
+			SHA1 rsha1 = new SHA1(readSha1);
+			
+			if (!sha1.equals(rsha1))
+				throw new IOException("SHA1 read and asked mismatch: " + sha1 + " " + rsha1);
+
+			short crc = store.readShort(); // Read CRC
+			if ( crc != checksum(flags,compressedLength, uncompressedLength, readSha1))
+				throw new IllegalArgumentException("Invalid header checksum: " + sha1);
+			
+			buffer = new byte[compressedLength];
+			store.readFully(buffer);
+			return getSha1Stream(sha1, buffer, uncompressedLength);
+		}
+	}
+
+	public boolean exists(byte[] sha1) throws Exception {
+		return index.search(sha1) >= 0;
+	}
+
+	public void reindex() throws Exception {
+		long length;
+		synchronized (store) {
+			length = store.length();
+			if (length < 0x100)
+				throw new IllegalArgumentException(
+						"Store file is too small, need to be at least 256 bytes: " + store);
+		}
+
+		RandomAccessFile in = new RandomAccessFile(new File(home, STOREFILE), "r");
+		try {
+			byte[] signature = new byte[4];
+			in.readFully(signature);
+			if (!Arrays.equals(CAFS, signature))
+				throw new IllegalArgumentException("Store file does not start with CAFS: " + in);
+
+			in.seek(0x100);
+			File ixf = new File(home, "index.new");
+			Index index = new Index(ixf, KEYLENGTH);
+
+			while (in.getFilePointer() < length) {
+				long entry = in.getFilePointer();
+				SHA1 sha1 = verifyEntry(in);
+				index.insert(sha1.digest(), entry);
+			}
+
+			synchronized (store) {
+				index.close();
+				File indexFile = new File(home, INDEXFILE);
+				ixf.renameTo(indexFile);
+				this.index = new Index(indexFile, KEYLENGTH);
+			}
+		} finally {
+			in.close();
+		}
+	}
+
+	public void close() throws IOException {
+		synchronized (store) {
+			try {
+				store.close();
+			} finally {
+				index.close();
+			}
+		}
+	}
+
+	private SHA1 verifyEntry(RandomAccessFile in) throws IOException, NoSuchAlgorithmException {
+		byte[] signature = new byte[4];
+		in.readFully(signature);
+		if (!Arrays.equals(CAFE, signature))
+			throw new IllegalArgumentException("File is corrupted: " + in);
+
+		/* int flags = */in.readInt();
+		int compressedSize = in.readInt();
+		int uncompressedSize = in.readInt();
+		byte[] key = new byte[KEYLENGTH];
+		in.readFully(key);
+		SHA1 sha1 = new SHA1(key);
+		
+		byte[] buffer = new byte[compressedSize];
+		in.readFully(buffer);
+
+		InputStream xin = getSha1Stream(sha1, buffer, uncompressedSize);
+		xin.skip(uncompressedSize);
+		xin.close();
+		return sha1;
+	}
+
+	private boolean verifySignature(DataInput din, byte[] org) throws IOException {
+		byte[] read = new byte[org.length];
+		din.readFully(read);
+		return Arrays.equals(read, org);
+	}
+
+	private InputStream getSha1Stream(final SHA1 sha1, byte[] buffer, final int total)
+			throws NoSuchAlgorithmException {
+		ByteArrayInputStream in = new ByteArrayInputStream(buffer);
+		InflaterInputStream iin = new InflaterInputStream(in) {
+			int count = 0;
+			final MessageDigest digestx = MessageDigest.getInstance(ALGORITHM);
+			final AtomicBoolean calculated = new AtomicBoolean();
+			
+			@Override public int read(byte[] data, int offset, int length) throws IOException {
+				int size = super.read(data, offset, length);
+				if (size <= 0)
+					eof();
+				else {
+					count+=size;
+					this.digestx.update(data, offset, size);
+				}
+				return size;
+			}
+
+			public int read() throws IOException {
+				int c = super.read();
+				if (c < 0)
+					eof();
+				else {
+					count++;
+					this.digestx.update((byte) c);
+				}
+				return c;
+			}
+
+			void eof() throws IOException {
+				if ( calculated.getAndSet(true))
+					return;
+				
+				if ( count != total )
+					throw new IOException("Counts do not match. Expected to read: " + total + " Actually read: " + count);
+				
+				SHA1 calculatedSha1 = new SHA1(digestx.digest());
+				if (!sha1.equals(calculatedSha1))
+					throw ( new IOException("SHA1 caclulated and asked mismatch, asked: "
+							+ sha1 + ", \nfound: " +calculatedSha1));
+			}
+
+			public void close() throws IOException {
+				eof();
+				super.close();
+			}
+		};
+		return iin;
+	}
+
+	/**
+	 * Update a record in the store, assuming the store is at the right
+	 * position.
+	 * 
+	 * @param sha1
+	 *            The checksum
+	 * @param compressed
+	 *            The compressed length
+	 * @param totalLength
+	 *            The uncompressed length
+	 * @throws IOException
+	 *             The exception
+	 */
+	private void update(byte[] sha1, byte[] compressed, int totalLength) throws IOException {
+		//System.err.println("pos: " + store.getFilePointer());
+		store.write(CAFE); // 00-03 Signature
+		store.writeInt(0); // 04-07 Flags for the future
+		store.writeInt(compressed.length); // 08-11 Length deflated data
+		store.writeInt(totalLength); // 12-15 Length
+		store.write(sha1); // 16-35
+		store.writeShort( checksum(0,compressed.length, totalLength, sha1));
+		store.write(compressed);
+		channel.force(false);
+	}
+
+	
+	
+	private short checksum(int flags, int compressedLength, int totalLength, byte[] sha1) {
+		CRC32 crc = new CRC32();
+		crc.update(flags);
+		crc.update(flags>>8);
+		crc.update(flags>>16);
+		crc.update(flags>>24);
+		crc.update(compressedLength);
+		crc.update(compressedLength>>8);
+		crc.update(compressedLength>>16);
+		crc.update(compressedLength>>24);
+		crc.update(totalLength);
+		crc.update(totalLength>>8);
+		crc.update(totalLength>>16);
+		crc.update(totalLength>>24);
+		crc.update(sha1);
+		return (short) crc.getValue();
+	}
+
+	public Iterator<SHA1> iterator() {
+		
+		return new Iterator<SHA1>() {
+			long position = 0x100;
+			
+			public boolean hasNext() {
+				synchronized(store) {
+					try {
+						return position < store.length();
+					} catch (IOException e) {
+						throw new RuntimeException(e);
+					}
+				}
+			}
+
+			public SHA1 next() {
+				synchronized(store) {
+					try {
+						store.seek(position);
+						byte [] signature = new byte[4];
+						store.readFully(signature);
+						if ( !Arrays.equals(CAFE, signature))
+							throw new IllegalArgumentException("No signature");
+
+						int flags = store.readInt();
+						int compressedLength = store.readInt();
+						int totalLength = store.readInt();
+						byte []sha1 = new byte[KEYLENGTH];
+						store.readFully(sha1);
+						short crc = store.readShort();
+						if ( crc != checksum(flags,compressedLength, totalLength, sha1))
+							throw new IllegalArgumentException("Header checksum fails");
+						
+						position += HEADERLENGTH + compressedLength;
+						return new SHA1(sha1);
+					} catch (IOException e) {
+						throw new RuntimeException(e);
+					}				
+				}
+			}
+
+			public void remove() {
+				throw new UnsupportedOperationException("Remvoe not supported, CAFS is write once");
+			}			
+		};
+	}
+
+	
+	public boolean isEmpty() throws IOException {
+		synchronized(store) {
+			return store.getFilePointer() <= 256;
+		}
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/cafs/packageinfo b/bundleplugin/src/main/java/aQute/libg/cafs/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cafs/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/classdump/ClassDumper.java b/bundleplugin/src/main/java/aQute/libg/classdump/ClassDumper.java
new file mode 100755
index 0000000..e45cd39
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/classdump/ClassDumper.java
@@ -0,0 +1,698 @@
+/* Copyright 2006 aQute SARL 
+ * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
+package aQute.libg.classdump;
+
+import java.io.*;
+import java.lang.reflect.*;
+
+public class ClassDumper {
+    /**
+     * <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 class Assoc {
+        Assoc(byte tag, int a, int b) {
+            this.tag = tag;
+            this.a = a;
+            this.b = b;
+        }
+
+        byte tag;
+        int  a;
+        int  b;
+
+    }
+
+    final String        path;
+    final static String NUM_COLUMN = "%-30s %d\n";
+    final static String HEX_COLUMN = "%-30s %x\n";
+    final static String STR_COLUMN = "%-30s %s\n";
+
+    PrintStream         ps         = System.err;
+    Object[]            pool;
+    InputStream         in;
+
+    public ClassDumper(String path) throws Exception {
+        this(path, new FileInputStream(new File(path)));
+    }
+
+    public ClassDumper(String path, InputStream in) throws IOException {
+        this.path = path;
+        this.in = in;
+    }
+
+    public void dump(PrintStream ps) throws Exception {
+        if (ps != null)
+            this.ps = ps;
+        DataInputStream din = new DataInputStream(in);
+        parseClassFile(din);
+        din.close();
+    }
+
+    void parseClassFile(DataInputStream in) throws IOException {
+        int magic = in.readInt();
+        if (magic != 0xCAFEBABE)
+            throw new IOException("Not a valid class file (no CAFEBABE header)");
+
+        ps.printf(HEX_COLUMN, "magic", magic);
+        int minor = in.readUnsignedShort(); // minor version
+        int major = in.readUnsignedShort(); // major version
+        ps.printf(STR_COLUMN, "version", "" + major + "." + minor);
+        int pool_size = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, "pool size", pool_size);
+        pool = new Object[pool_size];
+
+        process: for (int poolIndex = 1; poolIndex < pool_size; poolIndex++) {
+            byte tag = in.readByte();
+
+            switch (tag) {
+            case 0:
+                ps.printf("%30d tag (0)\n", poolIndex);
+                break process;
+
+            case 1:
+                String name = in.readUTF();
+                pool[poolIndex] = name;
+                ps.printf("%30d tag(1) utf8 '%s'\n", poolIndex, name);
+                break;
+
+            case 2:
+                throw new IOException("Invalid tag " + tag);
+
+            case 3:
+                int i = in.readInt();
+                pool[poolIndex] = Integer.valueOf(i);
+                ps.printf("%30d tag(3) int %s\n", poolIndex, i);
+                break;
+
+            case 4:
+                float f = in.readFloat();
+                pool[poolIndex] = new Float(f);
+                ps.printf("%30d tag(4) float %s\n", poolIndex, f);
+                break;
+
+            // For some insane optimization reason are
+            // the long and the double two entries in the
+            // constant pool. See 4.4.5
+            case 5:
+                long l = in.readLong();
+                pool[poolIndex] = Long.valueOf(l);
+                ps.printf("%30d tag(5) long %s\n", poolIndex, l);
+                poolIndex++;
+                break;
+
+            case 6:
+                double d = in.readDouble();
+                pool[poolIndex] = new Double(d);
+                ps.printf("%30d tag(6) double %s\n", poolIndex, d);
+                poolIndex++;
+                break;
+
+            case 7:
+                int class_index = in.readUnsignedShort();
+                pool[poolIndex] = Integer.valueOf(class_index);
+                ps.printf("%30d tag(7) constant classs %d\n", poolIndex,
+                        class_index);
+                break;
+
+            case 8:
+                int string_index = in.readUnsignedShort();
+                pool[poolIndex] = Integer.valueOf(string_index);
+                ps.printf("%30d tag(8) constant string %d\n", poolIndex,
+                        string_index);
+                break;
+
+            case 9: // Field ref
+                class_index = in.readUnsignedShort();
+                int name_and_type_index = in.readUnsignedShort();
+                pool[poolIndex] = new Assoc((byte) 9, class_index,
+                        name_and_type_index);
+                ps.printf("%30d tag(9) field ref %d/%d\n", poolIndex,
+                        class_index, name_and_type_index);
+                break;
+
+            case 10: // Method ref
+                class_index = in.readUnsignedShort();
+                name_and_type_index = in.readUnsignedShort();
+                pool[poolIndex] = new Assoc((byte) 10, class_index,
+                        name_and_type_index);
+                ps.printf("%30d tag(10) method ref %d/%d\n", poolIndex,
+                        class_index, name_and_type_index);
+                break;
+
+            case 11: // Interface and Method ref
+                class_index = in.readUnsignedShort();
+                name_and_type_index = in.readUnsignedShort();
+                pool[poolIndex] = new Assoc((byte) 11, class_index,
+                        name_and_type_index);
+                ps.printf("%30d tag(11) interface and method ref %d/%d\n",
+                        poolIndex, class_index, name_and_type_index);
+                break;
+
+            // Name and Type
+            case 12:
+                int name_index = in.readUnsignedShort();
+                int descriptor_index = in.readUnsignedShort();
+                pool[poolIndex] = new Assoc(tag, name_index, descriptor_index);
+                ps.printf("%30d tag(12) name and type %d/%d\n", poolIndex,
+                        name_index, descriptor_index);
+                break;
+
+            default:
+                throw new IllegalArgumentException("Unknown tag: " + tag);
+            }
+        }
+
+        int access = in.readUnsignedShort(); // access
+        printAccess(access);
+        int this_class = in.readUnsignedShort();
+        int super_class = in.readUnsignedShort();
+        ps.printf("%-30s %x %s(#%d)\n", "this_class", access, pool[this_class],
+                this_class);
+        ps.printf("%-30s %s(#%d)\n", "super_class", pool[super_class],
+                super_class);
+
+        int interfaces_count = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, "interface count", interfaces_count);
+        for (int i = 0; i < interfaces_count; i++) {
+            int interface_index = in.readUnsignedShort();
+            ps.printf("%-30s interface %s(#%d)", "interface count",
+                    pool[interface_index], interfaces_count);
+        }
+
+        int field_count = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, "field count", field_count);
+        for (int i = 0; i < field_count; i++) {
+            access = in.readUnsignedShort(); // access
+            printAccess(access);
+            int name_index = in.readUnsignedShort();
+            int descriptor_index = in.readUnsignedShort();
+            ps.printf("%-30s %x %s(#%d) %s(#%d)\n", "field def", access,
+                    pool[name_index], name_index, pool[descriptor_index],
+                    descriptor_index);
+            doAttributes(in, "  ");
+        }
+
+        int method_count = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, "method count", method_count);
+        for (int i = 0; i < method_count; i++) {
+            int access_flags = in.readUnsignedShort();
+            printAccess(access_flags);
+            int name_index = in.readUnsignedShort();
+            int descriptor_index = in.readUnsignedShort();
+            ps.printf("%-30s %x %s(#%d) %s(#%d)\n", "method def", access_flags,
+                    pool[name_index], name_index, pool[descriptor_index],
+                    descriptor_index);
+            doAttributes(in, "  ");
+        }
+
+        doAttributes(in, "");
+        if (in.read() >= 0)
+            ps.printf("Extra bytes follow ...");
+    }
+
+    /**
+     * Called for each attribute in the class, field, or method.
+     * 
+     * @param in
+     *            The stream
+     * @throws IOException
+     */
+    private void doAttributes(DataInputStream in, String indent)
+            throws IOException {
+        int attribute_count = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, indent + "attribute count", attribute_count);
+        for (int j = 0; j < attribute_count; j++) {
+            doAttribute(in, indent + j + ": ");
+        }
+    }
+
+    /**
+     * Process a single attribute, if not recognized, skip it.
+     * 
+     * @param in
+     *            the data stream
+     * @throws IOException
+     */
+    private void doAttribute(DataInputStream in, String indent)
+            throws IOException {
+        int attribute_name_index = in.readUnsignedShort();
+        long attribute_length = in.readInt();
+        attribute_length &= 0xFFFF;
+        String attributeName = (String) pool[attribute_name_index];
+        ps.printf("%-30s %s(#%d)\n", indent + "attribute", attributeName,
+                attribute_name_index);
+        if ("RuntimeVisibleAnnotations".equals(attributeName))
+            doAnnotations(in, indent);
+        else if ("SourceFile".equals(attributeName))
+            doSourceFile(in, indent);
+        else if ("Code".equals(attributeName))
+            doCode(in, indent);
+        else if ("LineNumberTable".equals(attributeName))
+            doLineNumberTable(in, indent);
+        else if ("LocalVariableTable".equals(attributeName))
+            doLocalVariableTable(in, indent);
+        else if ("InnerClasses".equals(attributeName))
+            doInnerClasses(in, indent);
+        else if ("Exceptions".equals(attributeName))
+            doExceptions(in, indent);
+        else if ("EnclosingMethod".equals(attributeName))
+            doEnclosingMethod(in, indent);
+        else if ("Signature".equals(attributeName))
+            doSignature(in, indent);
+        else if ("Synthetic".equals(attributeName))
+            ; // Is empty!
+        else if ("Deprecated".equals(attributeName))
+            ; // Is Empty
+        else {
+            ps.printf("%-30s %d\n", indent + "Unknown attribute, skipping",
+                    attribute_length);
+            if (attribute_length > 0x7FFFFFFF) {
+                throw new IllegalArgumentException("Attribute > 2Gb");
+            }
+            byte buffer[] = new byte[(int) attribute_length];
+            in.readFully(buffer);
+            printHex(buffer);
+        }
+    }
+
+    /**
+     * <pre>
+     * Signature_attribute {
+     * 	u2 attribute_name_index;
+     * 	u4 attribute_length;
+     * 	u2 signature_index;
+     * 	}
+     * </pre>
+     * 
+     * @param in
+     * @param indent
+     */
+    void doSignature(DataInputStream in, String indent) throws IOException {
+        int signature_index = in.readUnsignedShort();
+        ps.printf("%-30s %s(#%d)\n", indent + "signature",
+                pool[signature_index], signature_index);
+    }
+
+    /**
+     * <pre>
+     * EnclosingMethod_attribute {
+     * 	u2 attribute_name_index;
+     * 	u4 attribute_length;
+     * 	u2 class_index
+     * 	u2 method_index;
+     * 	}
+     * 	
+     * </pre>
+     */
+    void doEnclosingMethod(DataInputStream in, String indent)
+            throws IOException {
+        int class_index = in.readUnsignedShort();
+        int method_index = in.readUnsignedShort();
+        ps.printf("%-30s %s(#%d/c) %s\n", //
+        		indent + "enclosing method", //
+                pool[((Integer) pool[class_index]).intValue()], //
+                class_index, //
+                (method_index == 0 ? "<>" : pool[method_index]));
+    }
+
+    /**
+     * <pre>
+     *  Exceptions_attribute {
+     * 		u2 attribute_name_index;
+     * 		u4 attribute_length;
+     * 		u2 number_of_exceptions;
+     * 		u2 exception_index_table[number_of_exceptions];
+     * 	}
+     * </pre>
+     * 
+     * @param in
+     * @param indent
+     */
+    private void doExceptions(DataInputStream in, String indent)
+            throws IOException {
+        int number_of_exceptions = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, indent + "number of exceptions",
+                number_of_exceptions);
+        StringBuilder sb = new StringBuilder();
+        String del = "";
+        for (int i = 0; i < number_of_exceptions; i++) {
+            int exception_index_table = in.readUnsignedShort();
+            sb.append(del);
+            sb.append(pool[((Integer) pool[exception_index_table])]);
+            sb.append("(#");
+            sb.append(exception_index_table);
+            sb.append("/c)");
+            del = ", ";
+        }
+        ps.printf("%-30s %d: %s\n", indent + "exceptions",
+                number_of_exceptions, sb);
+    }
+
+    /**
+     * <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, String indent) throws IOException {
+        int max_stack = in.readUnsignedShort();
+        int max_locals = in.readUnsignedShort();
+        int code_length = in.readInt();
+        ps.printf(NUM_COLUMN, indent + "max_stack", max_stack);
+        ps.printf(NUM_COLUMN, indent + "max_locals", max_locals);
+        ps.printf(NUM_COLUMN, indent + "code_length", code_length);
+        byte code[] = new byte[code_length];
+        in.readFully(code);
+        printHex(code);
+        int exception_table_length = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, indent + "exception_table_length",
+                exception_table_length);
+
+        for (int i = 0; i < exception_table_length; i++) {
+            int start_pc = in.readUnsignedShort();
+            int end_pc = in.readUnsignedShort();
+            int handler_pc = in.readUnsignedShort();
+            int catch_type = in.readUnsignedShort();
+            ps.printf("%-30s %d/%d/%d/%d\n", indent + "exception_table",
+                    start_pc, end_pc, handler_pc, catch_type);
+        }
+        doAttributes(in, indent + "  ");
+    }
+
+    /**
+     * We must find Class.forName references ...
+     * 
+     * @param code
+     */
+    protected void printHex(byte[] code) {
+        int index = 0;
+        while (index < code.length) {
+            StringBuilder sb = new StringBuilder();
+            for (int i = 0; i < 16 && index < code.length; i++) {
+                String s = Integer.toHexString((0xFF & code[index++]))
+                        .toUpperCase();
+                if (s.length() == 1)
+                    sb.append("0");
+                sb.append(s);
+                sb.append(" ");
+            }
+            ps.printf(STR_COLUMN, "", sb.toString());
+        }
+    }
+
+    private void doSourceFile(DataInputStream in, String indent)
+            throws IOException {
+        int sourcefile_index = in.readUnsignedShort();
+        ps.printf("%-30s %s(#%d)\n", indent + "Source file",
+                pool[sourcefile_index], sourcefile_index);
+    }
+
+    private void doAnnotations(DataInputStream in, String indent)
+            throws IOException {
+        int num_annotations = in.readUnsignedShort(); // # of annotations
+        ps
+                .printf(NUM_COLUMN, indent + "Number of annotations",
+                        num_annotations);
+        for (int a = 0; a < num_annotations; a++) {
+            doAnnotation(in, indent);
+        }
+    }
+
+    private void doAnnotation(DataInputStream in, String indent)
+            throws IOException {
+        int type_index = in.readUnsignedShort();
+        ps.printf("%-30s %s(#%d)", indent + "type", pool[type_index],
+                type_index);
+        int num_element_value_pairs = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, indent + "num_element_value_pairs",
+                num_element_value_pairs);
+        for (int v = 0; v < num_element_value_pairs; v++) {
+            int element_name_index = in.readUnsignedShort();
+            ps.printf(NUM_COLUMN, indent + "element_name_index",
+                    element_name_index);
+            doElementValue(in, indent);
+        }
+    }
+
+    private void doElementValue(DataInputStream in, String indent)
+            throws IOException {
+        int tag = in.readUnsignedByte();
+        switch (tag) {
+        case 'B':
+        case 'C':
+        case 'D':
+        case 'F':
+        case 'I':
+        case 'J':
+        case 'S':
+        case 'Z':
+        case 's':
+            int const_value_index = in.readUnsignedShort();
+            ps.printf("%-30s %c %s(#%d)\n", indent + "element value", tag,
+                    pool[const_value_index], const_value_index);
+            break;
+
+        case 'e':
+            int type_name_index = in.readUnsignedShort();
+            int const_name_index = in.readUnsignedShort();
+            ps.printf("%-30s %c %s(#%d) %s(#%d)\n", indent + "type+const", tag,
+                    pool[type_name_index], type_name_index,
+                    pool[const_name_index], const_name_index);
+            break;
+
+        case 'c':
+            int class_info_index = in.readUnsignedShort();
+            ps.printf("%-30s %c %s(#%d)\n", indent + "element value", tag,
+                    pool[class_info_index], class_info_index);
+            break;
+
+        case '@':
+            ps.printf("%-30s %c\n", indent + "sub annotation", tag);
+            doAnnotation(in, indent);
+            break;
+
+        case '[':
+            int num_values = in.readUnsignedShort();
+            ps.printf("%-30s %c num_values=%d\n", indent + "sub element value",
+                    tag, num_values);
+            for (int i = 0; i < num_values; i++) {
+                doElementValue(in, indent);
+            }
+            break;
+
+        default:
+            throw new IllegalArgumentException(
+                    "Invalid value for Annotation ElementValue tag " + tag);
+        }
+    }
+
+    /**
+     * <pre>
+     *  LineNumberTable_attribute {
+     * 		u2 attribute_name_index;
+     * 		u4 attribute_length;
+     * 		u2 line_number_table_length;
+     * 		{  u2 start_pc;	     
+     * 		   u2 line_number;	     
+     * 		} line_number_table[line_number_table_length];
+     * 	}
+     * 	
+     * </pre>
+     */
+    void doLineNumberTable(DataInputStream in, String indent)
+            throws IOException {
+        int line_number_table_length = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, indent + "line number table length",
+                line_number_table_length);
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < line_number_table_length; i++) {
+            int start_pc = in.readUnsignedShort();
+            int line_number = in.readUnsignedShort();
+            sb.append(start_pc);
+            sb.append("/");
+            sb.append(line_number);
+            sb.append(" ");
+        }
+        ps.printf("%-30s %d: %s\n", indent + "line number table",
+                line_number_table_length, sb);
+    }
+
+    /**
+     * 
+     * <pre>
+     * 	LocalVariableTable_attribute {
+     * 		u2 attribute_name_index;
+     * 		u4 attribute_length;
+     * 		u2 local_variable_table_length;
+     * 		{  u2 start_pc;
+     * 		    u2 length;
+     * 		    u2 name_index;
+     * 		    u2 descriptor_index;
+     * 		    u2 index;
+     * 		} local_variable_table[local_variable_table_length];
+     * 	}	
+     * </pre>
+     */
+
+    void doLocalVariableTable(DataInputStream in, String indent)
+            throws IOException {
+        int local_variable_table_length = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, indent + "local variable table length",
+                local_variable_table_length);
+        for (int i = 0; i < local_variable_table_length; i++) {
+            int start_pc = in.readUnsignedShort();
+            int length = in.readUnsignedShort();
+            int name_index = in.readUnsignedShort();
+            int descriptor_index = in.readUnsignedShort();
+            int index = in.readUnsignedShort();
+            ps.printf("%-30s %d: %d/%d %s(#%d) %s(#%d)\n", indent, index,
+                    start_pc, length, pool[name_index], name_index,
+                    pool[descriptor_index], descriptor_index);
+        }
+    }
+
+    /**
+     * <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>
+     * 
+     */
+    void doInnerClasses(DataInputStream in, String indent) throws IOException {
+        int number_of_classes = in.readUnsignedShort();
+        ps.printf(NUM_COLUMN, indent + "number of classes", number_of_classes);
+        for (int i = 0; i < number_of_classes; i++) {
+            int inner_class_info_index = in.readUnsignedShort();
+            int outer_class_info_index = in.readUnsignedShort();
+            int inner_name_index = in.readUnsignedShort();
+            int inner_class_access_flags = in.readUnsignedShort();
+            printAccess(inner_class_access_flags);
+
+            String iname = "<>";
+            String oname = iname;
+
+            if (inner_class_info_index != 0)
+                iname = (String) pool[((Integer) pool[inner_class_info_index])
+                        .intValue()];
+            if (outer_class_info_index != 0)
+                oname = (String) pool[((Integer) pool[outer_class_info_index])
+                        .intValue()];
+
+            ps.printf("%-30s %d: %x %s(#%d/c) %s(#%d/c) %s(#%d) \n", indent, i,
+                    inner_class_access_flags, iname, inner_class_info_index,
+                    oname, outer_class_info_index, pool[inner_name_index],
+                    inner_name_index);
+        }
+    }
+
+
+    void printClassAccess(int mod) {
+        ps.printf("%-30s", "Class Access");
+        if ((ACC_PUBLIC&mod)!= 0)
+            ps.print(" public");
+        if ((ACC_FINAL&mod)!= 0)
+            ps.print(" final");
+        if ((ACC_SUPER&mod)!= 0)
+            ps.print(" super");
+        if ((ACC_INTERFACE&mod)!= 0)
+            ps.print(" interface");
+        if ((ACC_ABSTRACT&mod)!= 0)
+            ps.print(" abstract");
+
+        ps.println();
+    }
+
+    void printAccess(int mod) {
+        ps.printf("%-30s", "Access");
+        if (Modifier.isStatic(mod))
+            ps.print(" static");
+        if (Modifier.isAbstract(mod))
+            ps.print(" abstract");
+        if (Modifier.isPublic(mod))
+            ps.print(" public");
+        if (Modifier.isFinal(mod))
+            ps.print(" final");
+        if (Modifier.isInterface(mod))
+            ps.print(" interface");
+        if (Modifier.isNative(mod))
+            ps.print(" native");
+        if (Modifier.isPrivate(mod))
+            ps.print(" private");
+        if (Modifier.isProtected(mod))
+            ps.print(" protected");
+        if (Modifier.isStrict(mod))
+            ps.print(" strict");
+        if (Modifier.isSynchronized(mod))
+            ps.print(" synchronized");
+        if (Modifier.isTransient(mod))
+            ps.print(" transient");
+        if (Modifier.isVolatile(mod))
+            ps.print(" volatile");
+
+        ps.println();
+    }
+
+    public static void main(String args[]) throws Exception {
+        if (args.length == 0) {
+            System.err.println("clsd <class file>+");
+        }
+        for (int i = 0; i < args.length; i++) {
+            File f = new File(args[i]);
+            if (!f.isFile())
+                System.err.println("File does not exist or is directory " + f);
+            else {
+                ClassDumper cd = new ClassDumper(args[i]);
+                cd.dump(null);
+            }
+        }
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/classdump/packageinfo b/bundleplugin/src/main/java/aQute/libg/classdump/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/classdump/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/classloaders/URLClassLoaderWrapper.java b/bundleplugin/src/main/java/aQute/libg/classloaders/URLClassLoaderWrapper.java
new file mode 100644
index 0000000..10ddca5
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/classloaders/URLClassLoaderWrapper.java
@@ -0,0 +1,27 @@
+package aQute.libg.classloaders;
+
+import java.lang.reflect.*;
+import java.net.*;
+
+public class URLClassLoaderWrapper {
+	final URLClassLoader loader;
+	final Method addURL;
+	
+	public URLClassLoaderWrapper(ClassLoader loader) throws Exception {
+		this.loader = (URLClassLoader) loader;
+		addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
+		addURL.setAccessible(true);
+	}
+	
+	public void addURL(URL url) throws Exception  {
+		try {
+		addURL.invoke(loader, url);
+		} catch( InvocationTargetException ite) {
+			throw (Exception) ite.getTargetException();
+		}
+	}
+	
+	public Class<?> loadClass(String name) throws Exception {
+		return loader.loadClass(name);
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/classloaders/packageinfo b/bundleplugin/src/main/java/aQute/libg/classloaders/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/classloaders/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bundleplugin/src/main/java/aQute/libg/clauses/Clause.java b/bundleplugin/src/main/java/aQute/libg/clauses/Clause.java
new file mode 100755
index 0000000..bab9fee
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/clauses/Clause.java
@@ -0,0 +1,8 @@
+package aQute.libg.clauses;
+
+import java.util.*;
+
+public class Clause extends LinkedHashMap<String,String> {
+	private static final long	serialVersionUID	= 1L;
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/clauses/Clauses.java b/bundleplugin/src/main/java/aQute/libg/clauses/Clauses.java
new file mode 100755
index 0000000..12eba4f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/clauses/Clauses.java
@@ -0,0 +1,65 @@
+package aQute.libg.clauses;
+
+import java.util.*;
+
+import aQute.libg.log.*;
+import aQute.libg.qtokens.*;
+
+public class Clauses extends LinkedHashMap<String,Map<String,String>>{
+	private static final long	serialVersionUID	= 1L;
+	
+	/**
+	 * 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
+	 * @return
+	 * @throws MojoExecutionException
+	 */
+	static public Clauses parse(String value, Logger logger) {
+		if (value == null || value.trim().length() == 0)
+			return new Clauses();
+
+		Clauses result = new Clauses();
+		QuotedTokenizer qt = new QuotedTokenizer(value, ";=,");
+		char del;
+		do {
+			boolean hadAttribute = false;
+			Clause clause = new Clause();
+			List<String> aliases = new ArrayList<String>();
+			aliases.add(qt.nextToken());
+			del = qt.getSeparator();
+			while (del == ';') {
+				String adname = qt.nextToken();
+				if ((del = qt.getSeparator()) != '=') {
+					if (hadAttribute)
+						throw new IllegalArgumentException(
+								"Header contains name field after attribute or directive: "
+										+ adname + " from " + value);
+					aliases.add(adname);
+				} else {
+					String advalue = qt.nextToken();
+					clause.put(adname, advalue);
+					del = qt.getSeparator();
+					hadAttribute = true;
+				}
+			}
+			for (Iterator<String> i = aliases.iterator(); i.hasNext();) {
+				String packageName = i.next();
+				if (result.containsKey(packageName)) {
+					if (logger != null)
+						logger
+								.warning("Duplicate package name in header: "
+										+ packageName
+										+ ". Multiple package names in one clause not supported in Bnd.");
+				} else
+					result.put(packageName, clause);
+			}
+		} while (del == ',');
+		return result;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/clauses/Selector.java b/bundleplugin/src/main/java/aQute/libg/clauses/Selector.java
new file mode 100755
index 0000000..eaa806c
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/clauses/Selector.java
@@ -0,0 +1,129 @@
+/*
+ * $Header: /cvsroot/bnd/aQute.libg/src/aQute/libg/clauses/Selector.java,v 1.1 2009/01/19 14:17:42 pkriens Exp $
+ * 
+ * Copyright (c) OSGi Alliance (2006). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package aQute.libg.clauses;
+
+import java.util.*;
+import java.util.regex.*;
+
+public class Selector {
+	Pattern	pattern;
+	String	instruction;
+	boolean	negated;
+	Clause	clause;
+
+	public Selector(String instruction, boolean negated) {
+		this.instruction = instruction;
+		this.negated = negated;
+	}
+
+	public boolean matches(String value) {
+		if (pattern == null) {
+			pattern = Pattern.compile(instruction);
+		}
+		Matcher m = pattern.matcher(value);
+		return m.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 Selector getPattern(String string) {
+		boolean negated = false;
+		if (string.startsWith("!")) {
+			negated = true;
+			string = string.substring(1);
+		}
+		StringBuilder sb = new StringBuilder();
+		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 Selector(sb.toString(), negated);
+	}
+
+	public String toString() {
+		return getPattern();
+	}
+
+	public Clause getClause() {
+		return clause;
+	}
+
+	public void setClause(Clause clause) {
+		this.clause = clause;
+	}
+
+	public static List<Selector> getInstructions(Clauses clauses) {
+		List<Selector> result = new ArrayList<Selector>();
+		for (Map.Entry<String, Map<String, String>> entry : clauses.entrySet()) {
+			Selector instruction = getPattern(entry.getKey());
+			result.add(instruction);
+		}
+		return result;
+	}
+	
+	public static <T> List<T> select(Collection<T> domain,
+			List<Selector> instructions) {
+		List<T> result = new ArrayList<T>();
+		Iterator<T> iterator = domain.iterator(); 
+		value: while (iterator.hasNext()) {
+			T value = iterator.next();
+			for (Selector instruction : instructions) {
+				if (instruction.matches(value.toString())) {
+					if (!instruction.isNegated())
+						result.add(value);
+					continue value;
+				}
+			}
+		}
+		return result;
+	}
+	
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/clauses/packageinfo b/bundleplugin/src/main/java/aQute/libg/clauses/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/clauses/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..0a79a58
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/command/Command.java
@@ -0,0 +1,259 @@
+package aQute.libg.command;
+
+import java.io.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.concurrent.*;
+
+import aQute.libg.reporter.*;
+
+public class Command {
+
+	boolean				trace;
+	Reporter			reporter;
+	List<String>		arguments	= new ArrayList<String>();
+	Map<String, String>	variables	= new LinkedHashMap<String, String>();
+	long				timeout		= 0;
+	File				cwd			= new File("").getAbsoluteFile();
+	static Timer		timer		= new Timer(Command.class.getName(), true);
+	Process				process;
+	volatile boolean	timedout;
+	String				fullCommand;
+
+	public Command(String fullCommand) {
+		this.fullCommand = fullCommand;
+	}
+
+	public Command() {
+	}
+
+	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()]);
+		String vars[] = new String[variables.size()];
+		int i = 0;
+		for (Entry<String, String> s : variables.entrySet()) {
+			vars[i++] = s.getKey() + "=" + s.getValue();
+		}
+
+		if (fullCommand == null)
+			process = Runtime.getRuntime().exec(args, vars.length == 0 ? null : vars, cwd);
+		else
+			process = Runtime.getRuntime().exec(fullCommand, vars.length == 0 ? null : vars, 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, stderr).start();
+				if (handler != null)
+					handler.start();
+
+				result = process.waitFor();
+				if (reporter != null)
+					reporter.trace("exited process.waitFor, %s", result);
+
+			}
+			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;
+
+		Collector(InputStream inputStream, Appendable sb) {
+			this.in = inputStream;
+			this.sb = sb;
+			setDaemon(true);
+		}
+
+		public void run() {
+			try {
+				int c = in.read();
+				while (c >= 0) {
+					sb.append((char) c);
+					c = in.read();
+				}
+			}
+			catch( IOException e) {
+				// We assume the socket is closed
+			}
+			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);
+				}
+			}
+		}
+	}
+
+	static class InputStreamHandler extends Thread {
+		final InputStream	in;
+		final OutputStream	stdin;
+
+		InputStreamHandler(InputStream in, OutputStream stdin) {
+			this.stdin = stdin;
+			this.in = in;
+			setDaemon(true);
+		}
+
+		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?
+			}
+			finally {
+				try {
+					stdin.close();
+				}
+				catch (IOException e) {
+					// Who cares?
+				}
+			}
+		}
+	}
+
+	public Command var(String name, String value) {
+		variables.put(name, value);
+		return this;
+	}
+
+	public Command arg(String... args) {
+		add(args);
+		return this;
+	}
+
+	public Command full(String full) {
+		fullCommand = full;
+		return this;
+	}
+
+	public void inherit() {
+		ProcessBuilder pb = new ProcessBuilder();
+		for (Entry<String, String> e : pb.environment().entrySet()) {
+			var(e.getKey(), e.getValue());
+		}
+	}
+
+	public String var(String name) {
+		return variables.get(name);
+	}
+
+	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..a2afe57
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/command/packageinfo
@@ -0,0 +1 @@
+version 2.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..ff971e8
--- /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..90e7b1a
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Digest.java
@@ -0,0 +1,44 @@
+package aQute.libg.cryptography;
+
+import java.util.*;
+
+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();
+	
+	
+	public boolean equals(Object other) {
+		if ( !(other instanceof Digest))
+			return false;
+
+		Digest d = (Digest) other;
+		return Arrays.equals(d.digest, digest);
+	}
+	
+	public int hashCode() {
+		return Arrays.hashCode(digest);
+	}
+
+	public byte[] toByteArray() {
+		return digest();
+	}
+}
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..eeb2c8f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Digester.java
@@ -0,0 +1,47 @@
+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;
+	OutputStream out[];
+	
+	public Digester(MessageDigest instance, OutputStream ... out) {
+		md = instance;
+		this.out = out;
+	}
+	
+	@Override
+	public void write( byte[] buffer, int offset, int length) throws IOException{
+		md.update(buffer,offset,length);
+		for ( OutputStream o : out ) {
+			o.write(buffer, offset, length);
+		}
+	}
+	@Override
+	public void write( int b) throws IOException{
+		md.update((byte) b);
+		for ( OutputStream o : out ) {
+			o.write(b);
+		}
+	}
+	
+	public MessageDigest getMessageDigest() throws Exception {
+		return md;
+	}
+	
+	public T from(InputStream in) throws Exception {
+		IO.copy(in,this);
+		return digest();
+	}
+		
+	public void setOutputs(OutputStream ...out) {
+		this.out = out;
+	}
+	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..84b53ee
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/MD5.java
@@ -0,0 +1,34 @@
+package aQute.libg.cryptography;
+
+import java.io.*;
+import java.security.*;
+
+
+
+public class MD5 extends Digest {
+	public final static String ALGORITHM = "MD5";
+	
+	public static Digester<MD5> getDigester(OutputStream ... out) throws Exception {
+		return new Digester<MD5>(MessageDigest.getInstance(ALGORITHM), out) {
+			
+			@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..a01f112
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/SHA1.java
@@ -0,0 +1,35 @@
+package aQute.libg.cryptography;
+
+import java.io.*;
+import java.security.*;
+
+
+
+public class SHA1 extends Digest {
+	public final static String ALGORITHM = "SHA1";
+	
+	
+	public static Digester<SHA1> getDigester(OutputStream ... out  ) throws NoSuchAlgorithmException {
+		MessageDigest md = MessageDigest.getInstance(ALGORITHM);
+		return new Digester<SHA1>(md, out) {
+			@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/SHA256.java b/bundleplugin/src/main/java/aQute/libg/cryptography/SHA256.java
new file mode 100644
index 0000000..5b25cf3
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/SHA256.java
@@ -0,0 +1,35 @@
+package aQute.libg.cryptography;
+
+import java.io.*;
+import java.security.*;
+
+
+
+public class SHA256 extends Digest {
+	public final static String ALGORITHM = "SHA256";
+	
+	
+	public static Digester<SHA256> getDigester(OutputStream ... out  ) throws NoSuchAlgorithmException {
+		MessageDigest md = MessageDigest.getInstance(ALGORITHM);
+		return new Digester<SHA256>(md, out) {
+			@Override public SHA256 digest() throws Exception {
+				return new SHA256(md.digest());
+			}
+
+			@Override public SHA256 digest(byte[] bytes) {
+				return new SHA256(bytes);
+			}
+			@Override public String getAlgorithm() {
+				return ALGORITHM;
+			}
+		};
+	}
+	
+	public SHA256(byte[] b) {
+		super(b, 32);
+	}
+
+
+	@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..5218e2d
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/Signer.java
@@ -0,0 +1,41 @@
+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);
+			digester.write(buffer, offset, length);
+		} catch (SignatureException e) {
+			throw new IOException(e.getLocalizedMessage());
+		}
+	}
+
+	@Override public void write(int b) throws IOException {
+		try {
+			signature.update((byte) b);
+			digester.write(b);
+		} catch (SignatureException e) {
+			throw new IOException(e.getLocalizedMessage());
+		}
+	}
+	
+
+	public Signature signature() throws Exception {
+		return signature;
+	}
+	
+	public D digest() throws Exception {
+		return digester.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..5506ece
--- /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.getLocalizedMessage());
+		}
+	}
+
+	@Override
+	public void write( int b) throws IOException {
+		try {
+			signature.update((byte) b);
+		} catch (SignatureException e) {
+			throw new IOException(e.getLocalizedMessage());
+		}
+	}
+
+	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..e39f616
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/cryptography/packageinfo
@@ -0,0 +1 @@
+version 1.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..7cd73a2
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/fileiterator/FileIterator.java
@@ -0,0 +1,43 @@
+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();
+		return n < dir.list().length;
+    }
+
+    public File next() {
+        if (next != null) {
+            File answer = next.next();
+            if (!next.hasNext())
+                next = null;
+            return answer;
+        }
+		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/filelock/packageinfo b/bundleplugin/src/main/java/aQute/libg/filelock/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/filelock/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bundleplugin/src/main/java/aQute/libg/filerepo/FileRepo.java b/bundleplugin/src/main/java/aQute/libg/filerepo/FileRepo.java
new file mode 100644
index 0000000..a0149bc
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/filerepo/FileRepo.java
@@ -0,0 +1,106 @@
+package aQute.libg.filerepo;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.libg.version.*;
+
+public class FileRepo {
+	File	root;
+	Pattern	REPO_FILE	= Pattern.compile("([-a-zA-z0-9_\\.]+)-([0-9\\.]+|latest)\\.(jar|lib)");
+
+	public FileRepo(File root) {
+		this.root = root;
+	}
+
+	/**
+	 * Get a list of URLs to bundles that are constrained by the bsn and
+	 * versionRange.
+	 */
+	public File[] get(String bsn, final VersionRange versionRange) throws Exception {
+
+		//
+		// Check if the entry exists
+		//
+		File f = new File(root, bsn);
+		if (!f.isDirectory())
+			return null;
+
+		//
+		// 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.
+		//
+		return f.listFiles(new FilenameFilter() {
+			public boolean accept(File dir, String name) {
+				Matcher m = REPO_FILE.matcher(name);
+				if (!m.matches())
+					return false;
+				if ( versionRange == null)
+					return true;
+				
+				Version v = new Version(m.group(2));
+				return versionRange.includes(v);
+			}
+		});
+	}
+
+	public List<String> list(String regex) throws Exception {
+		if (regex == null)
+			regex = ".*";
+		final Pattern pattern = Pattern.compile(regex);
+
+		String list[] = root.list(new FilenameFilter() {
+
+			public boolean accept(File dir, String name) {
+				Matcher matcher = pattern.matcher(name);
+				return matcher.matches();
+			}
+
+		});
+		return Arrays.asList(list);
+	}
+
+	public List<Version> versions(String bsn) throws Exception {
+		File dir = new File(root, bsn);
+		final List<Version> versions = new ArrayList<Version>();
+		dir.list(new FilenameFilter() {
+
+			public boolean accept(File dir, String name) {
+				Matcher m = REPO_FILE.matcher(name);
+				if (m.matches()) {
+					versions.add(new Version(m.group(2)));
+					return true;
+				}
+				return false;
+			}
+
+		});
+		return versions;
+	}
+
+	public File get(String bsn, VersionRange range, int strategy) throws Exception {
+		File[] files = get(bsn, range);
+		if (files == null || files.length == 0)
+			return null;
+
+		if (files.length == 1)
+			return files[0];
+
+		if (strategy < 0) {
+			return files[0];
+		}
+		return files[files.length - 1];
+	}
+
+	public File put(String bsn, Version version) {
+		File dir = new File(root,bsn);
+		dir.mkdirs();
+		File file = new File(dir, bsn + "-" + version.getMajor() + "." + version.getMinor() + "." + version.getMicro() + ".jar");
+		return file;
+	}
+	
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/filerepo/packageinfo b/bundleplugin/src/main/java/aQute/libg/filerepo/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/filerepo/packageinfo
@@ -0,0 +1 @@
+version 1.0
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..2559fad
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/forker/Forker.java
@@ -0,0 +1,212 @@
+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 Map<T, Job>	waiting		= new HashMap<T, Job>();
+	final Set<Job>		executing	= new HashSet<Job>();
+	final AtomicBoolean	canceled	= new AtomicBoolean();
+	private int			count;
+
+	/**
+	 * 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;
+				e.printStackTrace();
+			} finally {
+				synchronized (this) {
+					t = null;
+				}
+				Thread.interrupted(); // clear the interrupt flag
+				done(this);
+			}
+		}
+
+		/**
+		 * 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) {
+		if (waiting.containsKey(target))
+			throw new IllegalArgumentException("You can only add a target once to the forker");
+
+		System.err.println("doWhen " + dependencies + " " + target);
+		Job job = new Job();
+		job.dependencies = new HashSet<T>(dependencies);
+		job.target = target;
+		job.runnable = runnable;
+		waiting.put(target, job);
+	}
+
+	public void start(long ms) throws InterruptedException {
+		check();
+		count = waiting.size();
+		System.err.println("Count " + count);
+		schedule();
+		if (ms >= 0)
+			sync(ms);
+	}
+
+	private void check() {
+		Set<T> dependencies = new HashSet<T>();
+		for (Job job : waiting.values())
+			dependencies.addAll(job.dependencies);
+		dependencies.removeAll(waiting.keySet());
+		if (dependencies.size() > 0)
+			throw new IllegalArgumentException(
+					"There are dependencies in the jobs that are not present in the targets: "
+							+ dependencies);
+
+	}
+
+	public synchronized void sync(long ms) throws InterruptedException {
+		System.err.println("Waiting for sync");
+		while (count > 0) {
+			System.err.println("Waiting for sync " + count);
+			wait(ms);
+		}
+		System.err.println("Exiting sync " + count);
+	}
+
+	private void schedule() {
+		if (canceled.get())
+			return;
+
+		List<Runnable> torun = new ArrayList<Runnable>();
+		synchronized (this) {
+			for (Iterator<Job> e = waiting.values().iterator(); e.hasNext();) {
+				Job job = e.next();
+				if (job.dependencies.isEmpty()) {
+					torun.add(job);
+					executing.add(job);
+					e.remove();
+				}
+			}
+		}
+		for (Runnable r : torun)
+			executor.execute(r);
+	}
+
+	/**
+	 * Called when the target has ran by the Job.
+	 * 
+	 * @param done
+	 */
+	private void done(Job done) {
+		synchronized (this) {
+			System.err.println("count = " + count);
+			executing.remove(done);
+			count--;
+			if (count == 0) {
+				System.err.println("finished");
+				notifyAll();
+				return;
+			}
+
+			for (Job job : waiting.values()) {
+				// boolean x =
+					job.dependencies.remove(done.target);
+				//System.err.println( "Removing " + done.target + " from " + job.target + " ?" + x  + " " + job.dependencies.size());
+			}
+		}
+		schedule();
+	}
+
+	/**
+	 * Cancel the forker.
+	 * 
+	 * @throws InterruptedException
+	 */
+	public void cancel(long ms) throws InterruptedException {
+		System.err.println("canceled " + count);
+
+		if (!canceled.getAndSet(true)) {
+			synchronized (this) {
+				for (Job job : executing) {
+					job.cancel();
+				}
+			}
+		}
+		sync(ms);
+	}
+
+	public int getCount() {
+		return count;
+	}
+}
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..ee708fd
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/generics/Create.java
@@ -0,0 +1,54 @@
+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 <K,V>  Map<K, V> map(Class<K> key, Class<V> value) {
+        return Collections.checkedMap(new LinkedHashMap<K,V>(), key,value);
+    }
+
+    public static <T>  List<T> list() {
+        return new ArrayList<T>();
+    }
+
+    public static <T>  List<T> list(Class<T> c) {
+        return Collections.checkedList(new ArrayList<T>(),c) ;
+    }
+
+    public static <T>  Set<T> set() {
+        return new HashSet<T>();
+    }
+
+    public static <T>  Set<T> set(Class<T> c) {
+        return Collections.checkedSet(new HashSet<T>(),c);
+    }
+
+    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/glob/Glob.java b/bundleplugin/src/main/java/aQute/libg/glob/Glob.java
new file mode 100644
index 0000000..c4d06a7
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/glob/Glob.java
@@ -0,0 +1,110 @@
+package aQute.libg.glob;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Glob {
+
+	private final String glob;
+	private final Pattern pattern;
+	
+	public Glob(String globString) {
+		this.glob = globString;
+		this.pattern = Pattern.compile(convertGlobToRegEx(globString));
+	}
+	
+	public Matcher matcher(CharSequence input) {
+		return pattern.matcher(input);
+	}
+	
+	@Override
+	public String toString() {
+		return glob;
+	}
+
+	private static String convertGlobToRegEx(String line) {
+		line = line.trim();
+		int strLen = line.length();
+		StringBuilder sb = new StringBuilder(strLen);
+		// Remove beginning and ending * globs because they're useless
+		if (line.startsWith("*")) {
+			line = line.substring(1);
+			strLen--;
+		}
+		if (line.endsWith("*")) {
+			line = line.substring(0, strLen - 1);
+			strLen--;
+		}
+		boolean escaping = false;
+		int inCurlies = 0;
+		for (char currentChar : line.toCharArray()) {
+			switch (currentChar) {
+			case '*':
+				if (escaping)
+					sb.append("\\*");
+				else
+					sb.append(".*");
+				escaping = false;
+				break;
+			case '?':
+				if (escaping)
+					sb.append("\\?");
+				else
+					sb.append('.');
+				escaping = false;
+				break;
+			case '.':
+			case '(':
+			case ')':
+			case '+':
+			case '|':
+			case '^':
+			case '$':
+			case '@':
+			case '%':
+				sb.append('\\');
+				sb.append(currentChar);
+				escaping = false;
+				break;
+			case '\\':
+				if (escaping) {
+					sb.append("\\\\");
+					escaping = false;
+				} else
+					escaping = true;
+				break;
+			case '{':
+				if (escaping) {
+					sb.append("\\{");
+				} else {
+					sb.append('(');
+					inCurlies++;
+				}
+				escaping = false;
+				break;
+			case '}':
+				if (inCurlies > 0 && !escaping) {
+					sb.append(')');
+					inCurlies--;
+				} else if (escaping)
+					sb.append("\\}");
+				else
+					sb.append("}");
+				escaping = false;
+				break;
+			case ',':
+				if (inCurlies > 0 && !escaping) {
+					sb.append('|');
+				} else if (escaping)
+					sb.append("\\,");
+				else
+					sb.append(",");
+				break;
+			default:
+				escaping = false;
+				sb.append(currentChar);
+			}
+		}
+		return sb.toString();
+	}
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/glob/packageinfo b/bundleplugin/src/main/java/aQute/libg/glob/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/glob/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bundleplugin/src/main/java/aQute/libg/gzip/GZipUtils.java b/bundleplugin/src/main/java/aQute/libg/gzip/GZipUtils.java
new file mode 100644
index 0000000..6606d0e
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/gzip/GZipUtils.java
@@ -0,0 +1,60 @@
+package aQute.libg.gzip;
+
+import java.io.BufferedInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.GZIPInputStream;
+
+public class GZipUtils {
+	
+	/**
+	 * Determines whether the specified stream contains gzipped data, by
+	 * checking for the GZIP magic number, and returns a stream capable of
+	 * reading those data.
+	 * 
+	 * @throws IOException
+	 */
+	public static InputStream detectCompression(InputStream stream) throws IOException {
+		InputStream buffered;
+		if (stream.markSupported())
+			buffered = stream;
+		else
+			buffered = new BufferedInputStream(stream);
+		
+		buffered.mark(2);
+		int magic = readUShort(buffered);
+		buffered.reset();
+		
+		InputStream result;
+		if (magic == GZIPInputStream.GZIP_MAGIC)
+			result = new GZIPInputStream(buffered);
+		else
+			result = buffered;
+		return result;
+	}
+
+    /*
+     * Reads unsigned short in Intel byte order.
+     */
+	private static int readUShort(InputStream in) throws IOException {
+		int b = readUByte(in);
+		return (readUByte(in) << 8) | b;
+	}
+    
+    /*
+     * Reads unsigned byte.
+     */
+    private static int readUByte(InputStream in) throws IOException {
+	int b = in.read();
+	if (b == -1) {
+	    throw new EOFException();
+	}
+        if (b < -1 || b > 255) {
+            // Report on this.in, not argument in; see read{Header, Trailer}.
+            throw new IOException(in.getClass().getName() + ".read() returned value out of range -1..255: " + b);
+        }
+	return b;
+    }
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/gzip/packageinfo b/bundleplugin/src/main/java/aQute/libg/gzip/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/gzip/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bundleplugin/src/main/java/aQute/libg/header/Attrs.java b/bundleplugin/src/main/java/aQute/libg/header/Attrs.java
new file mode 100644
index 0000000..d11b6d1
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/header/Attrs.java
@@ -0,0 +1,295 @@
+package aQute.libg.header;
+
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.lib.collections.*;
+import aQute.libg.version.*;
+
+public class Attrs implements Map<String, String> {
+	public enum Type {
+		STRING(null), LONG(null), VERSION(null), DOUBLE(null), STRINGS(STRING), LONGS(LONG), VERSIONS(VERSION), DOUBLES(DOUBLE);
+
+		Type	sub;
+
+		Type(Type sub) {
+			this.sub = sub;
+		}
+
+	}
+
+	/**
+	 * <pre>
+	 * Provide-Capability ::= capability ::=
+	 * name-space ::= typed-attr ::= type ::= scalar ::=
+	 * capability ( ',' capability )*
+	 * name-space
+	 *     ( ’;’ directive | typed-attr )*
+	 * symbolic-name
+	 * extended ( ’:’ type ) ’=’ argument
+	 * scalar | list
+	 * ’String’ | ’Version’ | ’Long’
+	 * list ::=
+	 * ’List<’ scalar ’>’
+	 * </pre>
+	 */
+	static String					EXTENDED	= "[\\-0-9a-zA-Z\\._]+";
+	static String					SCALAR		= "String|Version|Long|Double";
+	static String					LIST		= "List\\s*<\\s*(" + SCALAR + ")\\s*>";
+	public static final Pattern		TYPED		= Pattern.compile("\\s*(" + EXTENDED + ")\\s*:\\s*("+ SCALAR + "|" + LIST + ")\\s*");
+
+	private LinkedHashMap<String, String>	map;
+	private Map<String, Type>		types;
+	static Map<String, String>		EMPTY		= Collections.emptyMap();
+
+	public Attrs(Attrs... attrs) {
+		for (Attrs a : attrs) {
+			if (a != null) {
+				putAll(a);
+			}
+		}
+	}
+
+	public void clear() {
+		map.clear();
+	}
+
+	public boolean containsKey(String name) {
+		if (map == null)
+			return false;
+
+		return map.containsKey(name);
+	}
+
+	@SuppressWarnings("cast")
+	@Deprecated public boolean containsKey(Object name) {
+		assert name instanceof String;
+		if (map == null)
+			return false;
+
+		return map.containsKey((String) name);
+	}
+
+	public boolean containsValue(String value) {
+		if (map == null)
+			return false;
+
+		return map.containsValue(value);
+	}
+
+	@SuppressWarnings("cast")
+	@Deprecated public boolean containsValue(Object value) {
+		assert value instanceof String;
+		if (map == null)
+			return false;
+
+		return map.containsValue((String) value);
+	}
+
+	public Set<java.util.Map.Entry<String, String>> entrySet() {
+		if (map == null)
+			return EMPTY.entrySet();
+
+		return map.entrySet();
+	}
+
+	@SuppressWarnings("cast")
+	@Deprecated public String get(Object key) {
+		assert key instanceof String;
+		if (map == null)
+			return null;
+
+		return map.get((String) key);
+	}
+
+	public String get(String key) {
+		if (map == null)
+			return null;
+
+		return map.get(key);
+	}
+
+	public String get(String key, String deflt) {
+		String s = get(key);
+		if (s == null)
+			return deflt;
+		return s;
+	}
+
+	public boolean isEmpty() {
+		return map == null || map.isEmpty();
+	}
+
+	public Set<String> keySet() {
+		if (map == null)
+			return EMPTY.keySet();
+
+		return map.keySet();
+	}
+
+	public String put(String key, String value) {
+		if (map == null)
+			map = new LinkedHashMap<String, String>();
+
+		Matcher m = TYPED.matcher(key);
+		if (m.matches()) {
+			key = m.group(1);
+			String type = m.group(2);
+			Type t = Type.STRING;
+
+			if ( type.startsWith("List")) {
+				type = m.group(3);
+				if ( "String".equals(type))
+					t = Type.STRINGS;
+				else if ( "Long".equals(type))
+					t = Type.LONGS;
+				else if ( "Double".equals(type))
+					t = Type.DOUBLES;
+				else if ( "Version".equals(type))
+					t = Type.VERSIONS;				
+			} else {
+				if ( "String".equals(type))
+					t = Type.STRING;
+				else if ( "Long".equals(type))
+					t = Type.LONG;
+				else if ( "Double".equals(type))
+					t = Type.DOUBLE;
+				else if ( "Version".equals(type))
+					t = Type.VERSION;
+			}
+			if (types == null)
+				types = new LinkedHashMap<String, Type>();
+			types.put(key, t);
+
+			// TODO verify value?
+		}
+
+		return map.put(key, value);
+	}
+
+	public Type getType(String key) {
+		if (types == null)
+			return Type.STRING;
+		Type t = types.get(key);
+		if (t == null)
+			return Type.STRING;
+		return t;
+	}
+
+	public void putAll(Map<? extends String, ? extends String> map) {
+		for (Map.Entry<? extends String, ? extends String> e : map.entrySet())
+			put(e.getKey(), e.getValue());
+	}
+
+	@SuppressWarnings("cast")
+	@Deprecated public String remove(Object var0) {
+		assert var0 instanceof String;
+		if (map == null)
+			return null;
+
+		return map.remove((String) var0);
+	}
+
+	public String remove(String var0) {
+		if (map == null)
+			return null;
+		return map.remove(var0);
+	}
+
+	public int size() {
+		if (map == null)
+			return 0;
+		return map.size();
+	}
+
+	public Collection<String> values() {
+		if (map == null)
+			return EMPTY.values();
+
+		return map.values();
+	}
+
+	public String getVersion() {
+		return get("version");
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		append(sb);
+		return sb.toString();
+	}
+
+	public void append(StringBuilder sb) {
+		String del = "";
+		for (Map.Entry<String, String> e : entrySet()) {
+			sb.append(del);
+			sb.append(e.getKey());
+			sb.append("=");
+			sb.append(e.getValue());
+			del = ";";
+		}
+	}
+
+	@Deprecated public boolean equals(Object other) {
+		return super.equals(other);
+	}
+
+	@Deprecated public int hashCode() {
+		return super.hashCode();
+	}
+
+	public boolean isEqual(Attrs o) {
+		if (this == o)
+			return true;
+
+		Attrs other = o;
+
+		if (size() != other.size())
+			return false;
+
+		if (isEmpty())
+			return true;
+
+		SortedList<String> l = new SortedList<String>(keySet());
+		SortedList<String> lo = new SortedList<String>(other.keySet());
+		if (!l.isEqual(lo))
+			return false;
+
+		for (String key : keySet()) {
+			if (!get(key).equals(other.get(key)))
+				return false;
+		}
+		return true;
+
+	}
+
+	public Object getTyped(String adname) {
+		String s = get(adname);
+		if (s == null)
+			return null;
+
+		Type t = getType(adname);
+		return convert(t, s);
+	}
+
+	private Object convert(Type t, String s) {
+		if (t.sub == null) {
+			switch (t) {
+			case STRING:
+				return s;
+			case LONG:
+				return Long.parseLong(s.trim());
+			case VERSION:
+				return Version.parseVersion(s);
+			}
+			return null;
+		}
+		List<Object> list = new ArrayList<Object>();
+		String split[] = s.split("\\s*\\(\\?!\\),\\s*");
+		for (String p : split) {
+			p = p.replaceAll("\\\\", "");
+			list.add(convert(t.sub, p));
+		}
+		return list;
+	}
+}
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 100755
index 0000000..7b26f6f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/header/OSGiHeader.java
@@ -0,0 +1,138 @@
+package aQute.libg.header;
+
+import java.util.*;
+
+import aQute.libg.generics.*;
+import aQute.libg.qtokens.*;
+import aQute.libg.reporter.*;
+
+public class OSGiHeader {
+
+	static public Parameters 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 Parameters parseHeader(String value, Reporter logger) {
+		return parseHeader(value, logger, new Parameters());
+	}
+
+	static public Parameters parseHeader(String value, Reporter logger, Parameters result) {
+		if (value == null || value.trim().length() == 0)
+			return result;
+
+		QuotedTokenizer qt = new QuotedTokenizer(value, ";=,");
+		char del = 0;
+		do {
+			boolean hadAttribute = false;
+			Attrs clause = new Attrs();
+			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 Attrs parseProperties(String input) {
+		return parseProperties(input, null);
+	}
+
+	public static Attrs parseProperties(String input, Reporter logger) {
+		if (input == null || input.trim().length() == 0)
+			return new Attrs();
+
+		Attrs result = new Attrs();
+		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);
+			logger.error("Invalid syntax for properties: " + input);
+		}
+
+		return result;
+	}
+
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/header/Parameters.java b/bundleplugin/src/main/java/aQute/libg/header/Parameters.java
new file mode 100644
index 0000000..96f0d08
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/header/Parameters.java
@@ -0,0 +1,203 @@
+package aQute.libg.header;
+
+import java.util.*;
+
+import aQute.lib.collections.*;
+import aQute.libg.reporter.*;
+
+public class Parameters implements Map<String, Attrs> {
+	private LinkedHashMap<String, Attrs>	map;
+	static Map<String, Attrs>				EMPTY	= Collections.emptyMap();
+	String									error;
+
+	public Parameters() {
+	}
+
+	public Parameters(String header) {
+		OSGiHeader.parseHeader(header, null, this);
+	}
+
+	public Parameters(String header, Reporter reporter) {
+		OSGiHeader.parseHeader(header, reporter, this);
+	}
+
+	public void clear() {
+		map.clear();
+	}
+
+	public boolean containsKey(final String name) {
+		if (map == null)
+			return false;
+
+		return map.containsKey(name);
+	}
+
+	@SuppressWarnings("cast")
+	@Deprecated public boolean containsKey(Object name) {
+		assert name instanceof String;
+		if (map == null)
+			return false;
+
+		return map.containsKey((String) name);
+	}
+
+	public boolean containsValue(Attrs value) {
+		if (map == null)
+			return false;
+
+		return map.containsValue(value);
+	}
+
+	@SuppressWarnings("cast")
+	@Deprecated public boolean containsValue(Object value) {
+		assert value instanceof Attrs;
+		if (map == null)
+			return false;
+
+		return map.containsValue((Attrs) value);
+	}
+
+	public Set<java.util.Map.Entry<String, Attrs>> entrySet() {
+		if (map == null)
+			return EMPTY.entrySet();
+
+		return map.entrySet();
+	}
+
+	@SuppressWarnings("cast")
+	@Deprecated public Attrs get(Object key) {
+		assert key instanceof String;
+		if (map == null)
+			return null;
+
+		return map.get((String) key);
+	}
+
+	public Attrs get(String key) {
+		if (map == null)
+			return null;
+
+		return map.get(key);
+	}
+
+	public boolean isEmpty() {
+		return map == null || map.isEmpty();
+	}
+
+	public Set<String> keySet() {
+		if (map == null)
+			return EMPTY.keySet();
+
+		return map.keySet();
+	}
+
+	public Attrs put(String key, Attrs value) {
+		assert key != null;
+		assert value != null;
+
+		if (map == null)
+			map = new LinkedHashMap<String, Attrs>();
+
+		return map.put(key, value);
+	}
+
+	public void putAll(Map<? extends String, ? extends Attrs> map) {
+		if (this.map == null) {
+			if (map.isEmpty())
+				return;
+			this.map = new LinkedHashMap<String, Attrs>();
+		}
+		this.map.putAll(map);
+	}
+	public void putAllIfAbsent(Map<String, ? extends Attrs> map) {
+		for(Map.Entry<String, ? extends Attrs> entry : map.entrySet() ) {
+			if ( !containsKey(entry.getKey()))
+				put(entry.getKey(), entry.getValue());
+		}
+	}
+
+	@SuppressWarnings("cast")
+	@Deprecated public Attrs remove(Object var0) {
+		assert var0 instanceof String;
+		if (map == null)
+			return null;
+
+		return map.remove((String) var0);
+	}
+
+	public Attrs remove(String var0) {
+		if (map == null)
+			return null;
+		return map.remove(var0);
+	}
+
+	public int size() {
+		if (map == null)
+			return 0;
+		return map.size();
+	}
+
+	public Collection<Attrs> values() {
+		if (map == null)
+			return EMPTY.values();
+
+		return map.values();
+	}
+
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		append(sb);
+		return sb.toString();
+	}
+
+	public void append(StringBuilder sb) {
+		String del = "";
+		for (Map.Entry<String, Attrs> s : entrySet()) {
+			sb.append(del);
+			sb.append(s.getKey());
+			if (!s.getValue().isEmpty()) {
+				sb.append(';');
+				s.getValue().append(sb);
+			}
+
+			del = ",";
+		}
+	}
+
+	@Deprecated
+	public boolean equals(Object other) {
+		return super.equals(other);
+	}
+	
+	@Deprecated
+	public int hashCode() {
+		return super.hashCode();
+	}
+	
+
+	public boolean isEqual(Parameters other) {
+		if (this == other)
+			return true;
+
+		if (size() != other.size())
+			return false;
+
+		if (isEmpty())
+			return true;
+
+		SortedList<String> l = new SortedList<String>(keySet());
+		SortedList<String> lo = new SortedList<String>(other.keySet());
+		if (!l.isEqual(lo))
+			return false;
+
+		for (String key : keySet()) {
+			if (!get(key).isEqual(other.get(key)))
+				return false;
+		}
+		return true;
+	}
+
+	public Map<String,? extends Map<String,String>> asMapMap() {
+		return this;
+	}
+}
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..e39f616
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/header/packageinfo
@@ -0,0 +1 @@
+version 1.1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/log/Logger.java b/bundleplugin/src/main/java/aQute/libg/log/Logger.java
new file mode 100755
index 0000000..bb87707
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/log/Logger.java
@@ -0,0 +1,16 @@
+package aQute.libg.log;
+
+import java.util.*;
+
+
+public interface Logger {
+	void error(String s, Object ... args);
+	void warning(String s, Object ... args);
+	void progress(String s, Object ... args);
+	
+	List<String> getWarnings();
+	List<String> getErrors();
+	List<String> getProgress();
+	
+	boolean isPedantic();
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/log/packageinfo b/bundleplugin/src/main/java/aQute/libg/log/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/log/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/map/MAP.java b/bundleplugin/src/main/java/aQute/libg/map/MAP.java
new file mode 100644
index 0000000..41c588b
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/map/MAP.java
@@ -0,0 +1,45 @@
+package aQute.libg.map;
+
+import java.util.*;
+
+/**
+ * Easy way to build a map:
+ * 
+ * 	Map<String,Integer> s = MAP.$("a",2).$("b",3);
+ *
+ */
+public class MAP {
+
+	static public class MAPX<K, V> extends LinkedHashMap<K, V> {
+		private static final long	serialVersionUID	= 1L;
+		public MAPX<K, V> $(K key, V value) {
+			put(key, value);
+			return this;
+		}
+
+		public MAPX<K, V> $(Map<K,V> all) {
+			putAll(all);
+			return this;
+		}
+		public Hashtable<K,V> asHashtable() {
+			return new Hashtable<K,V>(this);
+		}
+	}
+
+	public static <Kx, Vx> MAPX<Kx, Vx> $(Kx key, Vx value) {
+		MAPX<Kx, Vx> map = new MAPX<Kx, Vx>();
+		map.put(key, value);
+		return map;
+	}
+	
+	
+	public <K,V> Map<K,V> dictionary(Dictionary<K,V> dict ) {
+		Map<K,V> map = new LinkedHashMap<K, V>();
+		for ( Enumeration<K> e = dict.keys(); e.hasMoreElements(); ) {
+			K k = e.nextElement();
+			V v = dict.get(k);
+			map.put(k,v);
+		}
+		return map;
+	}
+}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/map/packageinfo b/bundleplugin/src/main/java/aQute/libg/map/packageinfo
new file mode 100644
index 0000000..897578f
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/map/packageinfo
@@ -0,0 +1 @@
+version 1.2.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 100755
index 0000000..58ea539
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/qtokens/QuotedTokenizer.java
@@ -0,0 +1,116 @@
+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;
+		
+		StringBuilder sb = new StringBuilder();
+
+		while (index < string.length()) {
+			char c = string.charAt(index++);
+
+			if ( Character.isWhitespace(c)) {
+				if ( index == string.length())
+					break;
+				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(StringBuilder 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 100755
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/ReporterAdapter.java b/bundleplugin/src/main/java/aQute/libg/reporter/ReporterAdapter.java
new file mode 100644
index 0000000..249b776
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/reporter/ReporterAdapter.java
@@ -0,0 +1,182 @@
+package aQute.libg.reporter;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.libg.generics.*;
+
+/**
+ * Mainly used for testing where reporters are needed.
+ * 
+ */
+public class ReporterAdapter implements Reporter {
+	final List<String>	errors		= new ArrayList<String>();
+	final List<String>	warnings	= new ArrayList<String>();
+	final Formatter		out;
+	boolean				trace;
+	boolean				pedantic;
+	boolean				exceptions;
+
+	/**
+	 * @return the exceptions
+	 */
+	public boolean isExceptions() {
+		return exceptions;
+	}
+
+	/**
+	 * @param exceptions
+	 *            the exceptions to set
+	 */
+	public void setExceptions(boolean exceptions) {
+		this.exceptions = exceptions;
+	}
+
+	/**
+	 * @return the out
+	 */
+	public Formatter getOut() {
+		return out;
+	}
+
+	/**
+	 * @return the trace
+	 */
+	public boolean isTrace() {
+		return trace;
+	}
+
+	/**
+	 * @param pedantic
+	 *            the pedantic to set
+	 */
+	public void setPedantic(boolean pedantic) {
+		this.pedantic = pedantic;
+	}
+
+	public ReporterAdapter() {
+		out = null;
+	}
+
+	public ReporterAdapter(Appendable app) {
+		out = new Formatter(app);
+	}
+
+	public void error(String s, Object... args) {
+		String e = String.format(s, args);
+		errors.add(e);
+		trace("ERROR: %s", e);
+	}
+
+	public void exception(Throwable t, String s, Object... args) {
+		String e = String.format(s, args);
+		errors.add(e);
+		trace("ERROR: %s", e);
+		if (isExceptions() || isTrace())
+			if ( t instanceof InvocationTargetException )
+				t.getCause().printStackTrace(System.err);
+			else
+				t.printStackTrace(System.err);
+	}
+
+	public void warning(String s, Object... args) {
+		String e = String.format(s, args);
+		warnings.add(e);
+		trace("warning: %s", e);
+	}
+
+	public void progress(String s, Object... args) {
+		if (out != null) {
+			out.format(s, args);
+			if ( !s.endsWith("\n"))
+				out.format("\n");
+		}
+	}
+
+	public void trace(String s, Object... args) {
+		if (trace && out != null) {
+			out.format("# "+s+"\n", args);
+			out.flush();
+		}
+	}
+
+	public List<String> getWarnings() {
+		return warnings;
+	}
+
+	public List<String> getErrors() {
+		return errors;
+	}
+
+	public boolean isPedantic() {
+		return false;
+	}
+
+	public void setTrace(boolean b) {
+		this.trace = b;
+	}
+
+	public boolean isOk() {
+		return errors.isEmpty();
+	}
+
+	public boolean isPerfect() {
+		return isOk() && warnings.isEmpty();
+	}
+
+	public boolean check(String... pattern) {
+		Set<String> missed = Create.set();
+
+		if (pattern != null) {
+			for (String p : pattern) {
+				boolean match = false;
+				Pattern pat = Pattern.compile(p);
+				for (Iterator<String> i = errors.iterator(); i.hasNext();) {
+					if (pat.matcher(i.next()).find()) {
+						i.remove();
+						match = true;
+					}
+				}
+				for (Iterator<String> i = warnings.iterator(); i.hasNext();) {
+					if (pat.matcher(i.next()).find()) {
+						i.remove();
+						match = true;
+					}
+				}
+				if (!match)
+					missed.add(p);
+
+			}
+		}
+		if (missed.isEmpty() && isPerfect())
+			return true;
+
+		if (!missed.isEmpty())
+			error("Missed the following patterns in the warnings or errors: %s", missed);
+
+		return false;
+	}
+
+	/**
+	 * Report the errors and warnings
+	 */
+
+	public void report(Appendable out) {
+		Formatter f = new Formatter(out);
+		report("Error", getErrors(), f);
+		report("Warning", getWarnings(), f);
+		f.flush();
+	}
+
+	void report(String title, Collection<String> list, Formatter f) {
+		if (list.isEmpty())
+			return;
+		f.format(title + (list.size() > 1 ? "s" : "")+"\n");
+		int n=0;
+		for (String s : list) {
+			f.format("%3s. %s\n", n++, s);
+		}
+	}
+
+}
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..ef7df68
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/reporter/packageinfo
@@ -0,0 +1 @@
+version 1.2
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..74f4756
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sed/Sed.java
@@ -0,0 +1,99 @@
+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;
+    boolean backup = true;
+
+    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 Sed(File file) {
+        assert file.isFile();
+        this.file = file;
+        this.macro = null;
+    }
+
+    public void setOutput(File f) {
+        output = f;
+    }
+
+    public void replace(String pattern, String replacement) {
+        replacements.put(Pattern.compile(pattern), replacement);
+    }
+
+    public int doIt() throws IOException {
+    	int actions = 0;
+        BufferedReader brdr = new BufferedReader(new InputStreamReader( new FileInputStream(file),"UTF-8"));
+        File out;
+        if (output != null)
+            out = output;
+        else
+            out = new File(file.getAbsolutePath() + ".tmp");
+        PrintWriter pw = new PrintWriter(new OutputStreamWriter( new FileOutputStream(out),"UTF-8"));
+        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);
+                        if ( macro != null)
+                        	tmp = Matcher.quoteReplacement(macro.process(tmp));
+                        m.appendReplacement(sb, tmp);
+                        actions++;
+                    }
+                    m.appendTail(sb);
+
+                    line = sb.toString();
+                }
+                pw.println(line);
+            }
+            pw.close();
+            if (output == null) {
+            	if ( backup ) {
+                    File bak = new File(file.getAbsolutePath() + ".bak");
+            		file.renameTo(bak);
+            	}
+                out.renameTo(file);
+            }
+        } finally {
+            brdr.close();
+            pw.close();
+        }
+        return actions;
+    }
+
+    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();
+    }
+
+    public void setBackup(boolean b) {
+    	this.backup=b;
+    }
+}
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..b3d1f97
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/sed/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
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..3d05b76
--- /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> Collection<? extends Collection<T>> tarjan(Map<T, ? extends Collection<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 100755
index 0000000..d326ec4
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/version/Version.java
@@ -0,0 +1,166 @@
+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 static final Version	emptyVersion	= LOWEST;
+    public static final Version	ONE	= new Version(1,0,0);
+
+    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) {
+    	version = version.trim();
+        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;
+
+        Version o = 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() {
+        StringBuilder sb = new StringBuilder();
+        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)");
+        }
+    }
+    
+    public static Version parseVersion(String version) {
+		if (version == null) {
+			return LOWEST;
+		}
+
+		version = version.trim();
+		if (version.length() == 0) {
+			return LOWEST;
+		}
+
+		return new Version(version);
+
+    }
+    
+    public Version getWithoutQualifier() {
+    	return new Version(major,minor,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 100755
index 0000000..46f9e94
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/version/VersionRange.java
@@ -0,0 +1,96 @@
+package aQute.libg.version;
+
+import java.util.*;
+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();
+
+		StringBuilder sb = new StringBuilder();
+		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;
+	}
+	
+	public Iterable<Version> filter( final Iterable<Version> versions) {
+		List<Version> list = new ArrayList<Version>();
+		for ( Version v : versions) {
+			if ( includes(v))
+				list.add(v);
+		}
+		return list;
+	}
+	
+}
\ 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..b3d1f97
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/version/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
diff --git a/bundleplugin/src/main/java/aQute/libg/xslt/Transform.java b/bundleplugin/src/main/java/aQute/libg/xslt/Transform.java
new file mode 100644
index 0000000..ea0fcd0
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/xslt/Transform.java
@@ -0,0 +1,44 @@
+package aQute.libg.xslt;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.concurrent.*;
+
+import javax.xml.transform.*;
+import javax.xml.transform.stream.*;
+
+public class Transform {
+    static TransformerFactory transformerFactory = TransformerFactory
+                                                         .newInstance();
+
+    static Map<URL, Templates> cache          = new ConcurrentHashMap<URL, Templates>();
+
+    public static void transform(TransformerFactory transformerFactory, URL xslt, InputStream in, OutputStream out)
+            throws Exception {
+        if ( xslt == null ) 
+            throw new IllegalArgumentException("No source template specified");
+        
+        Templates templates = cache.get(xslt);
+        if (templates == null) {
+            InputStream xsltIn = xslt.openStream();
+            try {
+                templates = transformerFactory
+                        .newTemplates(new StreamSource(xsltIn));
+
+                cache.put(xslt, templates);
+            } finally {
+                in.close();
+            }
+        }
+        Result xmlResult = new StreamResult(out);
+        Source xmlSource = new StreamSource(in);
+        Transformer t = templates.newTransformer();
+        t.transform(xmlSource, xmlResult);
+        out.flush();
+    }
+
+    public static void transform(URL xslt, InputStream in, OutputStream out) throws Exception {
+        transform(transformerFactory,xslt, in, out);
+    }
+}
diff --git a/bundleplugin/src/main/java/aQute/libg/xslt/packageinfo b/bundleplugin/src/main/java/aQute/libg/xslt/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/libg/xslt/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/AbstractDependencyFilter.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/AbstractDependencyFilter.java
index 9b5d0cf..d111023 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/AbstractDependencyFilter.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/AbstractDependencyFilter.java
@@ -66,7 +66,7 @@
 
         public DependencyFilter( String expression, String defaultValue )
         {
-            m_instruction = Instruction.getPattern( expression );
+            m_instruction = new Instruction( expression );
             m_defaultValue = defaultValue;
         }
 
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java
index 2c8b3d9..0df974d 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java
@@ -41,6 +41,7 @@
 
 import aQute.bnd.service.AnalyzerPlugin;
 import aQute.lib.osgi.Analyzer;
+import aQute.lib.osgi.Descriptors.PackageRef;
 import aQute.lib.osgi.Jar;
 import aQute.lib.osgi.Processor;
 import aQute.lib.osgi.Resource;
@@ -74,7 +75,7 @@
         Set<String> headers = Create.set();
 
         String bpHeader = analyzer.getProperty( "Bundle-Blueprint", "OSGI-INF/blueprint" );
-        Map<String, Map<String, String>> map = Processor.parseHeader( bpHeader, null );
+        Map<String, ? extends Map<String, String>> map = Processor.parseHeader( bpHeader, null );
         for ( String root : map.keySet() )
         {
             Jar jar = analyzer.getJar();
@@ -138,9 +139,10 @@
                             continue;
                         }
                     }
-                    if ( !analyzer.getReferred().containsKey( pkg ) )
+                    PackageRef pkgRef = analyzer.getPackageRef( pkg );
+                    if ( !analyzer.getReferred().containsKey( pkgRef ) )
                     {
-                        analyzer.getReferred().put( pkg, a.getProperties() );
+                        analyzer.getReferred().put( pkgRef ).putAll( a.getProperties() );
                     }
                 }
             }
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 3136d89..fb4948a 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
@@ -757,8 +757,8 @@
             {
                 Set optionalPackages = getOptionalPackages( currentProject );
 
-                Map<String, Map<String, String>> values = new Analyzer().parseHeader( importPackages );
-                for ( Map.Entry<String, Map<String, String>> entry : values.entrySet() )
+                Map<String, ? extends Map<String, String>> values = new Analyzer().parseHeader( importPackages );
+                for ( Map.Entry<String, ? extends Map<String, String>> entry : values.entrySet() )
                 {
                     String pkg = entry.getKey();
                     Map<String, String> options = entry.getValue();
