diff --git a/bundleplugin/pom.xml b/bundleplugin/pom.xml
index 07933a3..d7c5536 100644
--- a/bundleplugin/pom.xml
+++ b/bundleplugin/pom.xml
@@ -55,48 +55,15 @@
      <target>1.5</target>
     </configuration>
    </plugin>
-<!--
- | vvvvvvvv TEMP vvvvvvvv
--->
-   <plugin>
-    <groupId>org.apache.rat</groupId>
-    <artifactId>apache-rat-plugin</artifactId>
-    <configuration>
-     <excludes>
-      <exclude>src/main/*/aQute/**</exclude>
-     </excludes>
-    </configuration>
-   </plugin>
-<!--
- | ^^^^^^^^ TEMP ^^^^^^^^
--->
   </plugins>
  </build>
 
  <dependencies>
-<!--
   <dependency>
     <groupId>biz.aQute</groupId>
     <artifactId>bndlib</artifactId>
-    <version>1.50.0</version>
+    <version>2.0.0.20130123-133441</version>
   </dependency>
--->
-<!--
- | vvvvvvvv TEMP vvvvvvvv
--->
-  <dependency>
-    <groupId>org.osgi</groupId>
-    <artifactId>org.osgi.core</artifactId>
-    <version>5.0.0</version>
-  </dependency>
-  <dependency>
-    <groupId>org.osgi</groupId>
-    <artifactId>org.osgi.compendium</artifactId>
-    <version>4.3.0</version>
-  </dependency>
-<!--
- | ^^^^^^^^ TEMP ^^^^^^^^
--->
   <dependency>
     <groupId>org.apache.felix</groupId>
     <artifactId>org.apache.felix.bundlerepository</artifactId>
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/ConsumerType.java b/bundleplugin/src/main/java/aQute/bnd/annotation/ConsumerType.java
deleted file mode 100644
index ae116a1..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/ConsumerType.java
+++ /dev/null
@@ -1,16 +0,0 @@
-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.
- */
-@Documented
-@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
deleted file mode 100644
index 4389c77..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/Export.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package aQute.bnd.annotation;
-
-import java.lang.annotation.*;
-
-@Documented
-@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;
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/ProviderType.java b/bundleplugin/src/main/java/aQute/bnd/annotation/ProviderType.java
deleted file mode 100644
index 22edcea..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/ProviderType.java
+++ /dev/null
@@ -1,16 +0,0 @@
-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.
- */
-@Documented
-@Retention(RetentionPolicy.CLASS)
-@Target(ElementType.TYPE)
-public @interface ProviderType {
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/Version.java b/bundleplugin/src/main/java/aQute/bnd/annotation/Version.java
deleted file mode 100644
index a90c250..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/Version.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package aQute.bnd.annotation;
-
-import java.lang.annotation.*;
-
-@Documented
-@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
deleted file mode 100644
index e731669..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Activate.java
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index 1d733ac..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Component.java
+++ /dev/null
@@ -1,40 +0,0 @@
-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
deleted file mode 100644
index 9e10951..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/component/ConfigurationPolicy.java
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 60c7be4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Deactivate.java
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index ae36b7f..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Modified.java
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index 2a71bac..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/component/Reference.java
+++ /dev/null
@@ -1,33 +0,0 @@
-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
deleted file mode 100644
index ec0efd4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/component/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index cd6b831..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Configurable.java
+++ /dev/null
@@ -1,292 +0,0 @@
-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;
-					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;
-				}
-				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
deleted file mode 100644
index d7b6745..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/Meta.java
+++ /dev/null
@@ -1,171 +0,0 @@
-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
deleted file mode 100644
index ec0efd4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/metatype/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.43.1
diff --git a/bundleplugin/src/main/java/aQute/bnd/annotation/packageinfo b/bundleplugin/src/main/java/aQute/bnd/annotation/packageinfo
deleted file mode 100644
index ec0efd4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/annotation/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c56a8eb..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/CircularDependencyException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index f693ddb..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/Container.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package aQute.bnd.build;
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-
-public class Container {
-	public enum TYPE {
-		REPO, PROJECT, EXTERNAL, LIBRARY, ERROR
-	}
-
-	private final File			file;
-	private final String		path;
-	final TYPE					type;
-	final String				bsn;
-	final String				version;
-	final String				error;
-	final Project				project;
-	final DownloadBlocker		db;
-	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, DownloadBlocker db) {
-		this.bsn = bsn;
-		this.version = version;
-		this.type = type;
-		this.file = source != null ? source : new File("/" + bsn + ":" + version + ":" + type);
-		this.path = file.getAbsolutePath();
-		
-		this.project = project;
-		this.error = error;
-		if (attributes == null || attributes.isEmpty())
-			this.attributes = Collections.emptyMap();
-		else
-			this.attributes = attributes;
-		this.db = db;
-	}
-
-	public Container(Project project, File file) {
-		this(project, file.getName(), "project", TYPE.PROJECT, file, null, null, null);
-	}
-
-	public Container(File file, DownloadBlocker db) {
-		this(null, file.getName(), "project", TYPE.EXTERNAL, file, null, null, db);
-	}
-
-	public File getFile() {
-		if (db != null && db.getReason() != null) {
-			return new File(db.getReason() + ": " + file);
-		}
-		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(getFile());
-				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;
-	}
-
-	@Override
-	public boolean equals(Object other) {
-		if (other instanceof Container)
-			return path.equals(((Container) other).path);
-		return false;
-	}
-
-	@Override
-	public int hashCode() {
-		return path.hashCode();
-	}
-
-	public Project getProject() {
-		return project;
-	}
-
-	/**
-	 * Must show the file name or the error formatted as a file name
-	 * 
-	 * @return
-	 */
-	@Override
-	public String toString() {
-		if (getError() != null)
-			return "/error/" + getError();
-		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(getFile());
-				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/DownloadBlocker.java b/bundleplugin/src/main/java/aQute/bnd/build/DownloadBlocker.java
deleted file mode 100644
index 5b9b785..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/DownloadBlocker.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package aQute.bnd.build;
-
-import java.io.*;
-
-import aQute.bnd.service.*;
-import aQute.service.reporter.*;
-
-/**
- * This class is intended to be used by the users of a {@link RepositoryPlugin}.
- * The
- * {@link RepositoryPlugin#get(String, aQute.bnd.version.Version, java.util.Map, aQute.bnd.service.RepositoryPlugin.DownloadListener...)}
- * method takes one or more Download Listeners. These are called back with the
- * success or failure of a download. This class is a simple implementation of
- * this model, just call {@link #getReason()} and it blocks until success or
- * failure is called.
- */
-public class DownloadBlocker implements RepositoryPlugin.DownloadListener {
-	public enum Stage {
-		INIT, SUCCESS, FAILURE
-	};
-
-	private volatile Stage	stage	= Stage.INIT;
-	private String			failure;
-	private File			file;
-	private final Reporter	reporter;
-
-	public DownloadBlocker(Reporter reporter) {
-		this.reporter = reporter;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see
-	 * aQute.bnd.service.RepositoryPlugin.DownloadListener#success(java.io.File)
-	 */
-	public void success(File file) throws Exception {
-		synchronized (this) {
-			assert stage == Stage.INIT;
-			stage = Stage.SUCCESS;
-			this.file = file;
-			notifyAll();
-		}
-		if (reporter != null)
-			reporter.trace("successfully downloaded %s", file);
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see
-	 * aQute.bnd.service.RepositoryPlugin.DownloadListener#failure(java.io.File,
-	 * java.lang.String)
-	 */
-	public void failure(File file, String reason) throws Exception {
-		synchronized (this) {
-			assert stage == Stage.INIT;
-			stage = Stage.FAILURE;
-			this.failure = reason;
-			this.file = file;
-			notifyAll();
-		}
-		if (reporter != null)
-			reporter.error("Download %s %s", reason, file);
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see
-	 * aQute.bnd.service.RepositoryPlugin.DownloadListener#progress(java.io.
-	 * File, int)
-	 */
-	public boolean progress(File file, int percentage) throws Exception {
-		assert stage == Stage.INIT;
-		return true;
-	}
-
-	/**
-	 * Return a failure reason or null. This method will block until either
-	 * {@link #success(File)} or {@link #failure(File, String)} has been called.
-	 * It can be called many times.
-	 * 
-	 * @return null or a reason for a failure
-	 */
-	public synchronized String getReason() {
-		try {
-			while (stage == Stage.INIT)
-				wait();
-		}
-		catch (InterruptedException e) {
-			return "Interrupted";
-		}
-
-		return failure;
-	}
-
-	/**
-	 * Return the stage we're in
-	 * 
-	 * @return the current stage
-	 */
-	public Stage getStage() {
-		return stage;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see java.lang.Object#toString()
-	 */
-	public String toString() {
-		return "DownloadBlocker(" + stage + "," + file + ", " + failure + ")";
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Project.java b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
deleted file mode 100644
index b6377c6..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/Project.java
+++ /dev/null
@@ -1,2090 +0,0 @@
-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.locks.*;
-import java.util.jar.*;
-import java.util.regex.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.help.*;
-import aQute.bnd.maven.support.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.eclipse.*;
-import aQute.bnd.service.*;
-import aQute.bnd.service.RepositoryPlugin.PutResult;
-import aQute.bnd.service.action.*;
-import aQute.bnd.version.*;
-import aQute.lib.io.*;
-import aQute.libg.generics.*;
-import aQute.libg.reporter.*;
-import aQute.libg.sed.*;
-
-/**
- * This class is NOT threadsafe
- */
-
-public class Project extends Processor {
-
-	final static Pattern		VERSION_ANNOTATION		= Pattern.compile("@\\s*(:?aQute\\.bnd\\.annotation\\.)?Version\\s*\\(\\s*(:?value\\s*=\\s*)?\"(\\d+(:?\\.\\d+(:?\\.\\d+(:?\\.[\\d\\w-_]+)?)?)?)\"\\s*\\)");
-	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;
-	final ProjectMessages		msgs					= ReporterMessages.base(this, ProjectMessages.class);
-
-	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());
-		builder.setPedantic(isPedantic());
-		builder.setTrace(isTrace());
-		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;
-	}
-
-	@Override
-	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 = getOutput0();
-					if (!output.exists()) {
-						if (!output.mkdirs()) {
-							throw new IOException("Could not create directory " + output);
-						}
-						getWorkspace().changedFile(output);
-					}
-					if (!output.isDirectory())
-						msgs.NoOutputDirectory_(output);
-					else {
-						Container c = new Container(this, output);
-						if (!buildpath.contains(c))
-							buildpath.add(c);
-					}
-
-					// Where we store all our generated stuff.
-					target = getTarget0();
-
-					// 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.
-					// The values are possibly negated globbing patterns.
-
-					// dependencies.add( getWorkspace().getProject("cnf"));
-
-					String dp = getProperty(Constants.DEPENDSON);
-					Set<String> requiredProjectNames = new LinkedHashSet<String>(new Parameters(dp).keySet());
-					
-					//Allow DependencyConstributors to modify requiredProjectNames
-					List<DependencyContributor> dcs = getPlugins(DependencyContributor.class);
-					for (DependencyContributor dc : dcs)
-						dc.addDependencies(this, requiredProjectNames);
-					
-					Instructions is = new Instructions(requiredProjectNames);
-					
-					Set<Instruction> unused = new HashSet<Instruction>();
-					Collection<Project> projects = getWorkspace().getAllProjects();
-					Collection<Project> dependencies = is.select(projects, unused, false);
-					
-					for (Instruction u: unused) 
-						msgs.MissingDependson_(u.getInput());							
-						
-					// 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);
-		}
-	}
-
-	/**
-	 * @return
-	 */
-	private File getOutput0() {
-		return getFile(getProperty("bin", "bin")).getAbsoluteFile();
-	}
-
-	/**
-	 * 
-	 */
-	private File getTarget0() throws IOException {
-		File target = getFile(getProperty("target", "generated"));
-		if (!target.exists()) {
-			if (!target.mkdirs()) {
-				throw new IOException("Could not create directory " + target);
-			}
-			getWorkspace().changedFile(target);
-		}
-		return target;
-	}
-
-	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);
-		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 = removeDuplicateMarker(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, null);
-						} else {
-							msgs.NoSuchProject(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, null);
-						} else {
-							found = new Container(this, bsn, "file", Container.TYPE.EXTERNAL, f, error, attrs, null);
-						}
-					} 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: %s, dropped duplicate", cc);
-						else
-							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, null);
-					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);
-			msgs.CircularDependencyContext_Message_(getName(), message);
-		}
-		catch (Exception e) {
-			msgs.Unexpected_Error_(spec, e);
-		}
-		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);
-	}
-
-	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));
-	}
-
-	/**
-	 * 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())
-			msgs.MissingPom();
-		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, null);
-				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, null));
-		}
-		for (File f : eclipse.getBootclasspath()) {
-			bootclasspath.add(new Container(f, null));
-		}
-		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);
-	}
-
-	@Override
-	protected Object[] getMacroDomains() {
-		return new Object[] {
-			workspace
-		};
-	}
-
-	public File release(String jarName, InputStream jarStream) throws Exception {
-		String name = getProperty(Constants.RELEASEREPO);
-		return release(name, jarName, jarStream);
-	}
-
-	/**
-	 * Release
-	 * 
-	 * @param name
-	 *            The repository name
-	 * @param jarName
-	 * @param jarStream
-	 * @return
-	 * @throws Exception
-	 */
-	public File release(String name, String jarName, InputStream jarStream) 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 {
-				PutResult r = rp.put(jarStream, new RepositoryPlugin.PutOptions());
-				trace("Released %s to %s in repository %s", jarName, r.artifact, rp);
-			}
-			catch (Exception e) {
-				msgs.Release_Into_Exception_(jarName, rp, e);
-			}
-		} else if (name == null)
-			msgs.NoNameForReleaseRepository();
-		else
-			msgs.ReleaseRepository_NotFoundIn_(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) {
-			release(name, jar.getName(), new BufferedInputStream(new FileInputStream(jar)));
-		}
-	}
-
-	/**
-	 * 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) {
-			if (!Verifier.isVersion(range))
-				return new Container(this, bsn, range, Container.TYPE.ERROR, null, bsn + ";version=" + range
-						+ " Invalid version", null, null);
-
-			// For an exact range we just iterate over the repos
-			// and return the first we find.
-			Version version = new Version(range);
-			for (RepositoryPlugin plugin : plugins) {
-				DownloadBlocker blocker = new DownloadBlocker(this);
-				File result = plugin.get(bsn, version, attrs, blocker);
-				if (result != null)
-					return toContainer(bsn, range, attrs, result, blocker);
-			}
-		} 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 {
-					SortedSet<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)) {
-						Version version = new Version(range);
-						DownloadBlocker blocker = new DownloadBlocker(this);
-						File file = plugin.get(bsn, version, attrs, blocker);
-						// and the entry must exist
-						// if it does, return this as a result
-						if (file != null)
-							return toContainer(bsn, range, attrs, file, blocker);
-					}
-				}
-			}
-
-			// 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;
-					case EXACT :
-						// TODO need to handle exact better
-						break;
-				}
-				if (provider != null) {
-					RepositoryPlugin repo = versions.get(provider);
-					String version = provider.toString();
-					DownloadBlocker blocker = new DownloadBlocker(this);
-					File result = repo.get(bsn, provider, attrs, blocker);
-					if (result != null)
-						return toContainer(bsn, version, attrs, result, blocker);
-				} else
-					msgs.FoundVersions_ForStrategy_ButNoProvider(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, 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, DownloadBlocker db) {
-		File f = result;
-		if (f == null) {
-			msgs.ConfusedNoContainerFile();
-			f = new File("was null");
-		}
-		Container container;
-		if (f.getName().endsWith("lib"))
-			container = new Container(this, bsn, range, Container.TYPE.LIBRARY, f, null, attrs, db);
-		else
-			container = new Container(this, bsn, range, Container.TYPE.REPO, f, null, attrs, db);
-		
-		return container;
-	}
-
-	/**
-	 * 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) {
-			try {
-				rp.put(new BufferedInputStream(new FileInputStream(file)), new RepositoryPlugin.PutOptions());
-				return;
-			}
-			catch (Exception e) {
-				msgs.DeployingFile_On_Exception_(file, rp.getName(), e);
-			}
-			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) {
-			for (Deploy d : getPlugins(Deploy.class)) {
-				trace("Deploying %s to: %s", output.getName(), d);
-				try {
-					if (d.deploy(this, output.getName(), new BufferedInputStream(new FileInputStream(output))))
-						trace("deployed %s successfully to %s", output, d);
-				}
-				catch (Exception e) {
-					msgs.Deploying(e);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Macro access to the repository ${repo;<bsn>[;<version>[;<low|high>]]}
-	 */
-
-	static String	_repoHelp	= "${repo ';'<bsn> [ ; <version> [; ('HIGHEST'|'LOWEST')]}";
-
-	public String _repo(String args[]) throws Exception {
-		if (args.length < 2) {
-			msgs.RepoTooFewArguments(_repoHelp, args);
-			return null;
-		}
-
-		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
-					msgs.InvalidStrategy(_repoHelp, args);
-			}
-		}
-
-		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 {
-		if (workspace.isOffline()) {
-			trace("working %s offline, so always stale", this);
-			return true;
-		}
-
-		Set<Project> visited = new HashSet<Project>();
-		return isStale(visited);
-	}
-
-	boolean isStale(Set<Project> visited) throws Exception {
-		// When we do not generate anything ...
-		if (isNoBundles())
-			return false;
-
-		if (visited.contains(this)) {
-			msgs.CircularDependencyContext_Message_(this.getName(), visited.toString());
-			return false;
-		}
-
-		visited.add(this);
-
-		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 == this)
-				continue;
-
-			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;
-					}
-					files.add(ff);
-				}
-				return this.files = files.toArray(new File[files.size()]);
-			}
-			finally {
-				rdr.close();
-			}
-		}
-		if (buildIfAbsent)
-			return files = buildLocal(false);
-		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);
-		try {
-			if (underTest)
-				builder.setProperty(Constants.UNDERTEST, "true");
-			Jar jars[] = builder.builds();
-			File[] files = new File[jars.length];
-
-			getInfo(builder);
-
-			if (isOk()) {
-				this.files = files;
-
-				for (int i = 0; i < jars.length; i++) {
-					Jar jar = jars[i];
-					files[i] = saveBuild(jar);
-				}
-
-				// 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;
-			}
-			return null;
-		}
-		finally {
-			builder.close();
-		}
-	}
-
-	/**
-	 * 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();
-				File fp = f.getParentFile();
-				if (!fp.isDirectory()) {
-					if (!fp.exists() && !fp.mkdirs()) {
-						throw new IOException("Could not create directory " + fp);
-					}
-				}
-				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.
-	 */
-	@Override
-	public boolean refresh() {
-		boolean changed = false;
-		if (isCnf()) {
-			changed = workspace.refresh();
-		}
-		return super.refresh() || changed;
-	}
-
-	public boolean isCnf() {
-		return getBase().getName().equals(Workspace.CNFDIR);
-	}
-
-	@Override
-	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 = getTarget0();
-		if (target.isDirectory() && target.getParentFile() != null) {
-			IO.delete(target);
-			if (!target.exists() && !target.mkdirs()) {
-				throw new IOException("Could not create directory " + target);
-			}
-		}
-		File output = getOutput0();
-		if (getOutput().isDirectory())
-			IO.delete(output);
-		if (!output.exists() && !output.mkdirs()) {
-			throw new IOException("Could not create directory " + output);
-		}
-	}
-
-	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(@SuppressWarnings("unused")
-	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 {
-		final Macro macro = getReplacer();
-		Sed sed = new Sed(new Replacer() {
-			public String process(String line) {
-				return macro.process(line);
-			}
-		}, 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(@SuppressWarnings("unused")
-	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(@SuppressWarnings("unused")
-	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(@SuppressWarnings("unused")
-	String type, String script) throws Exception {
-		// TODO check tyiping
-		List<Scripter> scripters = getPlugins(Scripter.class);
-		if (scripters.isEmpty()) {
-			msgs.NoScripters_(script);
-			return;
-		}
-		@SuppressWarnings("rawtypes")
-		Map x = getProperties();
-		scripters.get(0).eval(x, new StringReader(script));
-	}
-
-	public String _repos(@SuppressWarnings("unused")
-	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.equals("example"))
-			return syntax.getExample();
-		if (what.equals("pattern"))
-			return syntax.getPattern();
-		if (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, 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, @SuppressWarnings("unused")
-	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)) {
-							msgs.IncompatibleHandler_For_(launcher, defaultHandler);
-						} 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);
-	}
-
-	/**
-	 * 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 {
-			Version current = getPackageInfoJavaVersion(packageName);
-			boolean packageInfoJava = false;
-			if (current != null) {
-				updatePackageInfoJavaFile(packageName, version);
-				packageInfoJava = true;
-			}
-			if (!packageInfoJava || getPackageInfoFile(packageName).exists()) {
-				updatePackageInfoFile(packageName, version);
-			}
-		}
-		catch (Exception e) {
-			msgs.SettingPackageInfoException_(e);
-		}
-	}
-
-	void updatePackageInfoJavaFile(String packageName, final Version newVersion) throws Exception {
-		File file = getPackageInfoJavaFile(packageName);
-
-		if (!file.exists()) {
-			return;
-		}
-
-		// 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;
-		}
-
-		Sed sed = new Sed(new Replacer() {
-			public String process(String line) {
-				Matcher m = VERSION_ANNOTATION.matcher(line);
-				if (m.find()) {
-					return line.substring(0, m.start(3)) + newVersion.toString() + line.substring(m.end(3));
-				}
-				return line;
-			}
-		}, file);
-
-		sed.replace(VERSION_ANNOTATION.pattern(), "$0");
-		sed.setBackup(false);
-		sed.doIt();
-	}
-
-	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 = getPackageInfoVersion(packageName);
-		if (oldVersion == null) {
-			oldVersion = Version.emptyVersion;
-		}
-
-		if (newVersion.compareTo(oldVersion) == 0) {
-			return;
-		}
-		PrintWriter pw = IO.writer(file);
-		pw.println("version " + newVersion);
-		pw.flush();
-		pw.close();
-
-		String path = packageName.replace('.', '/') + "/packageinfo";
-		File binary = IO.getFile(getOutput(), path);
-		File bp = binary.getParentFile();
-		if (!bp.exists() && !bp.mkdirs()) {
-			throw new IOException("Could not create directory " + bp);
-		}
-		IO.copy(file, binary);
-	}
-
-	File getPackageInfoFile(String packageName) {
-		String path = packageName.replace('.', '/') + "/packageinfo";
-		return IO.getFile(getSrc(), path);
-
-	}
-
-	File getPackageInfoJavaFile(String packageName) {
-		String path = packageName.replace('.', '/') + "/package-info.java";
-		return IO.getFile(getSrc(), path);
-
-	}
-
-	public Version getPackageInfo(String packageName) throws IOException {
-
-		Version version = getPackageInfoJavaVersion(packageName);
-		if (version != null) {
-			return version;
-		}
-		
-		version = getPackageInfoVersion(packageName);
-		if (version != null) {
-			return version;
-		}
-
-		return Version.emptyVersion;
-	}
-
-	Version getPackageInfoVersion(String packageName) throws IOException {
-		File packageInfoFile = getPackageInfoFile(packageName);
-		if (!packageInfoFile.exists()) {
-			return null;
-		}
-		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 null;
-	}
-
-	Version getPackageInfoJavaVersion(String packageName) throws IOException {
-		File packageInfoJavaFile = getPackageInfoJavaFile(packageName);
-		if (!packageInfoJavaFile.exists()) {
-			return null;
-		}
-		BufferedReader reader = null;
-		try {
-			reader = IO.reader(packageInfoJavaFile);
-			String line;
-			while ((line = reader.readLine()) != null) {
-				Matcher matcher = VERSION_ANNOTATION.matcher(line);
-				if (matcher.find()) {
-					return Version.parseVersion(matcher.group(3));
-				}
-			}
-		}
-		finally {
-			if (reader != null) {
-				IO.close(reader);
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * 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() && !f.isDirectory()) {
-			msgs.AddingNonExistentFileToClassPath_(f);
-		}
-		Container container = new Container(f, null);
-		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
deleted file mode 100644
index e551c9c..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/ProjectBuilder.java
+++ /dev/null
@@ -1,189 +0,0 @@
-package aQute.bnd.build;
-
-import java.io.*;
-import java.util.*;
-
-import aQute.bnd.differ.*;
-import aQute.bnd.differ.Baseline.Info;
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-import aQute.bnd.version.*;
-
-public class ProjectBuilder extends Builder {
-	private final DiffPluginImpl	differ	= new DiffPluginImpl();
-	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.
-	 */
-	@Override
-	protected Object[] getMacroDomains() {
-		return new Object[] {
-				project, project.getWorkspace()
-		};
-	}
-
-	@Override
-	public Builder getSubBuilder() throws Exception {
-		return project.getBuilder(this);
-	}
-
-	public Project getProject() {
-		return project;
-	}
-
-	@Override
-	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) {
-			msgs.Unexpected_Error_("ProjectBuilder init", e);
-		}
-	}
-
-	@Override
-	public List<Jar> getClasspath() {
-		init();
-		return super.getClasspath();
-	}
-
-	@Override
-	protected void changedFile(File f) {
-		project.getWorkspace().changedFile(f);
-	}
-
-	/**
-	 * Compare this builder's JAR with a baseline
-	 * 
-	 * @throws Exception
-	 */
-	@Override
-	protected void doBaseline(Jar dot) throws Exception {
-
-		Jar jar = getBaselineJar(false);
-		if (jar == null) {
-			return;
-		}
-		try {
-			Baseline baseline = new Baseline(this, differ);
-
-			Set<Info> infos = baseline.baseline(dot, jar, 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);
-				}
-			}
-		}
-		finally {
-			jar.close();
-		}
-	}
-
-	public Jar getBaselineJar(boolean fallback) throws Exception {
-
-		String baseline = getProperty(Constants.BASELINE);
-		String baselineRepo = getProperty(Constants.BASELINEREPO);
-		if ((baseline == null || baseline.trim().length() == 0) 
-				&& (baselineRepo == null || baselineRepo.trim().length() == 0) && !fallback)
-			return null;
-
-		File baselineFile = null;
-		if ((baseline == null || baseline.trim().length() == 0)) {
-			baselineFile = getBaselineFromRepo(fallback);
-			if (baselineFile != null)
-				trace("baseline %s", baselineFile.getName());
-		} else {
-
-			trace("baseline %s", baseline);
-
-			Collection<Container> bundles = project.getBundles(Strategy.LOWEST, baseline);
-			for (Container c : bundles) {
-
-				if (c.getError() != null || c.getFile() == null) {
-					error("Erroneous baseline bundle %s", c);
-					continue;
-				}
-
-				baselineFile = c.getFile();
-				break;
-			}
-		}
-		if (fallback && baselineFile == null) {
-			return new Jar(".");
-		}
-		return new Jar(baselineFile);
-	}
-
-	private File getBaselineFromRepo(boolean fallback) throws Exception {
-		String repoName = getProperty(Constants.BASELINEREPO);
-		if (repoName == null && !fallback)
-			return null;
-
-		if (repoName == null) {
-			repoName = getProperty(Constants.RELEASEREPO);
-			if (repoName == null) {
-				return null;
-			}
-		}
-
-		List<RepositoryPlugin> repos = getPlugins(RepositoryPlugin.class);
-		for (RepositoryPlugin repo : repos) {
-			if (repoName.equals(repo.getName())) {
-				SortedSet<Version> versions = repo.versions(getBsn());
-				if (!versions.isEmpty()) {
-					return repo.get(getBsn(), versions.last(), null);
-				}
-				break;
-			}
-		}
-		return null;
-
-	}
-
-	/** 
-	 * Gets the baseline Jar. 
-	 * 
-	 * @return the baseline jar
-	 * @throws Exception
-	 */
-	public Jar getBaselineJar() throws Exception {
-		return getBaselineJar(true);
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ProjectLauncher.java b/bundleplugin/src/main/java/aQute/bnd/build/ProjectLauncher.java
deleted file mode 100644
index 3507f53..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/ProjectLauncher.java
+++ /dev/null
@@ -1,367 +0,0 @@
-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.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-import aQute.libg.command.*;
-import aQute.libg.generics.*;
-
-/**
- * A Project Launcher is a base class to be extended by launchers. Launchers are
- * JARs that launch a framework and install a number of bundles and then run the
- * framework. A launcher jar must specify a Launcher-Class manifest header. This
- * class is instantiated and cast to a LauncherPlugin. This plug in is then
- * asked to provide a ProjectLauncher. This project launcher is then used by the
- * project to run the code. Launchers must extend this class.
- */
-public abstract class ProjectLauncher {
-	private final Project		project;
-	private long				timeout				= 0;
-	private final 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));
-
-		List<Container> fws = project.getBundles(Strategy.HIGHEST, project.getProperty(Constants.RUNFW), Constants.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(System.in, 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/ProjectMessages.java b/bundleplugin/src/main/java/aQute/bnd/build/ProjectMessages.java
deleted file mode 100644
index c2908a4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/ProjectMessages.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package aQute.bnd.build;
-
-import java.io.*;
-import java.util.*;
-
-import aQute.bnd.service.*;
-import aQute.bnd.version.*;
-import aQute.service.reporter.*;
-
-public interface ProjectMessages extends Messages {
-
-	ERROR InvalidStrategy(String help, String[] args);
-
-	ERROR RepoTooFewArguments(String help, String[] args);
-
-	ERROR AddingNonExistentFileToClassPath_(File f);
-
-	ERROR Deploying(Exception e);
-
-	ERROR DeployingFile_On_Exception_(File file, String name, Exception e);
-
-	ERROR MissingPom();
-
-	ERROR FoundVersions_ForStrategy_ButNoProvider(SortedMap<Version,RepositoryPlugin> versions, Strategy useStrategy);
-
-	ERROR NoSuchProject(String bsn, String spec);
-
-	ERROR CircularDependencyContext_Message_(String name, String message);
-
-	ERROR IncompatibleHandler_For_(String launcher, String defaultHandler);
-
-	ERROR NoOutputDirectory_(File output);
-
-	ERROR MissingDependson_(String p);
-
-	ERROR NoNameForReleaseRepository();
-
-	ERROR ReleaseRepository_NotFoundIn_(String name, List<RepositoryPlugin> plugins);
-
-	ERROR Release_Into_Exception_(String jar, RepositoryPlugin rp, Exception e);
-
-	ERROR NoScripters_(String script);
-
-	ERROR SettingPackageInfoException_(Exception e);
-
-	ERROR ConfusedNoContainerFile();
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ProjectTester.java b/bundleplugin/src/main/java/aQute/bnd/build/ProjectTester.java
deleted file mode 100644
index 4549624..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/ProjectTester.java
+++ /dev/null
@@ -1,76 +0,0 @@
-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 {
-		if (!reportDir.exists() && !reportDir.mkdirs()) {
-			throw new IOException("Could not create directory " + reportDir);
-		}
-		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
deleted file mode 100644
index 7a0f855..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/ReflectAction.java
+++ /dev/null
@@ -1,23 +0,0 @@
-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);
-	}
-
-	@Override
-	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
deleted file mode 100644
index 1a98e76..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/ResolverMode.java
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index cba37e6..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/ScriptAction.java
+++ /dev/null
@@ -1,18 +0,0 @@
-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
deleted file mode 100644
index be7a71c..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/Workspace.java
+++ /dev/null
@@ -1,423 +0,0 @@
-package aQute.bnd.build;
-
-import java.io.*;
-import java.lang.ref.*;
-import java.net.*;
-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.osgi.*;
-import aQute.bnd.service.*;
-import aQute.bnd.service.action.*;
-import aQute.lib.deployer.*;
-import aQute.lib.hex.*;
-import aQute.lib.io.*;
-import aQute.lib.settings.*;
-import aQute.service.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());
-	private boolean								offline		= true;
-	Settings									settings	= new Settings();
-
-	/**
-	 * 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();
-		if (!dir.exists() && !dir.mkdirs()) {
-			throw new IOException("Could not create directory " + dir);
-		}
-		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();
-	}
-
-	@Override
-	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(@SuppressWarnings("unused")
-	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 {
-				offline = false;
-				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);
-	}
-
-	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);
-		}
-
-		@Override
-		public String toString() {
-			return "bnd-cache";
-		}
-
-		@Override
-		protected boolean 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 (super.init()) {
-					inited = true;
-					if (!root.exists() && !root.mkdirs()) {
-						throw new IOException("Could not create cache directory " + root);
-					}
-					if (!root.isDirectory())
-						throw new IllegalArgumentException("Cache directory " + root + " not a directory");
-
-					InputStream in = getClass().getResourceAsStream(EMBEDDED_REPO);
-					if (in != null)
-						unzip(in, root);
-					else {
-						error("Couldn't find embedded-repo.jar in bundle ");
-					}
-					return true;
-				} else
-					return false;
-			}
-			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) {
-							File dp = dest.getParentFile();
-							if (!dp.exists() && !dp.mkdirs()) {
-								throw new IOException("Could not create directory " + dp);
-							}
-							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());
-	}
-
-	/**
-	 * Return if we're in offline mode. Offline mode is defined as an
-	 * environment where nobody tells us the resources are out of date (refresh
-	 * or changed). This is currently defined as having bndlisteners.
-	 * 
-	 * @return
-	 */
-	public boolean isOffline() {
-		return offline;
-	}
-
-	public Workspace setOffline(boolean on) {
-		this.offline = on;
-		return this;
-	}
-
-	/**
-	 * Provide access to the global settings of this machine.
-	 * 
-	 * @throws Exception
-	 * @throws UnknownHostException
-	 */
-
-	public String _global(String[] args) throws Exception {
-		Macro.verifyCommand(args, "${global;<name>[;<default>]}, get a global setting from ~/.bnd/settings.json", null,
-				2, 3);
-
-		String key = args[1];
-		if (key.equals("key.public"))
-			return Hex.toHexString(settings.getPublicKey());
-		if (key.equals("key.private"))
-			return Hex.toHexString(settings.getPrivateKey());
-
-		String s = settings.get(key);
-		if (s != null)
-			return s;
-
-		if (args.length == 3)
-			return args[2];
-		
-		return null;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/WorkspaceRepository.java b/bundleplugin/src/main/java/aQute/bnd/build/WorkspaceRepository.java
deleted file mode 100644
index 296a45a..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/WorkspaceRepository.java
+++ /dev/null
@@ -1,188 +0,0 @@
-package aQute.bnd.build;
-
-import java.io.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-import aQute.bnd.version.*;
-import aQute.lib.collections.*;
-import aQute.libg.glob.*;
-
-public class WorkspaceRepository implements RepositoryPlugin, Actionable {
-	private final Workspace	workspace;
-
-	public WorkspaceRepository(Workspace workspace) {
-		this.workspace = workspace;
-	}
-
-	private File[] get(String bsn, String range) throws Exception {
-		Collection<Project> projects = workspace.getAllProjects();
-		SortedMap<Version,File> foundVersion = new TreeMap<Version,File>();
-		for (Project project : projects) {
-			for (Builder builder : project.getSubBuilders()) {	
-				if (!bsn.equals(builder.getBsn())) {
-					continue;
-				}
-				Version version = new Version(builder.getVersion());
-				boolean exact = range.matches("[0-9]+\\.[0-9]+\\.[0-9]+\\..*");
-				if ("latest".equals(range) || matchVersion(range, version, exact)) {
-					File file = project.getOutputFile(bsn);
-					if (!file.exists()) {
-						Jar jar = builder.build();
-						if (jar == null) {
-							project.getInfo(builder);
-							continue;
-						}
-						file = project.saveBuild(jar);
-						jar.close();
-					}
-					foundVersion.put(version, file);
-				}
-			}
-		}
-
-		File[] result = new File[foundVersion.size()];
-		result = foundVersion.values().toArray(result);
-		if (!"latest".equals(range)) {
-			return result;
-		}
-		if (result.length > 0) {
-			return new File[] {
-				result[0]
-			};
-		}
-		return new File[0];
-	}
-
-	private File get(String bsn, String range, Strategy strategy, Map<String,String> properties) throws Exception {
-		File[] files = get(bsn, range);
-
-		if (files.length == 0) {
-			return null;
-		}
-
-		if (strategy == Strategy.EXACT) {
-			return files[0];
-		} else if (strategy == Strategy.HIGHEST) {
-			return files[files.length - 1];
-		} else if (strategy == Strategy.LOWEST) {
-			return files[0];
-		}
-
-		return null;
-	}
-
-	private boolean matchVersion(String range, Version version, boolean exact) {
-		if (range == null || range.trim().length() == 0)
-			return true;
-		VersionRange vr = new VersionRange(range);
-
-		boolean result;
-		if (exact) {
-			if (vr.isRange())
-				result = false;
-			else
-				result = vr.getHigh().equals(version);
-		} else {
-			result = vr.includes(version);
-		}
-		return result;
-	}
-
-	public boolean canWrite() {
-		return false;
-	}
-
-	public PutResult put(InputStream stream, PutOptions options) throws Exception {
-		throw new UnsupportedOperationException("Read only repository");
-	}
-
-	public List<String> list(String pattern) throws Exception {
-		List<String> names = new ArrayList<String>();
-		Collection<Project> projects = workspace.getAllProjects();
-		for (Project project : projects) {
-			for (Builder builder : project.getSubBuilders()) {	
-				String bsn = builder.getBsn();
-				if (pattern != null) {
-					Glob glob = new Glob(pattern);
-					Matcher matcher = glob.matcher(bsn);
-					if (matcher.matches()) {
-						if (!names.contains(bsn)) {
-							names.add(bsn);
-						}
-					}
-				} else {
-					if (!names.contains(bsn)) {
-						names.add(bsn);
-					}
-				}
-			}
-		}
-
-		return names;
-	}
-
-	public SortedSet<Version> versions(String bsn) throws Exception {
-		List<Version> versions = new ArrayList<Version>();
-		Collection<Project> projects = workspace.getAllProjects();
-		for (Project project : projects) {
-			for (Builder builder : project.getSubBuilders()) {
-				if (bsn.equals(builder.getBsn())) {
-					String v  = builder.getVersion();
-					if (v == null)
-						v = "0";
-					else if (!Verifier.isVersion(v))
-						continue; // skip
-					
-					versions.add(new Version(v));
-				}
-			}
-		}
-		if ( versions.isEmpty())
-			return SortedList.empty();
-		
-		return new SortedList<Version>(versions);
-	}
-
-	public String getName() {
-		return "Workspace " + workspace.getBase().getName();
-	}
-
-	public String getLocation() {
-		return workspace.getBase().getAbsolutePath();
-	}
-
-	public File get(String bsn, Version version, Map<String,String> properties, DownloadListener ... listeners) throws Exception {
-		File file = get(bsn, version.toString(), Strategy.EXACT, properties);
-		if ( file == null)
-			return null;
-		for (DownloadListener l : listeners) {
-			try {
-				l.success(file);
-			}
-			catch (Exception e) {
-				workspace.exception(e, "Workspace repo listener callback for %s" ,file);
-			}
-		}
-		return file;
-	}
-
-	
-	public Map<String,Runnable> actions(Object... target) throws Exception {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public String tooltip(Object... target) throws Exception {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public String title(Object... target) throws Exception {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/BndEditModel.java b/bundleplugin/src/main/java/aQute/bnd/build/model/BndEditModel.java
deleted file mode 100644
index 41b9ac9..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/BndEditModel.java
+++ /dev/null
@@ -1,809 +0,0 @@
-package aQute.bnd.build.model;
-
-import java.beans.*;
-import java.io.*;
-import java.util.*;
-import java.util.Map.Entry;
-
-import org.osgi.resource.*;
-
-import aQute.bnd.build.*;
-import aQute.bnd.build.model.clauses.*;
-import aQute.bnd.build.model.conversions.*;
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.properties.*;
-import aQute.bnd.version.*;
-import aQute.libg.tuple.*;
-
-/**
- * A model for a Bnd file. In the first iteration, use a simple Properties
- * object; this will need to be enhanced to additionally record formatting, e.g.
- * line breaks and empty lines, and comments.
- * 
- * @author Neil Bartlett
- */
-public class BndEditModel {
-
-	public static final String										NEWLINE_LINE_SEPARATOR		= "\\n\\\n\t";
-	public static final String										LIST_SEPARATOR				= ",\\\n\t";
-
-	private static final String									ISO_8859_1					= "ISO-8859-1";												//$NON-NLS-1$
-
-	private static String[]										KNOWN_PROPERTIES			= new String[] {
-			Constants.BUNDLE_LICENSE, Constants.BUNDLE_CATEGORY,
-			Constants.BUNDLE_NAME, Constants.BUNDLE_DESCRIPTION, Constants.BUNDLE_COPYRIGHT, Constants.BUNDLE_UPDATELOCATION,
-			Constants.BUNDLE_VENDOR, Constants.BUNDLE_CONTACTADDRESS, Constants.BUNDLE_DOCURL,
-			Constants.BUNDLE_SYMBOLICNAME, Constants.BUNDLE_VERSION, Constants.BUNDLE_ACTIVATOR,
-			Constants.EXPORT_PACKAGE, Constants.IMPORT_PACKAGE, aQute.bnd.osgi.Constants.PRIVATE_PACKAGE,
-			aQute.bnd.osgi.Constants.SOURCES,
-			aQute.bnd.osgi.Constants.SERVICE_COMPONENT, aQute.bnd.osgi.Constants.CLASSPATH,
-			aQute.bnd.osgi.Constants.BUILDPATH, aQute.bnd.osgi.Constants.BUILDPACKAGES,
-			aQute.bnd.osgi.Constants.RUNBUNDLES, aQute.bnd.osgi.Constants.RUNPROPERTIES, aQute.bnd.osgi.Constants.SUB,
-			aQute.bnd.osgi.Constants.RUNFRAMEWORK, aQute.bnd.osgi.Constants.RUNFW,
-			aQute.bnd.osgi.Constants.RUNVM,
-			// BndConstants.RUNVMARGS,
-			// BndConstants.TESTSUITES,
-			aQute.bnd.osgi.Constants.TESTCASES, aQute.bnd.osgi.Constants.PLUGIN, aQute.bnd.osgi.Constants.PLUGINPATH,
-			aQute.bnd.osgi.Constants.RUNREPOS, aQute.bnd.osgi.Constants.RUNREQUIRES, aQute.bnd.osgi.Constants.RUNEE};
-
-	public static final String										BUNDLE_VERSION_MACRO		= "${"
-																										+ Constants.BUNDLE_VERSION
-																										+ "}";
-
-	private final Map<String,Converter< ? extends Object,String>>	converters					= new HashMap<String,Converter< ? extends Object,String>>();
-	private final Map<String,Converter<String, ? extends Object>>	formatters					= new HashMap<String,Converter<String, ? extends Object>>();
-	// private final DataModelHelper obrModelHelper = new DataModelHelperImpl();
-
-	private final PropertyChangeSupport								propChangeSupport			= new PropertyChangeSupport(
-																										this);
-	private final Properties										properties					= new Properties();
-
-	private File													bndResource;
-	private String													bndResourceName;
-	private final Map<String,Object>								objectProperties			= new HashMap<String,Object>();
-	private final Map<String,String>								changesToSave				= new HashMap<String,String>();
-
-	// CONVERTERS
-	private Converter<List<VersionedClause>,String>				buildPathConverter			= new ClauseListConverter<VersionedClause>(
-																										new Converter<VersionedClause,Pair<String,Attrs>>() {
-																											public VersionedClause convert(
-																													Pair<String,Attrs> input)
-																													throws IllegalArgumentException {
-																												return new VersionedClause(
-																														input.getFirst(),
-																														input.getSecond());
-																											}
-																										});
-	private Converter<List<VersionedClause>,String>				buildPackagesConverter		= new ClauseListConverter<VersionedClause>(
-																										new Converter<VersionedClause,Pair<String,Attrs>>() {
-																											public VersionedClause convert(
-																													Pair<String,Attrs> input)
-																													throws IllegalArgumentException {
-																												return new VersionedClause(
-																														input.getFirst(),
-																														input.getSecond());
-																											}
-																										});
-	private Converter<List<VersionedClause>,String>				clauseListConverter			= new ClauseListConverter<VersionedClause>(
-																										new VersionedClauseConverter());
-	private Converter<String,String>								stringConverter				= new NoopConverter<String>();
-	private Converter<Boolean,String>								includedSourcesConverter	= new Converter<Boolean,String>() {
-																									public Boolean convert(
-																											String string)
-																											throws IllegalArgumentException {
-																										return Boolean
-																												.valueOf(string);
-																									}
-																								};
-	private Converter<List<String>,String>						listConverter				= SimpleListConverter
-																										.create();
-	private Converter<List<HeaderClause>,String>					headerClauseListConverter	= new HeaderClauseListConverter();
-	private ClauseListConverter<ExportedPackage>					exportPackageConverter		= new ClauseListConverter<ExportedPackage>(
-																										new Converter<ExportedPackage,Pair<String,Attrs>>() {
-																											public ExportedPackage convert(
-																													Pair<String,Attrs> input) {
-																												return new ExportedPackage(
-																														input.getFirst(),
-																														input.getSecond());
-																											}
-																										});
-	private Converter<List<ServiceComponent>,String>				serviceComponentConverter	= new ClauseListConverter<ServiceComponent>(
-																										new Converter<ServiceComponent,Pair<String,Attrs>>() {
-																											public ServiceComponent convert(
-																													Pair<String,Attrs> input)
-																													throws IllegalArgumentException {
-																												return new ServiceComponent(
-																														input.getFirst(),
-																														input.getSecond());
-																											}
-																										});
-	private Converter<List<ImportPattern>,String>					importPatternConverter		= new ClauseListConverter<ImportPattern>(
-																										new Converter<ImportPattern,Pair<String,Attrs>>() {
-																											public ImportPattern convert(
-																													Pair<String,Attrs> input)
-																													throws IllegalArgumentException {
-																												return new ImportPattern(
-																														input.getFirst(),
-																														input.getSecond());
-																											}
-																										});
-
-	private Converter<Map<String,String>,String>					propertiesConverter			= new PropertiesConverter();
-	
-	private Converter<List<Requirement>,String>					requirementListConverter	= new RequirementListConverter();
-	private Converter<EE,String>									eeConverter					= new EEConverter();
-
-	// Converter<ResolveMode, String> resolveModeConverter =
-	// EnumConverter.create(ResolveMode.class, ResolveMode.manual);
-
-	// FORMATTERS
-	private Converter<String,String>								newlineEscapeFormatter		= new NewlineEscapedStringFormatter();
-	private Converter<String,Boolean>								defaultFalseBoolFormatter	= new DefaultBooleanFormatter(
-																										false);
-	private Converter<String,Collection< ? >>						stringListFormatter			= new CollectionFormatter<Object>(
-																										LIST_SEPARATOR,
-																										(String) null);
-	private Converter<String,Collection< ? extends HeaderClause>>	headerClauseListFormatter	= new CollectionFormatter<HeaderClause>(
-																										LIST_SEPARATOR,
-																										new HeaderClauseFormatter(),
-																										null);
-	private Converter<String,Map<String,String>>					propertiesFormatter			= new MapFormatter(
-																										LIST_SEPARATOR,
-																										new PropertiesEntryFormatter(),
-																										null);
-	
-	private Converter<String,Collection< ? extends Requirement>>	requirementListFormatter	= new CollectionFormatter<Requirement>(
-																										LIST_SEPARATOR,
-																										new RequirementFormatter(),
-																										null);
-
-	private Converter<String,EE>									eeFormatter					= new EEFormatter();
-	private Converter<String,Collection< ? extends String>>			runReposFormatter			= new CollectionFormatter<String>(
-																										LIST_SEPARATOR,
-																										aQute.bnd.osgi.Constants.EMPTY_HEADER);
-
-	// Converter<String, ResolveMode> resolveModeFormatter =
-	// EnumFormatter.create(ResolveMode.class, ResolveMode.manual);
-
-	@SuppressWarnings("deprecation")
-	public BndEditModel() {
-		// register converters
-		converters.put(aQute.bnd.osgi.Constants.BUNDLE_LICENSE, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.BUNDLE_CATEGORY, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.BUNDLE_NAME, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.BUNDLE_DESCRIPTION, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.BUNDLE_COPYRIGHT, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.BUNDLE_UPDATELOCATION, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.BUNDLE_VENDOR, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.BUNDLE_CONTACTADDRESS, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.BUNDLE_DOCURL, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.BUILDPATH, buildPathConverter);
-		converters.put(aQute.bnd.osgi.Constants.BUILDPACKAGES, buildPackagesConverter);
-		converters.put(aQute.bnd.osgi.Constants.RUNBUNDLES, clauseListConverter);
-		converters.put(Constants.BUNDLE_SYMBOLICNAME, stringConverter);
-		converters.put(Constants.BUNDLE_VERSION, stringConverter);
-		converters.put(Constants.BUNDLE_ACTIVATOR, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.OUTPUT, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.SOURCES, includedSourcesConverter);
-		converters.put(aQute.bnd.osgi.Constants.PRIVATE_PACKAGE, listConverter);
-		converters.put(aQute.bnd.osgi.Constants.CLASSPATH, listConverter);
-		converters.put(Constants.EXPORT_PACKAGE, exportPackageConverter);
-		converters.put(aQute.bnd.osgi.Constants.SERVICE_COMPONENT, serviceComponentConverter);
-		converters.put(Constants.IMPORT_PACKAGE, importPatternConverter);
-		converters.put(aQute.bnd.osgi.Constants.RUNFRAMEWORK, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.RUNFW, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.SUB, listConverter);
-		converters.put(aQute.bnd.osgi.Constants.RUNPROPERTIES, propertiesConverter);
-		converters.put(aQute.bnd.osgi.Constants.RUNVM, stringConverter);
-		// converters.put(BndConstants.RUNVMARGS, stringConverter);
-		converters.put(aQute.bnd.osgi.Constants.TESTSUITES, listConverter);
-		converters.put(aQute.bnd.osgi.Constants.TESTCASES, listConverter);
-		converters.put(aQute.bnd.osgi.Constants.PLUGIN, headerClauseListConverter);
-		converters.put(aQute.bnd.osgi.Constants.RUNREQUIRES, requirementListConverter);
-		converters.put(aQute.bnd.osgi.Constants.RUNEE, eeConverter);
-		converters.put(aQute.bnd.osgi.Constants.RUNREPOS, listConverter);
-		// converters.put(BndConstants.RESOLVE_MODE, resolveModeConverter);
-
-		formatters.put(aQute.bnd.osgi.Constants.BUNDLE_LICENSE, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.BUNDLE_CATEGORY, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.BUNDLE_NAME, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.BUNDLE_DESCRIPTION, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.BUNDLE_COPYRIGHT, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.BUNDLE_UPDATELOCATION, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.BUNDLE_VENDOR, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.BUNDLE_CONTACTADDRESS, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.BUNDLE_DOCURL, newlineEscapeFormatter);
-
-		formatters.put(aQute.bnd.osgi.Constants.BUILDPATH, headerClauseListFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.BUILDPACKAGES, headerClauseListFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.RUNBUNDLES, headerClauseListFormatter);
-		formatters.put(Constants.BUNDLE_SYMBOLICNAME, newlineEscapeFormatter);
-		formatters.put(Constants.BUNDLE_VERSION, newlineEscapeFormatter);
-		formatters.put(Constants.BUNDLE_ACTIVATOR, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.OUTPUT, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.SOURCES, defaultFalseBoolFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.PRIVATE_PACKAGE, stringListFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.CLASSPATH, stringListFormatter);
-		formatters.put(Constants.EXPORT_PACKAGE, headerClauseListFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.SERVICE_COMPONENT, headerClauseListFormatter);
-		formatters.put(Constants.IMPORT_PACKAGE, headerClauseListFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.RUNFRAMEWORK, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.RUNFW, newlineEscapeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.SUB, stringListFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.RUNPROPERTIES, propertiesFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.RUNVM, newlineEscapeFormatter);
-		// formatters.put(BndConstants.RUNVMARGS, newlineEscapeFormatter);
-		// formatters.put(BndConstants.TESTSUITES, stringListFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.TESTCASES, stringListFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.PLUGIN, headerClauseListFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.RUNREQUIRES, requirementListFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.RUNEE, eeFormatter);
-		formatters.put(aQute.bnd.osgi.Constants.RUNREPOS, runReposFormatter);
-		// formatters.put(BndConstants.RESOLVE_MODE, resolveModeFormatter);
-	}
-
-	public void loadFrom(IDocument document) throws IOException {
-		InputStream inputStream = new ByteArrayInputStream(document.get().getBytes(ISO_8859_1));
-		loadFrom(inputStream);
-	}
-
-	public void loadFrom(File file) throws IOException {
-		loadFrom(new BufferedInputStream(new FileInputStream(file)));
-	}
-
-	public void loadFrom(InputStream inputStream) throws IOException {
-		try {
-			// Clear and load
-			properties.clear();
-			properties.load(inputStream);
-			objectProperties.clear();
-			changesToSave.clear();
-
-			// Fire property changes on all known property names
-			for (String prop : KNOWN_PROPERTIES) {
-				// null values for old and new forced the change to be fired
-				propChangeSupport.firePropertyChange(prop, null, null);
-			}
-		}
-		finally {
-			inputStream.close();
-		}
-
-	}
-
-	public void saveChangesTo(IDocument document) {
-		for (Iterator<Entry<String,String>> iter = changesToSave.entrySet().iterator(); iter.hasNext();) {
-			Entry<String,String> entry = iter.next();
-			iter.remove();
-
-			String propertyName = entry.getKey();
-			String stringValue = entry.getValue();
-
-			updateDocument(document, propertyName, stringValue);
-		}
-	}
-
-	private static IRegion findEntry(IDocument document, String name) throws Exception {
-		PropertiesLineReader reader = new PropertiesLineReader(document);
-		LineType type = reader.next();
-		while (type != LineType.eof) {
-			if (type == LineType.entry) {
-				String key = reader.key();
-				if (name.equals(key))
-					return reader.region();
-			}
-			type = reader.next();
-		}
-		return null;
-	}
-
-	private static void updateDocument(IDocument document, String name, String value) {
-		String newEntry;
-		if (value != null) {
-			StringBuilder buffer = new StringBuilder();
-			buffer.append(name).append(": ").append(value);
-			newEntry = buffer.toString();
-		} else {
-			newEntry = "";
-		}
-
-		try {
-			IRegion region = findEntry(document, name);
-			if (region != null) {
-				// Replace an existing entry
-				int offset = region.getOffset();
-				int length = region.getLength();
-
-				// If the replacement is empty, remove one extra character to
-				// the right, i.e. the following newline,
-				// unless this would take us past the end of the document
-				if (newEntry.length() == 0 && offset + length + 1 < document.getLength()) {
-					length++;
-				}
-				document.replace(offset, length, newEntry);
-			} else if (newEntry.length() > 0) {
-				// This is a new entry, put it at the end of the file
-
-				// Does the last line of the document have a newline? If not,
-				// we need to add one.
-				if (document.getLength() > 0 && document.getChar(document.getLength() - 1) != '\n')
-					newEntry = "\n" + newEntry;
-				document.replace(document.getLength(), 0, newEntry);
-			}
-		}
-		catch (Exception e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	}
-
-	public List<String> getAllPropertyNames() {
-		List<String> result = new ArrayList<String>(properties.size());
-
-		Enumeration<String> names = (Enumeration<String>) properties.propertyNames();
-
-		while (names.hasMoreElements()) {
-			result.add(names.nextElement());
-		}
-		return result;
-	}
-
-	public Object genericGet(String propertyName) {
-		Converter< ? extends Object,String> converter = converters.get(propertyName);
-		if (converter == null)
-			converter = new NoopConverter<String>();
-		return doGetObject(propertyName, converter);
-	}
-
-	public void genericSet(String propertyName, Object value) {
-		Object oldValue = genericGet(propertyName);
-		Converter<String,Object> formatter = (Converter<String,Object>) formatters.get(propertyName);
-		if (formatter == null)
-			formatter = new DefaultFormatter();
-		doSetObject(propertyName, oldValue, value, formatter);
-	}
-
-	public String getBundleLicense() {
-		return doGetObject(Constants.BUNDLE_LICENSE, stringConverter);
-	}
-
-	public void setBundleLicense(String bundleLicense) {
-		doSetObject(Constants.BUNDLE_LICENSE, getBundleLicense(), bundleLicense, newlineEscapeFormatter);
-	}
-
-	public String getBundleCategory() {
-		return doGetObject(Constants.BUNDLE_CATEGORY, stringConverter);
-	}
-
-	public void setBundleCategory(String bundleCategory) {
-		doSetObject(Constants.BUNDLE_CATEGORY, getBundleCategory(), bundleCategory, newlineEscapeFormatter);
-	}
-
-	public String getBundleName() {
-		return doGetObject(Constants.BUNDLE_NAME, stringConverter);
-	}
-
-	public void setBundleName(String bundleName) {
-		doSetObject(Constants.BUNDLE_NAME, getBundleName(), bundleName, newlineEscapeFormatter);
-	}
-
-	public String getBundleDescription() {
-		return doGetObject(Constants.BUNDLE_DESCRIPTION, stringConverter);
-	}
-
-	public void setBundleDescription(String bundleDescription) {
-		doSetObject(Constants.BUNDLE_DESCRIPTION, getBundleDescription(), bundleDescription, newlineEscapeFormatter);
-	}
-
-	public String getBundleCopyright() {
-		return doGetObject(Constants.BUNDLE_COPYRIGHT, stringConverter);
-	}
-
-	public void setBundleCopyright(String bundleCopyright) {
-		doSetObject(Constants.BUNDLE_COPYRIGHT, getBundleCopyright(), bundleCopyright, newlineEscapeFormatter);
-	}
-
-	public String getBundleUpdateLocation() {
-		return doGetObject(Constants.BUNDLE_UPDATELOCATION, stringConverter);
-	}
-
-	public void setBundleUpdateLocation(String bundleUpdateLocation) {
-		doSetObject(Constants.BUNDLE_UPDATELOCATION, getBundleUpdateLocation(), bundleUpdateLocation, newlineEscapeFormatter);
-	}
-
-	public String getBundleVendor() {
-		return doGetObject(Constants.BUNDLE_VENDOR, stringConverter);
-	}
-
-	public void setBundleVendor(String bundleVendor) {
-		doSetObject(Constants.BUNDLE_VENDOR, getBundleVendor(), bundleVendor, newlineEscapeFormatter);
-	}
-
-	public String getBundleContactAddress() {
-		return doGetObject(Constants.BUNDLE_CONTACTADDRESS, stringConverter);
-	}
-
-	public void setBundleContactAddress(String bundleContactAddress) {
-		doSetObject(Constants.BUNDLE_CONTACTADDRESS, getBundleContactAddress(), bundleContactAddress, newlineEscapeFormatter);
-	}
-
-	public String getBundleDocUrl() {
-		return doGetObject(Constants.BUNDLE_DOCURL, stringConverter);
-	}
-
-	public void setBundleDocUrl(String bundleDocUrl) {
-		doSetObject(Constants.BUNDLE_DOCURL, getBundleDocUrl(), bundleDocUrl, newlineEscapeFormatter);
-	}
-
-	public String getBundleSymbolicName() {
-		return doGetObject(Constants.BUNDLE_SYMBOLICNAME, stringConverter);
-	}
-
-	public void setBundleSymbolicName(String bundleSymbolicName) {
-		doSetObject(Constants.BUNDLE_SYMBOLICNAME, getBundleSymbolicName(), bundleSymbolicName, newlineEscapeFormatter);
-	}
-
-	public String getBundleVersionString() {
-		return doGetObject(Constants.BUNDLE_VERSION, stringConverter);
-	}
-
-	public void setBundleVersion(String bundleVersion) {
-		doSetObject(Constants.BUNDLE_VERSION, getBundleVersionString(), bundleVersion, newlineEscapeFormatter);
-	}
-
-	public String getBundleActivator() {
-		return doGetObject(Constants.BUNDLE_ACTIVATOR, stringConverter);
-	}
-
-	public void setBundleActivator(String bundleActivator) {
-		doSetObject(Constants.BUNDLE_ACTIVATOR, getBundleActivator(), bundleActivator, newlineEscapeFormatter);
-	}
-
-	public String getOutputFile() {
-		return doGetObject(aQute.bnd.osgi.Constants.OUTPUT, stringConverter);
-	}
-
-	public void setOutputFile(String name) {
-		doSetObject(aQute.bnd.osgi.Constants.OUTPUT, getOutputFile(), name, newlineEscapeFormatter);
-	}
-
-	public boolean isIncludeSources() {
-		return doGetObject(aQute.bnd.osgi.Constants.SOURCES, includedSourcesConverter);
-	}
-
-	public void setIncludeSources(boolean includeSources) {
-		boolean oldValue = isIncludeSources();
-		doSetObject(aQute.bnd.osgi.Constants.SOURCES, oldValue, includeSources, defaultFalseBoolFormatter);
-	}
-
-	public List<String> getPrivatePackages() {
-		return doGetObject(aQute.bnd.osgi.Constants.PRIVATE_PACKAGE, listConverter);
-	}
-
-	public void setPrivatePackages(List< ? extends String> packages) {
-		List<String> oldPackages = getPrivatePackages();
-		doSetObject(aQute.bnd.osgi.Constants.PRIVATE_PACKAGE, oldPackages, packages, stringListFormatter);
-	}
-
-	public List<ExportedPackage> getSystemPackages() {
-		return doGetObject(aQute.bnd.osgi.Constants.RUNSYSTEMPACKAGES, exportPackageConverter);
-	}
-
-	public void setSystemPackages(List< ? extends ExportedPackage> packages) {
-		List<ExportedPackage> oldPackages = getSystemPackages();
-		doSetObject(aQute.bnd.osgi.Constants.RUNSYSTEMPACKAGES, oldPackages, packages, headerClauseListFormatter);
-	}
-
-	public List<String> getClassPath() {
-		return doGetObject(aQute.bnd.osgi.Constants.CLASSPATH, listConverter);
-	}
-
-	public void addPrivatePackage(String packageName) {
-		List<String> packages = getPrivatePackages();
-		if (packages == null)
-			packages = new ArrayList<String>();
-		else
-			packages = new ArrayList<String>(packages);
-		packages.add(packageName);
-		setPrivatePackages(packages);
-	}
-
-	public void setClassPath(List< ? extends String> classPath) {
-		List<String> oldClassPath = getClassPath();
-		doSetObject(aQute.bnd.osgi.Constants.CLASSPATH, oldClassPath, classPath, stringListFormatter);
-	}
-
-	public List<ExportedPackage> getExportedPackages() {
-		return doGetObject(Constants.EXPORT_PACKAGE, exportPackageConverter);
-	}
-
-	public void setExportedPackages(List< ? extends ExportedPackage> exports) {
-		boolean referencesBundleVersion = false;
-
-		if (exports != null) {
-			for (ExportedPackage pkg : exports) {
-				String versionString = pkg.getVersionString();
-				if (versionString != null && versionString.indexOf(BUNDLE_VERSION_MACRO) > -1) {
-					referencesBundleVersion = true;
-				}
-			}
-		}
-		List<ExportedPackage> oldValue = getExportedPackages();
-		doSetObject(Constants.EXPORT_PACKAGE, oldValue, exports, headerClauseListFormatter);
-
-		if (referencesBundleVersion && getBundleVersionString() == null) {
-			setBundleVersion(Version.emptyVersion.toString());
-		}
-	}
-
-	public void addExportedPackage(ExportedPackage export) {
-		List<ExportedPackage> exports = getExportedPackages();
-		exports = (exports == null) ? new ArrayList<ExportedPackage>() : new ArrayList<ExportedPackage>(exports);
-		exports.add(export);
-		setExportedPackages(exports);
-	}
-
-	public List<String> getDSAnnotationPatterns() {
-		return doGetObject(aQute.bnd.osgi.Constants.DSANNOTATIONS, listConverter);
-	}
-
-	public void setDSAnnotationPatterns(List< ? extends String> patterns) {
-		List<String> oldValue = getDSAnnotationPatterns();
-		doSetObject(aQute.bnd.osgi.Constants.DSANNOTATIONS, oldValue, patterns, stringListFormatter);
-	}
-
-	public List<ServiceComponent> getServiceComponents() {
-		return doGetObject(aQute.bnd.osgi.Constants.SERVICE_COMPONENT, serviceComponentConverter);
-	}
-
-	public void setServiceComponents(List< ? extends ServiceComponent> components) {
-		List<ServiceComponent> oldValue = getServiceComponents();
-		doSetObject(aQute.bnd.osgi.Constants.SERVICE_COMPONENT, oldValue, components, headerClauseListFormatter);
-	}
-
-	public List<ImportPattern> getImportPatterns() {
-		return doGetObject(Constants.IMPORT_PACKAGE, importPatternConverter);
-	}
-
-	public void setImportPatterns(List< ? extends ImportPattern> patterns) {
-		List<ImportPattern> oldValue = getImportPatterns();
-		doSetObject(Constants.IMPORT_PACKAGE, oldValue, patterns, headerClauseListFormatter);
-	}
-
-	public List<VersionedClause> getBuildPath() {
-		return doGetObject(aQute.bnd.osgi.Constants.BUILDPATH, buildPathConverter);
-	}
-
-	public void setBuildPath(List< ? extends VersionedClause> paths) {
-		List<VersionedClause> oldValue = getBuildPath();
-		doSetObject(aQute.bnd.osgi.Constants.BUILDPATH, oldValue, paths, headerClauseListFormatter);
-	}
-
-	public List<VersionedClause> getBuildPackages() {
-		return doGetObject(aQute.bnd.osgi.Constants.BUILDPACKAGES, buildPackagesConverter);
-	}
-
-	public void setBuildPackages(List< ? extends VersionedClause> paths) {
-		List<VersionedClause> oldValue = getBuildPackages();
-		doSetObject(aQute.bnd.osgi.Constants.BUILDPACKAGES, oldValue, paths, headerClauseListFormatter);
-	}
-
-	public List<VersionedClause> getRunBundles() {
-		return doGetObject(aQute.bnd.osgi.Constants.RUNBUNDLES, clauseListConverter);
-	}
-
-	public void setRunBundles(List< ? extends VersionedClause> paths) {
-		List<VersionedClause> oldValue = getBuildPath();
-		doSetObject(aQute.bnd.osgi.Constants.RUNBUNDLES, oldValue, paths, headerClauseListFormatter);
-	}
-
-	public boolean isIncludedPackage(String packageName) {
-		final Collection<String> privatePackages = getPrivatePackages();
-		if (privatePackages != null) {
-			if (privatePackages.contains(packageName))
-				return true;
-		}
-		final Collection<ExportedPackage> exportedPackages = getExportedPackages();
-		if (exportedPackages != null) {
-			for (ExportedPackage pkg : exportedPackages) {
-				if (packageName.equals(pkg.getName())) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	public List<String> getSubBndFiles() {
-		return doGetObject(aQute.bnd.osgi.Constants.SUB, listConverter);
-	}
-
-	public void setSubBndFiles(List<String> subBndFiles) {
-		List<String> oldValue = getSubBndFiles();
-		doSetObject(aQute.bnd.osgi.Constants.SUB, oldValue, subBndFiles, stringListFormatter);
-	}
-
-	public Map<String,String> getRunProperties() {
-		return doGetObject(aQute.bnd.osgi.Constants.RUNPROPERTIES, propertiesConverter);
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see bndtools.editor.model.IBndModel#setRunProperties(java.util.Map)
-	 */
-	public void setRunProperties(Map<String,String> props) {
-		Map<String,String> old = getRunProperties();
-		doSetObject(aQute.bnd.osgi.Constants.RUNPROPERTIES, old, props, propertiesFormatter);
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see bndtools.editor.model.IBndModel#getRunVMArgs()
-	 */
-	public String getRunVMArgs() {
-		return doGetObject(aQute.bnd.osgi.Constants.RUNVM, stringConverter);
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see bndtools.editor.model.IBndModel#setRunVMArgs(java.lang.String)
-	 */
-	public void setRunVMArgs(String args) {
-		String old = getRunVMArgs();
-		doSetObject(aQute.bnd.osgi.Constants.RUNVM, old, args, newlineEscapeFormatter);
-	}
-
-	@SuppressWarnings("deprecation")
-	public List<String> getTestSuites() {
-		List<String> testCases = doGetObject(aQute.bnd.osgi.Constants.TESTCASES, listConverter);
-		testCases = testCases != null ? testCases : Collections.<String> emptyList();
-
-		List<String> testSuites = doGetObject(aQute.bnd.osgi.Constants.TESTSUITES, listConverter);
-		testSuites = testSuites != null ? testSuites : Collections.<String> emptyList();
-
-		List<String> result = new ArrayList<String>(testCases.size() + testSuites.size());
-		result.addAll(testCases);
-		result.addAll(testSuites);
-		return result;
-	}
-
-	@SuppressWarnings("deprecation")
-	public void setTestSuites(List<String> suites) {
-		List<String> old = getTestSuites();
-		doSetObject(aQute.bnd.osgi.Constants.TESTCASES, old, suites, stringListFormatter);
-		doSetObject(aQute.bnd.osgi.Constants.TESTSUITES, null, null, stringListFormatter);
-	}
-
-	public List<HeaderClause> getPlugins() {
-		return doGetObject(aQute.bnd.osgi.Constants.PLUGIN, headerClauseListConverter);
-	}
-
-	public void setPlugins(List<HeaderClause> plugins) {
-		List<HeaderClause> old = getPlugins();
-		doSetObject(aQute.bnd.osgi.Constants.PLUGIN, old, plugins, headerClauseListFormatter);
-	}
-
-	public List<String> getPluginPath() {
-		return doGetObject(aQute.bnd.osgi.Constants.PLUGINPATH, listConverter);
-	}
-
-	public void setPluginPath(List<String> pluginPath) {
-		List<String> old = getPluginPath();
-		doSetObject(aQute.bnd.osgi.Constants.PLUGINPATH, old, pluginPath, stringListFormatter);
-	}
-	
-    public List<String> getRunRepos() {
-        return doGetObject(aQute.bnd.osgi.Constants.RUNREPOS, listConverter);
-    }
-
-    public void setRunRepos(List<String> repos) {
-        List<String> old = getRunRepos();
-        doSetObject(aQute.bnd.osgi.Constants.RUNREPOS, old, repos, runReposFormatter);
-    }
-    
-    public String getRunFramework() {
-        return doGetObject(aQute.bnd.osgi.Constants.RUNFRAMEWORK, stringConverter);
-    }
-
-    public String getRunFw() {
-        return doGetObject(aQute.bnd.osgi.Constants.RUNFW, stringConverter);
-    }
-
-    public EE getEE() {
-        return doGetObject(aQute.bnd.osgi.Constants.RUNEE, eeConverter);
-    }
-
-    public void setEE(EE ee) {
-        EE old = getEE();
-        doSetObject(aQute.bnd.osgi.Constants.RUNEE, old, ee, eeFormatter);
-    }
-
-    
-    public void setRunFramework(String clause) {
-        assert (Constants.RUNFRAMEWORK_SERVICES.equals(clause.toLowerCase().trim()) ||
-                Constants.RUNFRAMEWORK_NONE.equals(clause.toLowerCase().trim()));
-        String oldValue = getRunFramework();
-        doSetObject(aQute.bnd.osgi.Constants.RUNFRAMEWORK, oldValue, clause, newlineEscapeFormatter);
-    }
-    
-    public void setRunFw(String clause) {
-        String oldValue = getRunFw();
-        doSetObject(aQute.bnd.osgi.Constants.RUNFW, oldValue, clause, newlineEscapeFormatter);
-    }
-
-    public List<Requirement> getRunRequires() {
-    	return doGetObject(aQute.bnd.osgi.Constants.RUNREQUIRES, requirementListConverter);
-    }
-    
-    public void setRunRequires(List<Requirement> requires) {
-    	List<Requirement> oldValue = getRunRequires();
-    	doSetObject(aQute.bnd.osgi.Constants.RUNREQUIRES, oldValue, requires, requirementListFormatter);
-    }
-
-
-	private <R> R doGetObject(String name, Converter< ? extends R, ? super String> converter) {
-		R result;
-		if (objectProperties.containsKey(name)) {
-			R temp = (R) objectProperties.get(name);
-			result = temp;
-		} else if (changesToSave.containsKey(name)) {
-			result = converter.convert(changesToSave.get(name));
-			objectProperties.put(name, result);
-		} else if (properties.containsKey(name)) {
-			result = converter.convert(properties.getProperty(name));
-			objectProperties.put(name, result);
-		} else {
-			result = null;
-		}
-		return result;
-	}
-
-	private <T> void doSetObject(String name, T oldValue, T newValue, Converter<String, ? super T> formatter) {
-		objectProperties.put(name, newValue);
-		changesToSave.put(name, formatter.convert(newValue));
-		propChangeSupport.firePropertyChange(name, oldValue, newValue);
-	}
-
-	public boolean isProjectFile() {
-		return Project.BNDFILE.equals(getBndResourceName());
-	}
-
-	public boolean isBndrun() {
-		return getBndResourceName().endsWith(Constants.DEFAULT_BNDRUN_EXTENSION);
-	}
-
-	public void addPropertyChangeListener(PropertyChangeListener listener) {
-		propChangeSupport.addPropertyChangeListener(listener);
-	}
-
-	public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
-		propChangeSupport.addPropertyChangeListener(propertyName, listener);
-	}
-
-	public void removePropertyChangeListener(PropertyChangeListener listener) {
-		propChangeSupport.removePropertyChangeListener(listener);
-	}
-
-	public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
-		propChangeSupport.removePropertyChangeListener(propertyName, listener);
-	}
-
-	public void setBndResource(File bndResource) {
-		this.bndResource = bndResource;
-	}
-
-	public File getBndResource() {
-		return bndResource;
-	}
-
-	public String getBndResourceName() {
-		if (bndResourceName == null)
-			return "";
-		return bndResourceName;
-	}
-
-	public void setBndResourceName(String bndResourceName) {
-		this.bndResourceName = bndResourceName;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/EE.java b/bundleplugin/src/main/java/aQute/bnd/build/model/EE.java
deleted file mode 100644
index e7188a9..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/EE.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package aQute.bnd.build.model;
-
-public enum EE {
-
-    OSGI_Minimum_1_0("OSGi/Minimum-1.0"), OSGI_Minimum_1_1("OSGi/Minimum-1.1", OSGI_Minimum_1_0), OSGI_Minimum_1_2("OSGi/Minimum-1.2", OSGI_Minimum_1_0, OSGI_Minimum_1_1),
-
-    JRE_1_1("JRE-1.1"), J2SE_1_2("J2SE-1.2", JRE_1_1), J2SE_1_3("J2SE-1.3", JRE_1_1, J2SE_1_2, OSGI_Minimum_1_0, OSGI_Minimum_1_1), J2SE_1_4("J2SE-1.4", JRE_1_1, J2SE_1_2, J2SE_1_3, OSGI_Minimum_1_0, OSGI_Minimum_1_1, OSGI_Minimum_1_2), J2SE_1_5(
-            "J2SE-1.5", JRE_1_1, J2SE_1_2, J2SE_1_3, J2SE_1_4, OSGI_Minimum_1_0, OSGI_Minimum_1_1, OSGI_Minimum_1_2),
-
-    JavaSE_1_6("JavaSE-1.6", JRE_1_1, J2SE_1_2, J2SE_1_3, J2SE_1_4, J2SE_1_5, OSGI_Minimum_1_0, OSGI_Minimum_1_1, OSGI_Minimum_1_2), JavaSE_1_7("JavaSE-1.7", JRE_1_1, J2SE_1_2, J2SE_1_3, J2SE_1_4, J2SE_1_5, JavaSE_1_6, OSGI_Minimum_1_0,
-            OSGI_Minimum_1_1, OSGI_Minimum_1_2), JavaSE_1_8("JavaSE-1.8", JRE_1_1, J2SE_1_2, J2SE_1_3, J2SE_1_4, J2SE_1_5, JavaSE_1_6, JavaSE_1_7, OSGI_Minimum_1_0, OSGI_Minimum_1_1, OSGI_Minimum_1_2), JavaSE_1_9("JavaSE-1.9", JRE_1_1,
-            J2SE_1_2, J2SE_1_3, J2SE_1_4, J2SE_1_5, JavaSE_1_6, JavaSE_1_7, JavaSE_1_8, OSGI_Minimum_1_0, OSGI_Minimum_1_1, OSGI_Minimum_1_2);
-
-    private final String eeName;
-    private final EE[] compatible;
-
-    EE(String name, EE... compatible) {
-        eeName = name;
-        this.compatible = compatible;
-    }
-
-    public String getEEName() {
-        return eeName;
-    }
-
-    /**
-     * @return An array of EEs that this EE implicitly offers, through backwards compatibility.
-     */
-    public EE[] getCompatible() {
-        return compatible != null ? compatible : new EE[0];
-    }
-
-    public static EE parse(String str) {
-        for (EE ee : values()) {
-            if (ee.eeName.equals(str))
-                return ee;
-        }
-        throw new IllegalArgumentException("Unrecognised execution environment name: " + str);
-    }
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ComponentSvcReference.java b/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ComponentSvcReference.java
deleted file mode 100644
index 66272d6..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ComponentSvcReference.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package aQute.bnd.build.model.clauses;
-
-public class ComponentSvcReference implements Cloneable {
-
-	private String	name;
-	private String	bind;
-	private String	unbind;
-	private String	serviceClass;
-	private boolean	optional;
-	private boolean	multiple;
-	private boolean	dynamic;
-	private String	targetFilter;
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String getBind() {
-		return bind;
-	}
-
-	public void setBind(String bind) {
-		this.bind = bind;
-	}
-
-	public String getUnbind() {
-		return unbind;
-	}
-
-	public void setUnbind(String unbind) {
-		this.unbind = unbind;
-	}
-
-	public String getServiceClass() {
-		return serviceClass;
-	}
-
-	public void setServiceClass(String serviceClass) {
-		this.serviceClass = serviceClass;
-	}
-
-	public boolean isOptional() {
-		return optional;
-	}
-
-	public void setOptional(boolean optional) {
-		this.optional = optional;
-	}
-
-	public boolean isMultiple() {
-		return multiple;
-	}
-
-	public void setMultiple(boolean multiple) {
-		this.multiple = multiple;
-	}
-
-	public boolean isDynamic() {
-		return dynamic;
-	}
-
-	public void setDynamic(boolean dynamic) {
-		this.dynamic = dynamic;
-	}
-
-	public String getTargetFilter() {
-		return targetFilter;
-	}
-
-	public void setTargetFilter(String targetFilter) {
-		this.targetFilter = targetFilter;
-	}
-
-	@Override
-	public ComponentSvcReference clone() {
-		ComponentSvcReference copy = new ComponentSvcReference();
-		copy.name = this.name;
-		copy.serviceClass = this.serviceClass;
-		copy.bind = this.bind;
-		copy.unbind = this.unbind;
-		copy.optional = this.optional;
-		copy.multiple = this.multiple;
-		copy.dynamic = this.dynamic;
-		copy.targetFilter = this.targetFilter;
-		return copy;
-	}
-
-	public void copyFrom(ComponentSvcReference other) {
-		this.name = other.name;
-		this.serviceClass = other.serviceClass;
-		this.bind = other.bind;
-		this.unbind = other.unbind;
-		this.optional = other.optional;
-		this.multiple = other.multiple;
-		this.dynamic = other.dynamic;
-		this.targetFilter = other.targetFilter;
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ExportedPackage.java b/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ExportedPackage.java
deleted file mode 100644
index 47b37bd..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ExportedPackage.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package aQute.bnd.build.model.clauses;
-
-import org.osgi.framework.*;
-
-import aQute.bnd.header.*;
-
-public class ExportedPackage extends HeaderClause {
-
-	public ExportedPackage(String packageName, Attrs attribs) {
-		super(packageName, attribs);
-	}
-
-	@Override
-	protected boolean newlinesBetweenAttributes() {
-		return false;
-	}
-
-	public void setVersionString(String version) {
-		attribs.put(Constants.VERSION_ATTRIBUTE, version);
-	}
-
-	public String getVersionString() {
-		return attribs.get(Constants.VERSION_ATTRIBUTE);
-	}
-
-	public boolean isProvided() {
-		return Boolean.valueOf(attribs.get(aQute.bnd.osgi.Constants.PROVIDE_DIRECTIVE));
-	}
-
-	public void setProvided(boolean provided) {
-		if (provided)
-			attribs.put(aQute.bnd.osgi.Constants.PROVIDE_DIRECTIVE, Boolean.toString(true));
-		else
-			attribs.remove(aQute.bnd.osgi.Constants.PROVIDE_DIRECTIVE);
-	}
-
-	@Override
-	public ExportedPackage clone() {
-		return new ExportedPackage(this.name, new Attrs(this.attribs));
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/HeaderClause.java b/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/HeaderClause.java
deleted file mode 100644
index 4af4dde..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/HeaderClause.java
+++ /dev/null
@@ -1,153 +0,0 @@
-package aQute.bnd.build.model.clauses;
-
-import java.util.*;
-import java.util.Map.Entry;
-
-import aQute.bnd.header.*;
-
-public class HeaderClause implements Cloneable, Comparable<HeaderClause> {
-
-	private static final String	INTERNAL_LIST_SEPARATOR				= ";";
-	private static final String	INTERNAL_LIST_SEPARATOR_NEWLINES	= INTERNAL_LIST_SEPARATOR + "\\\n\t\t";
-
-	protected String			name;
-	protected Attrs				attribs;
-
-	public HeaderClause(String name, Attrs attribs) {
-		assert name != null;
-		assert attribs != null;
-
-		this.name = name;
-		this.attribs = attribs;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public Attrs getAttribs() {
-		return attribs;
-	}
-
-	public List<String> getListAttrib(String attrib) {
-		String string = attribs.get(attrib);
-		if (string == null)
-			return null;
-
-		List<String> result = new ArrayList<String>();
-		StringTokenizer tokenizer = new StringTokenizer(string, ",");
-		while (tokenizer.hasMoreTokens()) {
-			result.add(tokenizer.nextToken().trim());
-		}
-
-		return result;
-	}
-
-	public void setListAttrib(String attrib, Collection< ? extends String> value) {
-		if (value == null || value.isEmpty())
-			attribs.remove(attrib);
-		else {
-			StringBuilder buffer = new StringBuilder();
-			boolean first = true;
-			for (String string : value) {
-				if (!first)
-					buffer.append(',');
-				buffer.append(string);
-				first = false;
-			}
-			attribs.put(attrib, buffer.toString());
-		}
-	}
-
-	public void formatTo(StringBuilder buffer) {
-		formatTo(buffer, null);
-	}
-
-	public void formatTo(StringBuilder buffer, Comparator<Entry<String,String>> sorter) {
-		String separator = newlinesBetweenAttributes() ? INTERNAL_LIST_SEPARATOR_NEWLINES : INTERNAL_LIST_SEPARATOR;
-		buffer.append(name);
-		if (attribs != null) {
-			Set<Entry<String,String>> set;
-			if (sorter != null) {
-				set = new TreeSet<Map.Entry<String,String>>(sorter);
-				set.addAll(attribs.entrySet());
-			} else {
-				set = attribs.entrySet();
-			}
-
-			for (Iterator<Entry<String,String>> iter = set.iterator(); iter.hasNext();) {
-				Entry<String,String> entry = iter.next();
-				String name = entry.getKey();
-				String value = entry.getValue();
-
-				if (value != null && value.length() > 0) {
-					buffer.append(separator);
-
-					// If the value contains any comma or equals, then quote the
-					// whole thing
-					if (value.indexOf(',') > -1 || value.indexOf('=') > -1)
-						value = "'" + value + "'";
-
-					buffer.append(name).append('=').append(value);
-				}
-			}
-		}
-	}
-
-	protected boolean newlinesBetweenAttributes() {
-		return false;
-	}
-
-	@Override
-	public HeaderClause clone() {
-		try {
-			HeaderClause clone = (HeaderClause) super.clone();
-			clone.name = this.name;
-			clone.attribs = new Attrs(this.attribs);
-			return clone;
-		}
-		catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-	public int compareTo(HeaderClause other) {
-		return this.name.compareTo(other.name);
-	}
-
-	@SuppressWarnings("deprecation")
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((attribs == null) ? 0 : attribs.hashCode());
-		result = prime * result + ((name == null) ? 0 : name.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		HeaderClause other = (HeaderClause) obj;
-		if (attribs == null) {
-			if (other.attribs != null)
-				return false;
-		} else if (!attribs.isEqual(other.attribs))
-			return false;
-		if (name == null) {
-			if (other.name != null)
-				return false;
-		} else if (!name.equals(other.name))
-			return false;
-		return true;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ImportPattern.java b/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ImportPattern.java
deleted file mode 100644
index bdca772..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ImportPattern.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package aQute.bnd.build.model.clauses;
-
-import org.osgi.framework.*;
-
-import aQute.bnd.header.*;
-
-public class ImportPattern extends VersionedClause implements Cloneable {
-
-	public ImportPattern(String pattern, Attrs attributes) {
-		super(pattern, attributes);
-	}
-
-	public boolean isOptional() {
-		String resolution = attribs.get(aQute.bnd.osgi.Constants.RESOLUTION_DIRECTIVE);
-		return Constants.RESOLUTION_OPTIONAL.equals(resolution);
-	}
-
-	public void setOptional(boolean optional) {
-		if (optional)
-			attribs.put(aQute.bnd.osgi.Constants.RESOLUTION_DIRECTIVE, Constants.RESOLUTION_OPTIONAL);
-		else
-			attribs.remove(aQute.bnd.osgi.Constants.RESOLUTION_DIRECTIVE);
-	}
-
-	@Override
-	public ImportPattern clone() {
-		return new ImportPattern(this.name, new Attrs(this.attribs));
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ServiceComponent.java b/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ServiceComponent.java
deleted file mode 100644
index d8e4c6b..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/ServiceComponent.java
+++ /dev/null
@@ -1,249 +0,0 @@
-package aQute.bnd.build.model.clauses;
-
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.regex.*;
-
-import aQute.bnd.header.*;
-
-public class ServiceComponent extends HeaderClause implements Cloneable {
-
-	// v1.0.0 attributes
-	// 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:";
-
-	// v1.1.0 attributes
-	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:";
-
-	private final static Pattern	REFERENCE_PATTERN				= Pattern.compile("([^(]+)(\\(.+\\))?");
-
-	public ServiceComponent(String name, Attrs attribs) {
-		super(name, attribs);
-	}
-
-	public boolean isPath() {
-		return name.indexOf('/') >= 0 || name.endsWith(".xml");
-	}
-
-	private Set<String> getStringSet(String attrib) {
-		List<String> list = getListAttrib(attrib);
-		return list != null ? new HashSet<String>(list) : new HashSet<String>();
-	}
-
-	public void setPropertiesMap(Map<String,String> properties) {
-		List<String> strings = new ArrayList<String>(properties.size());
-		for (Entry<String,String> entry : properties.entrySet()) {
-			String line = new StringBuilder().append(entry.getKey()).append("=").append(entry.getValue()).toString();
-			strings.add(line);
-		}
-		setListAttrib(COMPONENT_PROPERTIES, strings);
-	}
-
-	public Map<String,String> getPropertiesMap() {
-		Map<String,String> result = new LinkedHashMap<String,String>();
-
-		List<String> list = getListAttrib(COMPONENT_PROPERTIES);
-		if (list != null) {
-			for (String entryStr : list) {
-				String name;
-				String value;
-
-				int index = entryStr.lastIndexOf('=');
-				if (index == -1) {
-					name = entryStr;
-					value = null;
-				} else {
-					name = entryStr.substring(0, index);
-					value = entryStr.substring(index + 1);
-				}
-
-				result.put(name, value);
-			}
-		}
-
-		return result;
-	}
-
-	public void setSvcRefs(List< ? extends ComponentSvcReference> refs) {
-		// First remove all existing references, i.e. non-directives
-		for (Iterator<String> iter = attribs.keySet().iterator(); iter.hasNext();) {
-			String name = iter.next();
-			if (!name.endsWith(":")) {
-				iter.remove();
-			}
-		}
-
-		// Add in the references
-		Set<String> dynamic = new HashSet<String>();
-		Set<String> optional = new HashSet<String>();
-		Set<String> multiple = new HashSet<String>();
-		for (ComponentSvcReference ref : refs) {
-			// Build the reference name with bind and unbind
-			String expandedRefName = ref.getName();
-			if (ref.getBind() != null) {
-				expandedRefName += "/" + ref.getBind();
-				if (ref.getUnbind() != null) {
-					expandedRefName += "/" + ref.getUnbind();
-				}
-			}
-
-			// Start building the map value
-			StringBuilder buffer = new StringBuilder();
-			buffer.append(ref.getServiceClass());
-
-			// Add the target filter
-			if (ref.getTargetFilter() != null) {
-				buffer.append('(').append(ref.getTargetFilter()).append(')');
-			}
-
-			// Work out the cardinality suffix (i.e. *, +, ? org ~).
-			// Adding to the dynamic/multiple/optional lists for non-standard
-			// cases
-			String cardinalitySuffix;
-			if (ref.isDynamic()) {
-				if (ref.isOptional()) {
-					if (ref.isMultiple()) // 0..n dynamic
-						cardinalitySuffix = "*";
-					else
-						// 0..1 dynamic
-						cardinalitySuffix = "?";
-				} else {
-					if (ref.isMultiple()) // 1..n dynamic
-						cardinalitySuffix = "+";
-					else { // 1..1 dynamic, not a normal combination
-						cardinalitySuffix = null;
-						dynamic.add(ref.getName());
-					}
-				}
-			} else {
-				if (ref.isOptional()) {
-					if (ref.isMultiple()) { // 0..n static, not a normal
-											// combination
-						cardinalitySuffix = null;
-						optional.add(ref.getName());
-						multiple.add(ref.getName());
-					} else { // 0..1 static
-						cardinalitySuffix = "~";
-					}
-				} else {
-					if (ref.isMultiple()) { // 1..n static, not a normal
-											// combination
-						multiple.add(ref.getName());
-						cardinalitySuffix = null;
-					} else { // 1..1 static
-						cardinalitySuffix = null;
-					}
-				}
-			}
-
-			if (cardinalitySuffix != null)
-				buffer.append(cardinalitySuffix);
-
-			// Write to the map
-			attribs.put(expandedRefName, buffer.toString());
-		}
-		setListAttrib(COMPONENT_OPTIONAL, optional);
-		setListAttrib(COMPONENT_MULTIPLE, multiple);
-		setListAttrib(COMPONENT_DYNAMIC, dynamic);
-	}
-
-	public List<ComponentSvcReference> getSvcRefs() {
-		List<ComponentSvcReference> result = new ArrayList<ComponentSvcReference>();
-
-		Set<String> dynamicSet = getStringSet(COMPONENT_DYNAMIC);
-		Set<String> optionalSet = getStringSet(COMPONENT_OPTIONAL);
-		Set<String> multipleSet = getStringSet(COMPONENT_MULTIPLE);
-
-		for (Entry<String,String> entry : attribs.entrySet()) {
-			String referenceName = entry.getKey();
-
-			// Skip directives
-			if (referenceName.endsWith(":"))//$NON-NLS-1$
-				continue;
-
-			ComponentSvcReference svcRef = new ComponentSvcReference();
-
-			String bind = null;
-			String unbind = null;
-
-			if (referenceName.indexOf('/') >= 0) {
-				String parts[] = referenceName.split("/");
-				referenceName = parts[0];
-				bind = parts[1];
-				if (parts.length > 2)
-					unbind = parts[2];
-				/*
-				 * else if (bind.startsWith("add")) unbind =
-				 * bind.replaceAll("add(.+)", "remove$1"); else unbind = "un" +
-				 * bind; } else if
-				 * (Character.isLowerCase(referenceName.charAt(0))) { bind =
-				 * "set" + Character.toUpperCase(referenceName.charAt(0)) +
-				 * referenceName.substring(1); unbind = "un" + bind;
-				 */
-			}
-			svcRef.setName(referenceName);
-			svcRef.setBind(bind);
-			svcRef.setUnbind(unbind);
-
-			String interfaceName = entry.getValue();
-			if (interfaceName == null || interfaceName.length() == 0) {
-				continue;
-			}
-			svcRef.setServiceClass(interfaceName);
-
-			// Check the 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 == '~')
-					optionalSet.add(referenceName);
-				if (c == '+' || c == '*')
-					multipleSet.add(referenceName);
-				if (c == '+' || c == '*' || c == '?')
-					dynamicSet.add(referenceName);
-				interfaceName = interfaceName.substring(0, interfaceName.length() - 1);
-			}
-			svcRef.setOptional(optionalSet.contains(referenceName));
-			svcRef.setMultiple(multipleSet.contains(referenceName));
-			svcRef.setDynamic(dynamicSet.contains(referenceName));
-
-			// Parse the target from the interface name
-			// The target is a filter.
-			String target = null;
-			Matcher m = REFERENCE_PATTERN.matcher(interfaceName);
-			if (m.matches()) {
-				interfaceName = m.group(1);
-				target = m.group(2);
-			}
-			svcRef.setTargetFilter(target);
-
-			result.add(svcRef);
-		}
-
-		return result;
-	}
-
-	@Override
-	public ServiceComponent clone() {
-		return new ServiceComponent(this.name, new Attrs(this.attribs));
-	}
-
-	@Override
-	protected boolean newlinesBetweenAttributes() {
-		return true;
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/VersionedClause.java b/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/VersionedClause.java
deleted file mode 100644
index 358ec08..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/VersionedClause.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package aQute.bnd.build.model.clauses;
-
-import org.osgi.framework.*;
-
-import aQute.bnd.header.*;
-
-public class VersionedClause extends HeaderClause implements Cloneable {
-	public VersionedClause(String name, Attrs attribs) {
-		super(name, attribs);
-	}
-
-	public String getVersionRange() {
-		return attribs.get(Constants.VERSION_ATTRIBUTE);
-	}
-
-	public void setVersionRange(String versionRangeString) {
-		attribs.put(Constants.VERSION_ATTRIBUTE, versionRangeString);
-	}
-
-	@Override
-	public VersionedClause clone() {
-		VersionedClause clone = (VersionedClause) super.clone();
-		clone.name = this.name;
-		clone.attribs = new Attrs(this.attribs);
-		return clone;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/packageinfo b/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/packageinfo
deleted file mode 100644
index 55af8e5..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/clauses/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 2
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/ClauseListConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/ClauseListConverter.java
deleted file mode 100644
index 893a22f..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/ClauseListConverter.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import java.util.*;
-import java.util.Map.Entry;
-
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.libg.tuple.*;
-
-public class ClauseListConverter<R> implements Converter<List<R>,String> {
-
-	private final Converter< ? extends R, ? super Pair<String,Attrs>>	itemConverter;
-
-	public ClauseListConverter(Converter< ? extends R, ? super Pair<String,Attrs>> itemConverter) {
-		this.itemConverter = itemConverter;
-	}
-
-	public List<R> convert(String input) throws IllegalArgumentException {
-		List<R> result = new ArrayList<R>();
-
-		Parameters header = new Parameters(input);
-		for (Entry<String,Attrs> entry : header.entrySet()) {
-			String key = Processor.removeDuplicateMarker(entry.getKey());
-			Pair<String,Attrs> pair = Pair.newInstance(key, entry.getValue());
-			result.add(itemConverter.convert(pair));
-		}
-
-		return result;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/CollectionFormatter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/CollectionFormatter.java
deleted file mode 100644
index d9f345a..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/CollectionFormatter.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import java.util.*;
-
-public class CollectionFormatter<T> implements Converter<String,Collection< ? extends T>> {
-
-	private final String						separator;
-	private final Converter<String, ? super T>	itemFormatter;
-	private final String						emptyOutput;
-
-	public CollectionFormatter(String separator) {
-		this(separator, (String) null);
-	}
-
-	public CollectionFormatter(String separator, String emptyOutput) {
-		this(separator, new DefaultFormatter(), emptyOutput);
-	}
-
-	public CollectionFormatter(String separator, Converter<String, ? super T> itemFormatter) {
-		this(separator, itemFormatter, null);
-	}
-
-	public CollectionFormatter(String separator, Converter<String, ? super T> itemFormatter, String emptyOutput) {
-		this.separator = separator;
-		this.itemFormatter = itemFormatter;
-		this.emptyOutput = emptyOutput;
-	}
-
-	public String convert(Collection< ? extends T> input) throws IllegalArgumentException {
-		String result = null;
-		if (input != null) {
-			if (input.isEmpty()) {
-				result = emptyOutput;
-			} else {
-				StringBuilder buffer = new StringBuilder();
-				for (Iterator< ? extends T> iter = input.iterator(); iter.hasNext();) {
-					T item = iter.next();
-					buffer.append(itemFormatter.convert(item));
-					if (iter.hasNext())
-						buffer.append(separator);
-				}
-				result = buffer.toString();
-			}
-		}
-		return result;
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/Converter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/Converter.java
deleted file mode 100644
index 8513f52..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/Converter.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-public interface Converter<R, T> {
-	R convert(T input) throws IllegalArgumentException;
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/DefaultBooleanFormatter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/DefaultBooleanFormatter.java
deleted file mode 100644
index f188569..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/DefaultBooleanFormatter.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-/**
- * Formatter for booleans with a default value; if the input value matches the
- * default then it is formatted to <code>null</code>.
- * 
- * @author Neil Bartlett
- */
-public class DefaultBooleanFormatter implements Converter<String,Boolean> {
-
-	private final boolean	defaultValue;
-
-	public DefaultBooleanFormatter(boolean defaultValue) {
-		this.defaultValue = defaultValue;
-	}
-
-	public String convert(Boolean input) throws IllegalArgumentException {
-		String result = null;
-
-		if (input != null && input.booleanValue() != defaultValue)
-			result = input.toString();
-
-		return result;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/DefaultFormatter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/DefaultFormatter.java
deleted file mode 100644
index a552c0d..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/DefaultFormatter.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-public class DefaultFormatter implements Converter<String,Object> {
-
-	public String convert(Object input) throws IllegalArgumentException {
-		return input == null ? null : input.toString();
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EEConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EEConverter.java
deleted file mode 100644
index a2defbf..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EEConverter.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import aQute.bnd.build.model.*;
-
-public class EEConverter implements Converter<EE,String> {
-
-	public EE convert(String input) throws IllegalArgumentException {
-		return EE.parse(input);
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EEFormatter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EEFormatter.java
deleted file mode 100644
index 44a7de6..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EEFormatter.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import aQute.bnd.build.model.*;
-
-public final class EEFormatter implements Converter<String,EE> {
-	public String convert(EE input) throws IllegalArgumentException {
-		return input != null ? input.getEEName() : null;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EnumConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EnumConverter.java
deleted file mode 100644
index 4c94d3b..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EnumConverter.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-public class EnumConverter<E extends Enum<E>> implements Converter<E,String> {
-
-	private final Class<E>	enumType;
-	private final E			defaultValue;
-
-	public static <E extends Enum<E>> EnumConverter<E> create(Class<E> enumType) {
-		return new EnumConverter<E>(enumType, null);
-	}
-
-	public static <E extends Enum<E>> EnumConverter<E> create(Class<E> enumType, E defaultValue) {
-		return new EnumConverter<E>(enumType, defaultValue);
-	}
-
-	private EnumConverter(Class<E> enumType, E defaultValue) {
-		this.enumType = enumType;
-		this.defaultValue = defaultValue;
-	}
-
-	public E convert(String input) throws IllegalArgumentException {
-		if (input == null)
-			return defaultValue;
-		return Enum.valueOf(enumType, input);
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EnumFormatter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EnumFormatter.java
deleted file mode 100644
index 8500a25..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/EnumFormatter.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-/**
- * Formats an enum type. Outputs {@code null} when the value of the enum is
- * equal to a default value.
- * 
- * @param <E>
- * @author Neil Bartlett
- */
-public class EnumFormatter<E extends Enum<E>> implements Converter<String,E> {
-
-	private final E			defaultValue;
-
-	/**
-	 * Construct a new formatter with no default value, i.e. any non-null value
-	 * of the enum will print that value.
-	 * 
-	 * @param enumType
-	 *            The enum type.
-	 * @return
-	 */
-	public static <E extends Enum<E>> EnumFormatter<E> create(Class<E> enumType) {
-		return new EnumFormatter<E>(null);
-	}
-
-	/**
-	 * Construct a new formatter with the specified default value.
-	 * 
-	 * @param enumType
-	 *            The enum type.
-	 * @param defaultValue
-	 *            The default value, which will never be output.
-	 * @return
-	 */
-	public static <E extends Enum<E>> EnumFormatter<E> create(Class<E> enumType, E defaultValue) {
-		return new EnumFormatter<E>(defaultValue);
-	}
-
-	private EnumFormatter(E defaultValue) {
-		this.defaultValue = defaultValue;
-	}
-
-	public String convert(E input) throws IllegalArgumentException {
-		String result;
-		if (input == defaultValue || input == null)
-			result = null;
-		else {
-			result = input.toString();
-		}
-		return result;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/HeaderClauseConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/HeaderClauseConverter.java
deleted file mode 100644
index dffd900..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/HeaderClauseConverter.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import aQute.bnd.build.model.clauses.*;
-import aQute.bnd.header.*;
-import aQute.libg.tuple.*;
-
-public class HeaderClauseConverter implements Converter<HeaderClause,Pair<String,Attrs>> {
-
-	public HeaderClause convert(Pair<String,Attrs> input) throws IllegalArgumentException {
-		return new HeaderClause(input.getFirst(), input.getSecond());
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/HeaderClauseFormatter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/HeaderClauseFormatter.java
deleted file mode 100644
index f4161f5..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/HeaderClauseFormatter.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import aQute.bnd.build.model.clauses.*;
-
-public class HeaderClauseFormatter implements Converter<String,HeaderClause> {
-	public String convert(HeaderClause input) throws IllegalArgumentException {
-		StringBuilder buffer = new StringBuilder();
-		input.formatTo(buffer);
-		return buffer.toString();
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/HeaderClauseListConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/HeaderClauseListConverter.java
deleted file mode 100644
index 65d8471..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/HeaderClauseListConverter.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import aQute.bnd.build.model.clauses.*;
-
-public class HeaderClauseListConverter extends ClauseListConverter<HeaderClause> {
-
-	public HeaderClauseListConverter() {
-		super(new HeaderClauseConverter());
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/MapFormatter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/MapFormatter.java
deleted file mode 100644
index 03d6f71..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/MapFormatter.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import java.util.*;
-import java.util.Map.Entry;
-
-public class MapFormatter implements Converter<String,Map<String,String>> {
-
-	private CollectionFormatter<Entry<String,String>>	entrySetFormatter;
-
-	public MapFormatter(String listSeparator, Converter<String, ? super Entry<String,String>> entryFormatter,
-			String emptyOutput) {
-		entrySetFormatter = new CollectionFormatter<Entry<String,String>>(listSeparator, entryFormatter, emptyOutput);
-	}
-
-	public String convert(Map<String,String> input) throws IllegalArgumentException {
-		return entrySetFormatter.convert(input.entrySet());
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/NewlineEscapedStringFormatter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/NewlineEscapedStringFormatter.java
deleted file mode 100644
index 1bf9220..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/NewlineEscapedStringFormatter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import aQute.bnd.build.model.*;
-
-public class NewlineEscapedStringFormatter implements Converter<String,String> {
-
-	public String convert(String input) throws IllegalArgumentException {
-		if (input == null)
-			return null;
-
-		// Shortcut the result for the majority of cases where there is no
-		// newline
-		if (input.indexOf('\n') == -1)
-			return input;
-
-		// Build a new string with newlines escaped
-		StringBuilder result = new StringBuilder();
-		int position = 0;
-		while (position < input.length()) {
-			int newlineIndex = input.indexOf('\n', position);
-			if (newlineIndex == -1) {
-				result.append(input.substring(position));
-				break;
-			}
-			result.append(input.substring(position, newlineIndex));
-			result.append(BndEditModel.NEWLINE_LINE_SEPARATOR);
-			position = newlineIndex + 1;
-		}
-
-		return result.toString();
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/NoopConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/NoopConverter.java
deleted file mode 100644
index 7a9f39d..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/NoopConverter.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-public class NoopConverter<T> implements Converter<T,T> {
-	public T convert(T input) throws IllegalArgumentException {
-		return input;
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/PropertiesConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/PropertiesConverter.java
deleted file mode 100644
index cd45c60..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/PropertiesConverter.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import java.util.*;
-
-import aQute.bnd.header.*;
-
-public class PropertiesConverter implements Converter<Map<String,String>,String> {
-
-	public Map<String,String> convert(String input) throws IllegalArgumentException {
-		return OSGiHeader.parseProperties(input);
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/PropertiesEntryFormatter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/PropertiesEntryFormatter.java
deleted file mode 100644
index b487190..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/PropertiesEntryFormatter.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import java.util.Map.Entry;
-
-public class PropertiesEntryFormatter implements Converter<String,Entry<String,String>> {
-	public String convert(Entry<String,String> entry) {
-		StringBuilder buffer = new StringBuilder();
-
-		String name = entry.getKey();
-		buffer.append(name).append('=');
-
-		String value = entry.getValue();
-		if (value != null && value.length() > 0) {
-			int quotableIndex = value.indexOf(',');
-			if (quotableIndex == -1)
-				quotableIndex = value.indexOf('=');
-
-			if (quotableIndex >= 0) {
-				buffer.append('\'').append(value).append('\'');
-			} else {
-				buffer.append(value);
-			}
-		}
-		return buffer.toString();
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/RequirementFormatter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/RequirementFormatter.java
deleted file mode 100644
index 2a293ef..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/RequirementFormatter.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import java.util.Map.Entry;
-
-import org.osgi.resource.*;
-
-public class RequirementFormatter implements Converter<String,Requirement> {
-
-	public String convert(Requirement req) throws IllegalArgumentException {
-		StringBuilder builder = new StringBuilder();
-		
-		builder.append(req.getNamespace());
-		
-		for (Entry<String,String> directive : req.getDirectives().entrySet()) {
-			builder.append(';').append(directive.getKey()).append(":='").append(directive.getValue()).append('\'');
-		}
-		
-		for (Entry<String,Object> attribute : req.getAttributes().entrySet()) {
-			builder.append(';').append(attribute.getKey()).append("='").append(attribute.getValue()).append('\'');
-		}
-		
-		return builder.toString();
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/RequirementListConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/RequirementListConverter.java
deleted file mode 100644
index dacd6ed..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/RequirementListConverter.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import java.util.Map.Entry;
-
-import org.osgi.resource.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.resource.*;
-import aQute.libg.tuple.*;
-
-public class RequirementListConverter extends ClauseListConverter<Requirement> {
-
-	public RequirementListConverter() {
-		super(new Converter<Requirement,Pair<String,Attrs>>() {
-			public Requirement convert(Pair<String,Attrs> input) throws IllegalArgumentException {
-				String namespace = input.getFirst();
-				CapReqBuilder builder = new CapReqBuilder(namespace);
-				for (Entry<String,String> entry : input.getSecond().entrySet()) {
-					String key = entry.getKey();
-					if (key.endsWith(":")) {
-						key = key.substring(0, key.length() - 1);
-						builder.addDirective(key, entry.getValue());
-					} else {
-						builder.addAttribute(key, entry.getValue());
-					}
-				}
-				return builder.buildSyntheticRequirement();
-			}
-		});
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/SimpleListConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/SimpleListConverter.java
deleted file mode 100644
index a3a262b..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/SimpleListConverter.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import java.util.*;
-
-import aQute.bnd.osgi.*;
-import aQute.libg.qtokens.*;
-
-public class SimpleListConverter<R> implements Converter<List<R>,String> {
-
-	private Converter< ? extends R, ? super String>	itemConverter;
-
-	public static <R> Converter<List<R>,String> create(Converter<R, ? super String> itemConverter) {
-		return new SimpleListConverter<R>(itemConverter);
-	}
-
-	public static Converter<List<String>,String> create() {
-		return new SimpleListConverter<String>(new NoopConverter<String>());
-	}
-
-	private SimpleListConverter(Converter< ? extends R, ? super String> itemConverter) {
-		this.itemConverter = itemConverter;
-	}
-
-	public List<R> convert(String input) throws IllegalArgumentException {
-		List<R> result = new ArrayList<R>();
-
-		if (Constants.EMPTY_HEADER.equalsIgnoreCase(input.trim()))
-			return result;
-
-		QuotedTokenizer qt = new QuotedTokenizer(input, ",");
-		String token = qt.nextToken();
-
-		while (token != null) {
-			result.add(itemConverter.convert(token.trim()));
-			token = qt.nextToken();
-		}
-
-		return result;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/StringEntryConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/StringEntryConverter.java
deleted file mode 100644
index c857ddc..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/StringEntryConverter.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import java.util.Map.Entry;
-
-public class StringEntryConverter implements Converter<String,Entry<String, ? >> {
-
-	public String convert(Entry<String, ? > input) throws IllegalArgumentException {
-		return input.getKey();
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/VersionedClauseConverter.java b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/VersionedClauseConverter.java
deleted file mode 100644
index 31a1663..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/VersionedClauseConverter.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package aQute.bnd.build.model.conversions;
-
-import aQute.bnd.build.model.clauses.*;
-import aQute.bnd.header.*;
-import aQute.libg.tuple.*;
-
-public class VersionedClauseConverter implements Converter<VersionedClause,Pair<String,Attrs>> {
-	public VersionedClause convert(Pair<String,Attrs> input) throws IllegalArgumentException {
-		return new VersionedClause(input.getFirst(), input.getSecond());
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/packageinfo b/bundleplugin/src/main/java/aQute/bnd/build/model/packageinfo
deleted file mode 100644
index 5d22684..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 2.1
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/packageinfo b/bundleplugin/src/main/java/aQute/bnd/build/packageinfo
deleted file mode 100644
index 084a0d4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 2.0.0
diff --git a/bundleplugin/src/main/java/aQute/bnd/compatibility/Access.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/Access.java
deleted file mode 100644
index 1fcb640..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/compatibility/Access.java
+++ /dev/null
@@ -1,26 +0,0 @@
-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;
-	}
-
-	@Override
-	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
deleted file mode 100644
index e801a8a..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/compatibility/GenericParameter.java
+++ /dev/null
@@ -1,28 +0,0 @@
-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)
-			};
-	}
-
-	@Override
-	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
deleted file mode 100644
index ce286f2..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/compatibility/GenericType.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package aQute.bnd.compatibility;
-
-public class GenericType {
-	public GenericType(@SuppressWarnings("unused") 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
deleted file mode 100644
index 2e9f5cd..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/compatibility/Kind.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package aQute.bnd.compatibility;
-
-/**
- * The kind of thing we scope
- */
-public enum Kind {
-	ROOT, CLASS, FIELD, CONSTRUCTOR, METHOD, UNKNOWN;
-
-	@Override
-	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
deleted file mode 100644
index 6cb52ce..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/compatibility/ParseSignatureBuilder.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package aQute.bnd.compatibility;
-
-import java.io.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.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
deleted file mode 100644
index 9e6b090..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/compatibility/RuntimeSignatureBuilder.java
+++ /dev/null
@@ -1,218 +0,0 @@
-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
deleted file mode 100644
index c44f3bf..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/compatibility/Scope.java
+++ /dev/null
@@ -1,167 +0,0 @@
-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;
-	}
-
-	@Override
-	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/Signatures.java b/bundleplugin/src/main/java/aQute/bnd/compatibility/Signatures.java
deleted file mode 100644
index 70abede..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/compatibility/Signatures.java
+++ /dev/null
@@ -1,544 +0,0 @@
-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);
-		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
deleted file mode 100644
index f9c396e..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java
+++ /dev/null
@@ -1,444 +0,0 @@
-package aQute.bnd.component;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.regex.*;
-
-import org.osgi.service.component.annotations.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Clazz.MethodDef;
-import aQute.bnd.osgi.Descriptors.TypeRef;
-import aQute.bnd.version.*;
-import aQute.lib.collections.*;
-
-/**
- * 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("\\s*([^=\\s:]+)\\s*(?::\\s*(Boolean|Byte|Character|Short|Integer|Long|Float|Double|String)\\s*)?=(.*)");
-
-	public static final Version	V1_0					= new Version("1.0.0");																												// "1.0.0"
-	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.2.0"
-//	public static final Version	V1_3					= new Version("1.3.0");																												// "1.3.0"
-
-	public static final String FELIX_1_2				= "http://felix.apache.org/xmlns/scr/v1.2.0-felix";
-	
-	static Pattern				BINDNAME				= Pattern.compile("(set|add|bind)?(.*)");
-	
-	static Pattern				BINDDESCRIPTORDS10			= Pattern
-																.compile("\\(((L([^;]+);)|Lorg/osgi/framework/ServiceReference;)\\)V");
-	static Pattern				BINDDESCRIPTORDS11			= Pattern
-																.compile("\\(((L([^;]+);)(Ljava/util/Map;)?|Lorg/osgi/framework/ServiceReference;)\\)V");
-	static Pattern				BINDDESCRIPTORDS13			= Pattern
-																.compile("\\(((L([^;]+);)(Ljava/util/Map;)?|Lorg/osgi/framework/ServiceReference;)\\)Ljava/util/Map;");
-	static Pattern				REFERENCEBINDDESCRIPTOR		= Pattern
-																.compile("\\(Lorg/osgi/framework/ServiceReference;\\)V");
-
-	static Pattern				LIFECYCLEDESCRIPTORDS10		= Pattern
-																.compile("\\((Lorg/osgi/service/component/ComponentContext;)\\)V");
-	static Pattern				LIFECYCLEDESCRIPTORDS11		= Pattern
-																.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;))*\\)V");
-	static Pattern				LIFECYCLEDESCRIPTORDS13		= Pattern
-																.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;))*\\)Ljava/util/Map;");
-	static Pattern				DEACTIVATEDESCRIPTORDS11	= Pattern
-																.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;)|(Ljava/lang/Integer;)|(I))*\\)V");
-	static Pattern				DEACTIVATEDESCRIPTORDS13	= Pattern
-																.compile("\\(((Lorg/osgi/service/component/ComponentContext;)|(Lorg/osgi/framework/BundleContext;)|(Ljava/util/Map;)|(Ljava/lang/Integer;)|(I))*\\)Ljava/util/Map;");
-
-	ComponentDef				component				= new ComponentDef();
-
-	Clazz						clazz;
-	TypeRef						interfaces[];
-	MethodDef					method;
-	TypeRef						className;
-	Analyzer					analyzer;
-	MultiMap<String,String>		methods					= new MultiMap<String,String>();
-	TypeRef						extendsClass;
-	final boolean						inherit;
-	boolean						baseclass				= true;
-	
-	final boolean						felixExtensions;
-
-	AnnotationReader(Analyzer analyzer, Clazz clazz, boolean inherit, boolean felixExtensions) {
-		this.analyzer = analyzer;
-		this.clazz = clazz;
-		this.inherit = inherit;
-		this.felixExtensions = felixExtensions;
-	}
-
-	public static ComponentDef getDefinition(Clazz c, Analyzer analyzer) throws Exception {
-		boolean inherit = Processor.isTrue(analyzer.getProperty("-dsannotations-inherit"));
-		boolean felixExtensions = Processor.isTrue(analyzer.getProperty("-ds-felix-extensions"));
-		AnnotationReader r = new AnnotationReader(analyzer, c, inherit, felixExtensions);
-		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 = BINDDESCRIPTORDS10.matcher(descriptor);
-				if (matcher.matches()) {
-					String type = matcher.group(2);
-					if (rdef.service.equals(Clazz.objectDescriptorToFQN(type)) 
-							|| type.equals("Lorg/osgi/framework/ServiceReference;")) {
-
-						return value;
-					}
-				}
-				matcher = BINDDESCRIPTORDS11.matcher(descriptor);
-				if (matcher.matches()) {
-					String type = matcher.group(2);
-					if (rdef.service.equals(Clazz.objectDescriptorToFQN(type)) 
-							|| type.equals("Lorg/osgi/framework/ServiceReference;")) {
-						rdef.updateVersion(V1_1);
-						return value;
-					}
-				}
-				matcher = BINDDESCRIPTORDS13.matcher(descriptor);
-				if (felixExtensions && matcher.matches()) {
-					String type = matcher.group(2);
-					if (rdef.service.equals(Clazz.objectDescriptorToFQN(type)) 
-							|| type.equals("Lorg/osgi/framework/ServiceReference;")) {
-						rdef.updateVersion(V1_2);
-						if (component.xmlns == null) {
-							component.xmlns = FELIX_1_2;
-						}
-						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;
-	}
-
-	@Override
-	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 doActivate() {
-		String methodDescriptor = method.getDescriptor().toString();
-		if ("activate".equals(method.getName()) && LIFECYCLEDESCRIPTORDS10.matcher(methodDescriptor).matches()) {
-			component.activate = method.getName();			
-		} else if (LIFECYCLEDESCRIPTORDS11.matcher(methodDescriptor).matches()) {
-			component.activate = method.getName();	
-			component.updateVersion(V1_1);
-		} else if (felixExtensions && LIFECYCLEDESCRIPTORDS13.matcher(methodDescriptor).matches()) {
-			component.activate = method.getName();	
-			component.updateVersion(V1_2);
-			if (component.xmlns == null) {
-				component.xmlns = FELIX_1_2;
-			}
-		} else 
-			analyzer.error(
-					"Activate method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
-					clazz, method.getDescriptor());
-		
-	}
-
-	/**
-	 * 
-	 */
-	protected void doDeactivate() {
-		String methodDescriptor = method.getDescriptor().toString();
-		if ( "deactivate".equals(method.getName()) && LIFECYCLEDESCRIPTORDS10.matcher(methodDescriptor).matches()) {
-			component.deactivate = method.getName();			
-		} else if (DEACTIVATEDESCRIPTORDS11.matcher(methodDescriptor).matches()) {
-			component.deactivate = method.getName();
-			component.updateVersion(V1_1);
-		} else if (felixExtensions && DEACTIVATEDESCRIPTORDS13.matcher(methodDescriptor).matches()) {
-			component.deactivate = method.getName();
-			component.updateVersion(V1_2);
-			if (component.xmlns == null) {
-				component.xmlns = FELIX_1_2;
-			}
-		} else
-			analyzer.error(
-					"Deactivate method for %s does not have an acceptable prototype, only Map, ComponentContext, BundleContext, int, or Integer is allowed. Found: %s",
-					clazz, method.getDescriptor());
-	}
-
-	/**
-	 * 
-	 */
-	protected void doModified() {
-		if (LIFECYCLEDESCRIPTORDS11.matcher(method.getDescriptor().toString()).matches()) {
-			component.modified = method.getName();
-			component.updateVersion(V1_1);
-		} else if (felixExtensions && LIFECYCLEDESCRIPTORDS13.matcher(method.getDescriptor().toString()).matches()) {
-			component.modified = method.getName();
-			component.updateVersion(V1_2);
-			if (component.xmlns == null) {
-				component.xmlns = FELIX_1_2;
-			}
-		} else
-
-			analyzer.error(
-					"Modified method for %s does not have an acceptable prototype, only Map, ComponentContext, or BundleContext is allowed. Found: %s",
-					clazz, method.getDescriptor());
-	}
-
-	/**
-	 * @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.
-			String methodDescriptor = method.getDescriptor().toString();
-			Matcher m = BINDDESCRIPTORDS10.matcher(methodDescriptor);
-			if (m.matches()) {
-				def.service = Descriptors.binaryToFQN(m.group(3));
-			} else {
-				m = BINDDESCRIPTORDS11.matcher(methodDescriptor);
-				if (m.matches()) {
-					def.service = Descriptors.binaryToFQN(m.group(3));
-					def.updateVersion(V1_1);
-				} else {
-					m = BINDDESCRIPTORDS13.matcher(methodDescriptor);
-					if (felixExtensions && m.matches()) {
-						def.service = Descriptors.binaryToFQN(m.group(3));
-						def.updateVersion(V1_2);
-						if (component.xmlns == null) {
-							component.xmlns = FELIX_1_2;
-						}
-					} 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();
-	}
-
-	/**
-	 * @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.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();
-			component.updateVersion(V1_2);
-		}
-
-		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 type = m.group(2);
-					if ( type != null)
-						key += ":" + type;
-					
-					String value = m.group(3);
-					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
deleted file mode 100644
index 8c4b090..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/component/ComponentDef.java
+++ /dev/null
@@ -1,242 +0,0 @@
-package aQute.bnd.component;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.osgi.service.component.annotations.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Descriptors.TypeRef;
-import aQute.bnd.version.*;
-import aQute.lib.collections.*;
-import aQute.lib.tag.*;
-
-/**
- * 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 LinkedHashMap<String,ReferenceDef>();
-
-	Version							version			= AnnotationReader.V1_0;
-	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 {
-
-		prepareVersion(analyzer);
-
-
-		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");
-
-		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);
-		}
-	}
-
-	private void prepareVersion(Analyzer analyzer) throws Exception {
-		
-		for (ReferenceDef ref : references.values()) {
-			ref.prepare(analyzer);
-			updateVersion(ref.version);
-		}
-		if (configurationPolicy != null)
-			updateVersion(AnnotationReader.V1_1);
-		if (configurationPid != null)
-			updateVersion(AnnotationReader.V1_2);
-		if (modified != null)
-			updateVersion(AnnotationReader.V1_1);
-			
-	}
-	
-	void sortReferences() {
-		Map<String, ReferenceDef> temp = new TreeMap<String,ReferenceDef>(references);
-		references.clear();
-		references.putAll(temp);
-	}
-
-	/**
-	 * Returns a tag describing the component element.
-	 * 
-	 * @return a component element
-	 */
-	Tag getTag() {
-		String xmlns = this.xmlns;
-		if (xmlns == null && version != AnnotationReader.V1_0)
-			xmlns = NAMESPACE_STEM + "/v" + version;
-		Tag component = new Tag(xmlns == null? "component": "scr:component");
-		if (xmlns != null)
-			component.addAttribute("xmlns:scr", xmlns);
-
-		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 && version != AnnotationReader.V1_0)
-			component.addAttribute("activate", activate);
-
-		if (deactivate != null && version != AnnotationReader.V1_0)
-			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 {
-			if ( type.equals("Char"))
-				type = "Character";
-			
-			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;
-	}
-	
-	void updateVersion(Version version) {
-		this.version = max(this.version, version);
-	}
-	
-	static <T extends Comparable<T>> T max(T a, T b) {
-		int n = a.compareTo(b);
-		if (n >= 0)
-			return a;
-		return b;
-	}
-
-}
\ 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
deleted file mode 100644
index f3840f3..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/component/DSAnnotations.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package aQute.bnd.component;
-
-import java.util.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-
-/**
- * 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(Constants.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 (Clazz c: list) {
-			for (Instruction instruction : instructions.keySet()) {
-
-				if (instruction.matches(c.getFQN())) {
-					if (instruction.isNegated())
-						break;
-					ComponentDef definition = AnnotationReader.getDefinition(c, analyzer);
-					if (definition != null) {
-						definition.sortReferences();
-						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/HeaderReader.java b/bundleplugin/src/main/java/aQute/bnd/component/HeaderReader.java
deleted file mode 100644
index d69b0aa..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/component/HeaderReader.java
+++ /dev/null
@@ -1,502 +0,0 @@
-package aQute.bnd.component;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.osgi.service.component.annotations.ConfigurationPolicy;
-import org.osgi.service.component.annotations.ReferenceCardinality;
-import org.osgi.service.component.annotations.ReferencePolicy;
-import org.osgi.service.component.annotations.ReferencePolicyOption;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Clazz.MethodDef;
-import aQute.bnd.osgi.Descriptors.TypeRef;
-import aQute.lib.tag.Tag;
-import aQute.bnd.version.Version;
-
-public class HeaderReader extends Processor {
-	final static Pattern		PROPERTY_PATTERN		= Pattern
-	.compile("([^=]+([:@](Boolean|Byte|Char|Short|Integer|Long|Float|Double|String))?)\\s*=(.*)");
-	private final static Set<String> LIFECYCLE_METHODS = new HashSet<String>(Arrays.asList("activate", "deactivate", "modified"));
-	
-    private final Analyzer analyzer;
-
-	private final static String ComponentContextTR = "org.osgi.service.component.ComponentContext";
-	private final static String BundleContextTR = "org.osgi.framework.BundleContext";
-	private final static String MapTR = Map.class.getName();
-	private final static String IntTR = int.class.getName();
-	final static Set<String> allowed = new HashSet<String>(Arrays.asList(ComponentContextTR, BundleContextTR, MapTR));
-	final static Set<String> allowedDeactivate = new HashSet<String>(Arrays.asList(ComponentContextTR, BundleContextTR, MapTR, IntTR));
-	
-	private final static String ServiceReferenceTR = "org.osgi.framework.ServiceReference";
-
-    public HeaderReader(Analyzer analyzer) {
-    	this.analyzer = analyzer;
-    }
-    
-	public Tag createComponentTag(String name, String impl, Map<String, String> info)
-	throws Exception {
-		final ComponentDef cd = new ComponentDef();
-		cd.name = name;
-		if (info.get(COMPONENT_ENABLED) != null)
-			cd.enabled = Boolean.valueOf(info.get(COMPONENT_ENABLED));
-		cd.factory = info.get(COMPONENT_FACTORY);
-		if (info.get(COMPONENT_IMMEDIATE) != null) 
-		    cd.immediate = Boolean.valueOf(info.get(COMPONENT_IMMEDIATE));
-		if (info.get(COMPONENT_CONFIGURATION_POLICY) != null)
-		    cd.configurationPolicy = ConfigurationPolicy.valueOf(info.get(COMPONENT_CONFIGURATION_POLICY).toUpperCase());
-		cd.activate = checkIdentifier(COMPONENT_ACTIVATE, info.get(COMPONENT_ACTIVATE));
-		cd.deactivate = checkIdentifier(COMPONENT_DEACTIVATE, info.get(COMPONENT_DEACTIVATE));
-		cd.modified = checkIdentifier(COMPONENT_MODIFIED, info.get(COMPONENT_MODIFIED));
-		
-		cd.implementation = analyzer.getTypeRefFromFQN(impl == null? name: impl);
-		
-
-		String provides = info.get(COMPONENT_PROVIDE);
-		if (info.get(COMPONENT_SERVICEFACTORY) != null) {
-			if (provides != null)
-			    cd.servicefactory = Boolean.valueOf(info.get(COMPONENT_SERVICEFACTORY));
-			else
-				warning("The servicefactory:=true directive is set but no service is provided, ignoring it");
-		}
-
-		if (cd.servicefactory != null && cd.servicefactory  && cd.immediate != null && cd.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);
-		}
-		
-		//analyze the class for suitable methods.
-		final Map<String, MethodDef> lifecycleMethods = new HashMap<String, MethodDef>();
-		final Map<String, MethodDef> bindmethods = new HashMap<String, MethodDef>();
-		TypeRef typeRef = analyzer.getTypeRefFromFQN(impl);
-		Clazz clazz = analyzer.findClass(typeRef);
-		boolean privateAllowed = true;
-		boolean defaultAllowed = true; 
-		String topPackage = typeRef.getPackageRef().getFQN();
-		while (clazz != null) {
-			final boolean pa = privateAllowed;
-			final boolean da = defaultAllowed;
-			final Map<String, MethodDef> classLifecyclemethods = new HashMap<String, MethodDef>();
-			final Map<String, MethodDef> classBindmethods = new HashMap<String, MethodDef>();
-			
-			clazz.parseClassFileWithCollector(new ClassDataCollector() {
-				
-				@Override
-				public void method(MethodDef md) {
-					Set<String> allowedParams = allowed;
-					String lifecycleName = null;
-					
-					boolean isLifecycle = (cd.activate == null? "activate": cd.activate).equals(md.getName()) ||
-						md.getName().equals(cd.modified);	
-					if (!isLifecycle && (cd.deactivate == null? "deactivate": cd.deactivate).equals(md.getName())) {
-						isLifecycle = true;
-						allowedParams = allowedDeactivate;
-					}
-					if (isLifecycle && !lifecycleMethods.containsKey(md.getName()) &&
-							(md.isPublic() ||
-									md.isProtected() ||
-									(md.isPrivate() && pa) ||
-									(!md.isPrivate()) && da) &&
-							isBetter(md, classLifecyclemethods.get(md.getName()), allowedParams)) {
-						classLifecyclemethods.put(md.getName(), md);
-					}
-					if (!bindmethods.containsKey(md.getName()) &&
-							(md.isPublic() ||
-									md.isProtected() ||
-									(md.isPrivate() && pa) ||
-									(!md.isPrivate()) && da) &&
-							isBetterBind(md, classBindmethods.get(md.getName()))) {
-						classBindmethods.put(md.getName(), md);
-					}
-				}
-
-				private boolean isBetter(MethodDef test, MethodDef existing, Set<String> allowedParams) {
-					int testRating = rateLifecycle(test, allowedParams);
-					if (existing == null)
-						return testRating < 6;// ignore invalid methods
-					if (testRating < rateLifecycle(existing, allowedParams))
-						return true;
-					
-					return false;
-				}
-
-				private boolean isBetterBind(MethodDef test, MethodDef existing) {
-					int testRating = rateBind(test);
-					if (existing == null)
-						return testRating < 6;// ignore invalid methods
-					if (testRating < rateBind(existing))
-						return true;
-					
-					return false;
-				}
-
-			});
-			lifecycleMethods.putAll(classLifecyclemethods);
-			bindmethods.putAll(classBindmethods);
-			typeRef = clazz.getSuper();
-			if (typeRef == null)
-				break;
-			clazz = analyzer.findClass(typeRef);
-			privateAllowed = false;
-			defaultAllowed = defaultAllowed && topPackage.equals(typeRef.getPackageRef().getFQN());
-		}
-		
-		
-		if (cd.activate != null && !lifecycleMethods.containsKey(cd.activate)) {
-			error("in component %s, activate method %s specified but not found", cd.implementation.getFQN(), cd.activate);
-			cd.activate = null;
-		}
-		if (cd.deactivate != null && !lifecycleMethods.containsKey(cd.deactivate)) {
-			error("in component %s, deactivate method %s specified but not found", cd.implementation.getFQN(), cd.deactivate);
-			cd.activate = null;
-		}
-		if (cd.modified != null && !lifecycleMethods.containsKey(cd.modified)) {
-			error("in component %s, modified method %s specified but not found", cd.implementation.getFQN(), cd.modified);
-			cd.activate = null;
-		}
-		
-		provide(cd, provides, impl);
-		properties(cd, info, name);
-		reference(info, impl, cd, bindmethods);
-		//compute namespace after references, an updated method means ds 1.2.
-		getNamespace(info, cd, lifecycleMethods);
-		cd.prepare(analyzer);
-		return cd.getTag();
-
-	}
-
-	private String checkIdentifier(String name, String value) {
-		if (value != null) {
-			if (!Verifier.isIdentifier(value)) {
-				error("Component attribute %s has value %s but is not a Java identifier",
-						name, value);
-				return null;
-			}
-		}
-		return value;
-	}
-
-	/**
-	 * Check if we need to use the v1.1 namespace (or later).
-	 * 
-	 * @param info
-	 * @param cd TODO
-	 * @param descriptors TODO
-	 * @return
-	 */
-	private void getNamespace(Map<String, String> info, ComponentDef cd, Map<String,MethodDef> descriptors) {
-		String namespace = info.get(COMPONENT_NAMESPACE);
-		if (namespace != null) {
-			cd.xmlns = namespace;
-		}
-		String version = info.get(COMPONENT_VERSION);
-		if (version != null) {
-			try {
-				Version v = new Version(version);
-				cd.updateVersion(v);
-			} catch (Exception e) {
-				error("version: specified on component header but not a valid version: "
-						+ version);
-				return;
-			}
-		}
-		for (String key : info.keySet()) {
-			if (SET_COMPONENT_DIRECTIVES_1_2.contains(key)) {
-				cd.updateVersion(AnnotationReader.V1_2);
-				return;
-			}
-		}
-		for (ReferenceDef rd: cd.references.values()) {
-			if (rd.updated != null) {
-				cd.updateVersion(AnnotationReader.V1_2);
-				return;
-			}
-		}
-		//among other things this picks up any specified lifecycle methods
-		for (String key : info.keySet()) {
-			if (SET_COMPONENT_DIRECTIVES_1_1.contains(key)) {
-				cd.updateVersion(AnnotationReader.V1_1);
-				return;
-			}
-		}
-		for (String lifecycle: LIFECYCLE_METHODS) {
-			//lifecycle methods were not specified.... check for non 1.0 signatures.
-			MethodDef test = descriptors.get(lifecycle);
-			if (descriptors.containsKey(lifecycle) && (!(test.isPublic() || test.isProtected()) || 
-					rateLifecycle(test, "deactivate".equals(lifecycle)? allowedDeactivate: allowed) > 1)) {
-				cd.updateVersion(AnnotationReader.V1_1);
-				return;
-			}
-		}
-	}
-
-	/**
-	 * Print the Service-Component properties element
-	 * 
-	 * @param cd
-	 * @param info
-	 */
-	void properties(ComponentDef cd, Map<String, String> info, String name) {
-		Collection<String> properties = split(info.get(COMPONENT_PROPERTIES));
-		for (String p : properties) {
-			Matcher m = PROPERTY_PATTERN.matcher(p);
-
-			if (m.matches()) {
-				String key = m.group(1).replaceAll("@", ":");
-				String value = m.group(4);
-				String parts[] = value.split("\\s*(\\||\\n)\\s*");
-				for (String part: parts) {
-					cd.property.add(key, part);
-				}
-			} else
-				throw new IllegalArgumentException("Malformed property '" + p
-						+ "' on component: " + name);
-		}
-	}
-
-	/**
-	 * @param cd
-	 * @param provides
-	 */
-	void provide(ComponentDef cd, String provides, String impl) {
-		if (provides != null) {
-			StringTokenizer st = new StringTokenizer(provides, ",");
-			List<TypeRef> provide = new ArrayList<TypeRef>();
-			while (st.hasMoreTokens()) {
-				String interfaceName = st.nextToken();
-				TypeRef ref = analyzer.getTypeRefFromFQN(interfaceName);
-				provide.add(ref);
-				analyzer.referTo(ref);
-
-				// TODO verifies the impl. class extends or implements the
-				// interface
-			}
-			cd.service = provide.toArray(new TypeRef[provide.size()]);
-		} 
-	}
-
-	public final static Pattern	REFERENCE	= Pattern.compile("([^(]+)(\\(.+\\))?");
-
-	/**
-	 * rates the methods according to the scale in 112.5.8 (compendium 4.3, ds 1.2), also returning "6" for invalid methods
-	 * We don't look at return values yet due to proposal to all them for setting service properties.
-	 * @param test methodDef to examine for suitability as a DS lifecycle method
-	 * @param allowedParams TODO
-	 * @return rating; 6 if invalid, lower is better
-	 */
-	int rateLifecycle(MethodDef test, Set<String> allowedParams) {
-		TypeRef[] prototype = test.getDescriptor().getPrototype();
-		if (prototype.length == 1 && ComponentContextTR.equals(prototype[0].getFQN()))
-			    return 1;
-		if (prototype.length == 1 && BundleContextTR.equals(prototype[0].getFQN()))
-			return 2;
-		if (prototype.length == 1 && MapTR.equals(prototype[0].getFQN()))
-			return 3;
-		if (prototype.length > 1) {
-			for (TypeRef tr: prototype) {
-				if (!allowedParams.contains(tr.getFQN()))
-					return 6;
-			}
-			return 5;
-		}
-		if (prototype.length == 0)
-			return 5;
-
-		return 6;
-	}
-
-	/**
-	 * see 112.3.2.  We can't distinguish the bind type, so we just accept anything.
-	 * @param test
-	 * @return
-	 */
-	int rateBind(MethodDef test) {
-		TypeRef[] prototype = test.getDescriptor().getPrototype();
-		if (prototype.length == 1 && ServiceReferenceTR.equals(prototype[0].getFQN()))
-			return 1;
-		if (prototype.length == 1)
-			return 2;
-		if (prototype.length == 2 && MapTR.equals(prototype[1].getFQN()))
-			return 3;
-		return 6;
-	}
-
-	/**
-	 * @param info
-	 * @param impl TODO
-	 * @param descriptors TODO
-	 * @param pw
-	 * @throws Exception 
-	 */
-	void reference(Map<String, String> info, String impl, ComponentDef cd, Map<String,MethodDef> descriptors) throws Exception {
-		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> greedy = new ArrayList<String>(split(info.get(COMPONENT_GREEDY)));
-
-
-		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;
-			String updated = null;
-
-			boolean bindCalculated = true;
-			boolean unbindCalculated = true;
-			boolean updatedCalculated = true;
-
-			if (referenceName.indexOf('/') >= 0) {
-				String parts[] = referenceName.split("/");
-				referenceName = parts[0];
-				if (parts[1].length() > 0) {
-					bind = parts[1];
-					bindCalculated = false;
-				} else {
-					bind = calculateBind(referenceName);
-				}
-				bind = parts[1].length() == 0? calculateBind(referenceName): parts[1];
-				if (parts.length > 2 && parts[2].length() > 0) {
-					unbind = parts[2] ;
-					unbindCalculated = false;
-				} else {
-					if (bind.startsWith("add"))
-						unbind = bind.replaceAll("add(.+)", "remove$1");
-					else
-						unbind = "un" + bind;
-				}
-				if (parts.length > 3) {
-					updated = parts[3];
-					updatedCalculated = false;
-				}
-			} else if (Character.isLowerCase(referenceName.charAt(0))) {
-				bind = calculateBind(referenceName);
-				unbind = "un" + bind;
-				updated = "updated" + Character.toUpperCase(referenceName.charAt(0))
-				+ referenceName.substring(1);
-			}
-
-			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.containsKey(bind))
-					if (bindCalculated)
-						bind = null;
-					else
-						error("In component %s, the bind method %s for %s not defined", cd.name, bind, referenceName);
-
-				// Check if the unbind method exists
-				if (!descriptors.containsKey(unbind)) {
-					if (unbindCalculated)
-						// remove it
-						unbind = null;
-					else
-						error("In component %s, the unbind method %s for %s not defined", cd.name, unbind, referenceName);
-				}
-				if (!descriptors.containsKey(updated)) {
-					if (updatedCalculated)
-						//remove it
-						updated = null;
-					else 
-						error("In component %s, the updated method %s for %s is not defined", cd.name, updated, referenceName);
-				}
-			}
-			// Check the 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);
-			ReferenceDef rd = new ReferenceDef();
-			rd.name = referenceName;
-			rd.service = interfaceName;
-
-			if (optional.contains(referenceName)) {
-				if (multiple.contains(referenceName)) {
-					rd.cardinality = ReferenceCardinality.MULTIPLE;
-				} else {
-					rd.cardinality = ReferenceCardinality.OPTIONAL;
-				}
-			} else {
-				if (multiple.contains(referenceName)) {
-					rd.cardinality = ReferenceCardinality.AT_LEAST_ONE;
-				} else {
-					rd.cardinality = ReferenceCardinality.MANDATORY;
-				}
-			}
-			if (bind != null) {
-				rd.bind = bind;
-				if (unbind != null) {
-					rd.unbind = unbind;
-				}
-				if (updated != null) {
-					rd.updated = updated;
-				}
-			}
-
-			if (dynamic.contains(referenceName)) {
-				rd.policy = ReferencePolicy.DYNAMIC;
-			}
-
-			if (greedy.contains(referenceName)) {
-				rd.policyOption = ReferencePolicyOption.GREEDY;
-			}
-
-			if (target != null) {
-				rd.target = target;
-			}
-			cd.references.put(referenceName, rd);
-		}
-	}
-
-	private String calculateBind(String referenceName) {
-		return "set" + Character.toUpperCase(referenceName.charAt(0))
-		+ referenceName.substring(1);
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java b/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java
deleted file mode 100644
index 255eef1..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package aQute.bnd.component;
-
-import org.osgi.service.component.annotations.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.version.*;
-import aQute.lib.tag.*;
-
-/**
- * Holds the information in the reference element.
- */
-
-class ReferenceDef {
-	Version					version	= AnnotationReader.V1_0;
-	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)
-			updateVersion(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;
-	}
-
-	@Override
-	public String toString() {
-		return name;
-	}
-	
-	void updateVersion(Version version) {
-		this.version = ComponentDef.max(this.version, version);
-	}
-
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/TagResource.java b/bundleplugin/src/main/java/aQute/bnd/component/TagResource.java
deleted file mode 100644
index 814a2b6..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/component/TagResource.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package aQute.bnd.component;
-
-import java.io.*;
-
-import aQute.bnd.osgi.*;
-import aQute.lib.tag.*;
-
-public class TagResource extends WriteResource {
-	final Tag	tag;
-
-	public TagResource(Tag tag) {
-		this.tag = tag;
-	}
-
-	@Override
-	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();
-		}
-	}
-
-	@Override
-	public long lastModified() {
-		return 0;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/Baseline.java b/bundleplugin/src/main/java/aQute/bnd/differ/Baseline.java
deleted file mode 100644
index cd2d9b6..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/differ/Baseline.java
+++ /dev/null
@@ -1,287 +0,0 @@
-package aQute.bnd.differ;
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.diff.*;
-import aQute.bnd.service.diff.Diff.Ignore;
-import aQute.bnd.version.*;
-import aQute.libg.generics.*;
-import aQute.service.reporter.*;
-
-/**
- * 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;
-	Diff			diff;
-	Set<Info>		infos;
-	String 			bsn;
-	Version			newerVersion;
-	Version			olderVersion;
-	Version			suggestedVersion;
-	String			releaseRepository;
-
-	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 = n.diff(o);
-		Diff apiDiff = diff.get("<api>");
-		infos = Create.set();
-
-		bsn = getBsn(n);
-
-		newerVersion = getVersion(n);
-		olderVersion = getVersion(o);
-
-		boolean firstRelease = false;
-		if (o.get("<manifest>") == null) {
-			firstRelease = true;
-			if (newerVersion.equals(Version.emptyVersion)) {
-				newerVersion = Version.ONE;
-			}
-		}
-		Delta highestDelta = Delta.MICRO;
-		for (Diff pdiff : apiDiff.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 not equal";
-				}
-			} else if (pdiff.getDelta() == Delta.REMOVED) {
-				info.suggestedVersion = null;
-			} else if (pdiff.getDelta() == Delta.ADDED) {
-				if (firstRelease) {
-					info.suggestedVersion = info.newerVersion;
-					if (info.suggestedVersion.equals(Version.emptyVersion)) {
-						info.suggestedVersion = newerVersion.getWithoutQualifier();
-					}
-				} else {
-					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);
-						}
-					}
-				}
-			}
-			if (pdiff.getDelta().compareTo(highestDelta) > 0) {
-				highestDelta = pdiff.getDelta();
-			}
-		}
-		if (firstRelease) {
-			suggestedVersion = newerVersion;
-		} else {
-			suggestedVersion = bumpBundle(highestDelta, olderVersion, 1, 0);
-		}
-		return infos;
-	}
-
-	/**
-	 * Gets the generated diff
-	 * 
-	 * @return the diff
-	 */
-	public Diff getDiff() {
-		return diff;
-	}
-
-	public Set<Info> getPackageInfos() {
-		if (infos == null)
-			return Collections.emptySet();
-		return infos;
-	}
-
-	public String getBsn() {
-		return bsn;
-	}
-
-	public Version getSuggestedVersion() {
-		return suggestedVersion;
-	}
-
-	public void setSuggestedVersion(Version suggestedVersion) {
-		this.suggestedVersion = suggestedVersion;
-	}
-
-	public Version getNewerVersion() {
-		return newerVersion;
-	}
-
-	public Version getOlderVersion() {
-		return olderVersion;
-	}
-
-	public String getReleaseRepository() {
-		return releaseRepository;
-	}
-
-	public void setReleaseRepository(String releaseRepository) {
-		this.releaseRepository = releaseRepository;
-	}
-
-	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));
-	}
-	
-	private Version getVersion(Tree top) {
-		Tree manifest = top.get("<manifest>");
-		if (manifest == null) {
-			return Version.emptyVersion;
-		}
-		for (Tree tree : manifest.getChildren()) {
-			if (tree.getName().startsWith(Constants.BUNDLE_VERSION)) {
-				return Version.parseVersion(tree.getName().substring(15));
-			}
-		}
-		return Version.emptyVersion;
-	}
-
-	private String getBsn(Tree top) {
-		Tree manifest = top.get("<manifest>");
-		if (manifest == null) {
-			return "";
-		}
-		for (Tree tree : manifest.getChildren()) {
-			if (tree.getName().startsWith(Constants.BUNDLE_SYMBOLICNAME) && tree.getChildren().length > 0) {
-				return tree.getChildren()[0].getName();
-			}
-		}
-		return "";
-	}
-
-	private Version bumpBundle(Delta delta, Version last, int offset, int base) {
-		switch (delta) {
-			case MINOR :
-				return new Version(last.getMajor(), last.getMinor() + offset, base);
-			case MAJOR :
-				return new Version(last.getMajor() + 1, base, base);
-			case ADDED :
-				return new Version(last.getMajor(), last.getMinor() + offset, base);
-			default :
-				return new Version(last.getMajor(), last.getMinor(), last.getMicro() + offset);
-		}
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/DiffImpl.java b/bundleplugin/src/main/java/aQute/bnd/differ/DiffImpl.java
deleted file mode 100644
index ef21f65..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/differ/DiffImpl.java
+++ /dev/null
@@ -1,243 +0,0 @@
-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 Tree				older;
-	final Tree				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
-	 */
-	public DiffImpl(Tree newer, Tree 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.
-		Tree[] newerChildren = newer == null ? Element.EMPTY : newer.getChildren();
-		Tree[] olderChildren = older == null ? Element.EMPTY : older.getChildren();
-
-		int o = 0;
-		int n = 0;
-		List<DiffImpl> children = new ArrayList<DiffImpl>();
-		while (true) {
-			Tree nw = n < newerChildren.length ? newerChildren[n] : null;
-			Tree 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.ifRemoved();
-				else if (sub == ADDED)
-					sub = child.newer.ifAdded();
-
-				// 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;
-	}
-
-	@Override
-	public String toString() {
-		return String.format("%-10s %-10s %s", getDelta(), getType(), getName());
-	}
-
-	@Override
-	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;
-	}
-
-	@Override
-	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());
-			}
-			return getType().compareTo(other.getType());
-		}
-		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;
-	}
-
-	public Data serialize() {
-		Data data = new Data();
-		data.type = getType();
-		data.delta = delta;
-		data.name = getName();
-		data.children = new Data[children.size()];
-		
-		int i=0;		
-		for ( Diff d : children)
-			data.children[i++] = d.serialize();
-				
-		return data;
-	}
-
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/DiffPluginImpl.java b/bundleplugin/src/main/java/aQute/bnd/differ/DiffPluginImpl.java
deleted file mode 100644
index d3dc6a4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/differ/DiffPluginImpl.java
+++ /dev/null
@@ -1,192 +0,0 @@
-package aQute.bnd.differ;
-
-import static aQute.bnd.service.diff.Delta.*;
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.diff.*;
-import aQute.bnd.service.diff.Tree.Data;
-import aQute.lib.collections.*;
-import aQute.lib.hex.*;
-import aQute.lib.io.*;
-import aQute.libg.cryptography.*;
-
-/**
- * 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);
-
-	/**
-	 * Headers that have values that should be sorted
-	 */
-	final static Set<String>	ORDERED_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);
-
-		ORDERED_HEADERS.add(Constants.SERVICE_COMPONENT);
-		ORDERED_HEADERS.add(Constants.TESTCASES);
-	}
-
-	/**
-	 * @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(), Arrays.asList(new Element(Type.SHA,value)), 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()) {
-						String paramValue = parameter.getValue();
-						if (Constants.EXPORT_PACKAGE.equals(header) && Constants.USES_DIRECTIVE.equals(parameter.getKey())) {
-							ExtList<String> uses = ExtList.from(parameter.getValue());
-							Collections.sort(uses);
-							paramValue = uses.join();
-						}
-						parameterDef.add(new Element(Type.PARAMETER, parameter.getKey() + ":" + paramValue,
-								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 if (ORDERED_HEADERS.contains(header)) {
-				ExtList<String> values = ExtList.from(value);
-				Collections.sort(values);
-				result.add(new Element(Type.HEADER, header + ":" + values.join(), null, 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
deleted file mode 100644
index 6b74b4d..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/differ/Element.java
+++ /dev/null
@@ -1,145 +0,0 @@
-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 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(Tree other) {
-		if (type == other.getType())
-			return name.compareTo(other.getName());
-		return type.compareTo(other.getType());
-	}
-
-	@Override
-	public boolean equals(Object other) {
-		if (other == null || getClass() != other.getClass())
-			return false;
-
-		return compareTo((Element) other) == 0;
-	}
-
-	@Override
-	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, older);
-	}
-
-	public Element get(String name) {
-		for (Element e : children) {
-			if (e.name.equals(name))
-				return e;
-		}
-		return null;
-	}
-
-	@Override
-	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
deleted file mode 100644
index 99ccdd2..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/differ/JavaElement.java
+++ /dev/null
@@ -1,647 +0,0 @@
-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.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Clazz.JAVA;
-import aQute.bnd.osgi.Clazz.MethodDef;
-import aQute.bnd.osgi.Descriptors.PackageRef;
-import aQute.bnd.osgi.Descriptors.TypeRef;
-import aQute.bnd.service.diff.*;
-import aQute.bnd.service.diff.Type;
-import aQute.bnd.version.Version;
-import aQute.lib.collections.*;
-import aQute.libg.generics.*;
-
-/**
- * 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;
-					}
-					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, @SuppressWarnings("unused") 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/differ/RepositoryElement.java b/bundleplugin/src/main/java/aQute/bnd/differ/RepositoryElement.java
deleted file mode 100644
index 99cdf89..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/differ/RepositoryElement.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package aQute.bnd.differ;
-
-import java.util.*;
-
-import aQute.bnd.service.*;
-import aQute.bnd.service.diff.*;
-import aQute.bnd.version.*;
-
-public class RepositoryElement {
-
-	public static Element getTree(RepositoryPlugin repo) throws Exception {
-		List<Element> programs = new ArrayList<Element>();
-		for (String bsn : repo.list(null)) {
-			List<Element> versions = new ArrayList<Element>();
-			for (Version version : repo.versions(bsn)) {
-				versions.add(new Element(Type.VERSION, version.toString()));
-			}
-			programs.add(new Element(Type.PROGRAM, bsn, versions, Delta.MINOR, Delta.MAJOR, null));
-		}
-		return new Element(Type.REPO, repo.getName(), programs, Delta.MINOR, Delta.MAJOR, repo.getLocation());
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/packageinfo b/bundleplugin/src/main/java/aQute/bnd/differ/packageinfo
deleted file mode 100644
index a4f1546..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/differ/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/filerepo/FileRepo.java b/bundleplugin/src/main/java/aQute/bnd/filerepo/FileRepo.java
deleted file mode 100644
index 548ace7..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/filerepo/FileRepo.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package aQute.bnd.filerepo;
-
-import java.io.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.version.*;
-
-public class FileRepo {
-	File	root;
-	Pattern	REPO_FILE	= Pattern.compile("([-a-zA-z0-9_\\.]+)-([0-9\\.]+)\\.(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) throws IOException {
-		File dir = new File(root, bsn);
-		if (!dir.exists() && !dir.mkdirs()) {
-			throw new IOException("Could not create directory " + dir);
-		}
-		File file = new File(dir, bsn + "-" + version.getMajor() + "." + version.getMinor() + "." + version.getMicro()
-				+ ".jar");
-		return file;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/filerepo/packageinfo b/bundleplugin/src/main/java/aQute/bnd/filerepo/packageinfo
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/filerepo/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
diff --git a/bundleplugin/src/main/java/aQute/bnd/header/Attrs.java b/bundleplugin/src/main/java/aQute/bnd/header/Attrs.java
deleted file mode 100644
index d0c41ba..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/header/Attrs.java
+++ /dev/null
@@ -1,315 +0,0 @@
-package aQute.bnd.header;
-
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.version.*;
-import aQute.lib.collections.*;
-
-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");
-	}
-
-	@Override
-	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 = ";";
-		}
-	}
-
-	@Override
-	@Deprecated
-	public boolean equals(Object other) {
-		return super.equals(other);
-	}
-
-	@Override
-	@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);
-				case DOUBLE :
-					return Double.parseDouble(s.trim());
-					
-				case DOUBLES :
-				case LONGS :
-				case STRINGS :
-				case VERSIONS :
-					// Cannot happen since the sub is null
-					return null;
-			}
-			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/bnd/header/OSGiHeader.java b/bundleplugin/src/main/java/aQute/bnd/header/OSGiHeader.java
deleted file mode 100755
index 810513a..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/header/OSGiHeader.java
+++ /dev/null
@@ -1,134 +0,0 @@
-package aQute.bnd.header;
-
-import java.util.*;
-
-import aQute.libg.generics.*;
-import aQute.libg.qtokens.*;
-import aQute.service.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/bnd/header/Parameters.java b/bundleplugin/src/main/java/aQute/bnd/header/Parameters.java
deleted file mode 100644
index 7666f4b..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/header/Parameters.java
+++ /dev/null
@@ -1,209 +0,0 @@
-package aQute.bnd.header;
-
-import java.util.*;
-
-import aQute.lib.collections.*;
-import aQute.service.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();
-	}
-
-	@Override
-	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 = ",";
-		}
-	}
-
-	@Override
-	@Deprecated
-	public boolean equals(Object other) {
-		return super.equals(other);
-	}
-
-	@Override
-	@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/bnd/header/packageinfo b/bundleplugin/src/main/java/aQute/bnd/header/packageinfo
deleted file mode 100644
index e39f616..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/header/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.1.0
diff --git a/bundleplugin/src/main/java/aQute/bnd/help/Syntax.java b/bundleplugin/src/main/java/aQute/bnd/help/Syntax.java
deleted file mode 100644
index b79780f..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/help/Syntax.java
+++ /dev/null
@@ -1,375 +0,0 @@
-package aQute.bnd.help;
-
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.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_ATTRIBUTE + "=\"[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_ATTRIBUTE + "=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_ATTRIBUTE + "=1.3", null,
-																			Verifier.VERSIONRANGE);
-
-	static Syntax							path_version			= new Syntax(
-																			VERSION_ATTRIBUTE,
-																			"Specifies the range in the repository, project or file.",
-																			VERSION_ATTRIBUTE + "=project", "project,type", Pattern
-																					.compile("project|type|"
-																							+ Verifier.VERSIONRANGE
-																									.toString()));
-
-	static final Syntax[]					syntaxes				= new Syntax[] {
-			new Syntax(
-					BUNDLE_ACTIVATIONPOLICY,
-					"The " + BUNDLE_ACTIVATIONPOLICY + " header 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 + " header 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.", "size=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_ATTRIBUTE + "=\"Describe 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,
-					"The " + BUNDLE_MANIFESTVERSION + " header is set by bnd automatically to 2. The header defines that the bundle follows the rules of this specification.",
-					"# " + BUNDLE_MANIFESTVERSION + ": 2", "2", Verifier.NUMBERPATTERN),
-			new Syntax(
-					BUNDLE_NAME,
-					"The " + BUNDLE_NAME + " header will be derived from the " + BUNDLE_SYMBOLICNAME + " header 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_ATTRIBUTE + "=MacOS", Processor.join(
-							Verifier.OSNAMES, ","), Verifier.ANYPATTERN),
-					new Syntax(OSVERSION_ATTRIBUTE, "Operating System Version.", OSVERSION_ATTRIBUTE + "=3.1", null,
-							Verifier.ANYPATTERN),
-					new Syntax(LANGUAGE_ATTRIBUTE, "Language ISO 639 code.", LANGUAGE_ATTRIBUTE + "=nl", null, Verifier.ISO639),
-					new Syntax(PROCESSOR_ATTRIBUTE, "Processor name.", PROCESSOR_ATTRIBUTE + "=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_ATTRIBUTE + "=\"(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.",
-							SINGLETON_DIRECTIVE + "=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 page 73. 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 " + NO_IMPORT_DIRECTIVE + " to an exported package will make it export only.",
-							NO_IMPORT_DIRECTIVE + "=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_DIRECTIVE + "=\"bar,foo\"", null, null), new Syntax(INCLUDE_DIRECTIVE,
-							"A comma-separated list of class names that must be visible to an importer.",
-							INCLUDE_DIRECTIVE + "=\"Qux*\"", null, null), new Syntax(EXCLUDE_DIRECTIVE,
-							"A comma-separated list of class names that must not be visible to an importer.",
-							EXCLUDE_DIRECTIVE + "=\"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_DIRECTIVE + "=framework", "framework,bootclasspath", Pattern
-									.compile("framework|bootclasspath")), bundle_version),
-			new Syntax(
-					IMPORT_PACKAGE,
-					"The " + IMPORT_PACKAGE + " header is normally calculated by bnd, however, you can decorate packages or skip packages. The 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_DIRECTIVE + "=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_DIRECTIVE + "=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_DIRECTIVE + "=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_DIRECTIVE + "=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_DIRECTIVE + "=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.",
-					EXPORT_CONTENTS + "=!*impl*,*;version=3.0", null, null),
-
-			new Syntax(FAIL_OK, "Return with an ok status (0) even if the build generates errors.", FAIL_OK + "=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", "true,false",
-					Verifier.TRUEORFALSEPATTERN),
-
-			new Syntax(NOUSES, "Do not calculate the " + USES_DIRECTIVE + " directive on exports.", NOUSES + "=true", "true,false",
-					Verifier.TRUEORFALSEPATTERN),
-
-			new Syntax(PEDANTIC, "Warn about things that are not really wrong but still not right.", PEDANTIC + "=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)
-																	};
-
-	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
deleted file mode 100644
index f2dddc4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/help/Warnings.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package aQute.bnd.help;
-
-public interface Warnings {
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/help/packageinfo b/bundleplugin/src/main/java/aQute/bnd/help/packageinfo
deleted file mode 100644
index a4f1546..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/help/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/Make.java b/bundleplugin/src/main/java/aQute/bnd/make/Make.java
deleted file mode 100644
index 59d252a..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/make/Make.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package aQute.bnd.make;
-
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.regex.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-
-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
deleted file mode 100644
index cda13b4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/make/MakeBnd.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package aQute.bnd.make;
-
-import java.io.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.build.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-
-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);
-		}
-		return null;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java b/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java
deleted file mode 100644
index c799dc7..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/make/MakeCopy.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package aQute.bnd.make;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-
-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);
-		}
-		File f = builder.getFile(from);
-		if (f.isFile())
-			return new FileResource(f);
-		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
deleted file mode 100644
index 76fac28..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/make/calltree/CalltreeResource.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package aQute.bnd.make.calltree;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.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.
-	 */
-	@Override
-	public long lastModified() {
-		return 0;
-	}
-
-	/**
-	 * The write method is called to write the resource. We just call the static
-	 * method.
-	 */
-	@Override
-	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
-			@Override
-			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());
-														}
-													};
-
-	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
deleted file mode 100644
index b9d7e4f..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java
+++ /dev/null
@@ -1,365 +0,0 @@
-package aQute.bnd.make.component;
-
-import static aQute.bnd.osgi.Constants.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.annotation.component.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Clazz.MethodDef;
-import aQute.bnd.osgi.Descriptors.TypeRef;
-import aQute.service.reporter.*;
-
-/**
- * This converts bnd style annotations to, roughly, the header format.
- *
- */
-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;
-	}
-
-	@Override
-	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);
-
-			//this error reporting currently handled in HeaderReader.  If we rewrite this to go directly to ComponentDesc, we'll want this.
-//			if (unbind != null && !descriptors.contains(unbind))
-//				reporter.error("In component %s, for bind method %s, missing unbind method %s", name, bind, 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("\\s*([^=\\s]+)\\s*=(.+)");
-
-	private void doProperties(aQute.bnd.osgi.Annotation annotation) {
-		Object[] properties = annotation.get(Component.PROPERTIES);
-
-		if (properties != null) {
-			for (Object o : properties) {
-				String p = (String) o;
-				Matcher m = PROPERTY_PATTERN.matcher(p);
-				if (m.matches())
-					this.properties.add(m.group(1)+"="+m.group(2));
-				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
deleted file mode 100644
index eaa5ddb..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java
+++ /dev/null
@@ -1,286 +0,0 @@
-package aQute.bnd.make.component;
-
-import java.io.*;
-import java.util.*;
-import java.util.Map.Entry;
-
-import aQute.bnd.annotation.component.*;
-import aQute.bnd.component.*;
-import aQute.bnd.header.*;
-import aQute.bnd.make.metatype.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Clazz.QUERY;
-import aQute.bnd.osgi.Descriptors.TypeRef;
-import aQute.bnd.service.*;
-import aQute.lib.tag.*;
-
-/**
- * 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);
-					throw 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;
-				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 Exception {
-
-			// 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 Exception {
-			Tag tag = new HeaderReader(analyzer).createComponentTag(name, impl, info);
-			return new TagResource(tag);
-		}
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java b/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java
deleted file mode 100644
index 672c5cd..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/make/coverage/Coverage.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package aQute.bnd.make.coverage;
-
-import java.io.*;
-import java.util.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Clazz.MethodDef;
-import aQute.bnd.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;
-
-				@Override
-				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
-				@Override
-				public void method(MethodDef source) {
-//					this.source = source;
-				}
-
-				// TODO need to use different reference method
-//				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() {
-
-				@Override
-				public boolean classStart(int access, TypeRef name) {
-					return clazz.isPublic();
-				}
-
-				@Override
-				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
deleted file mode 100644
index 753b69d..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/make/coverage/CoverageResource.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package aQute.bnd.make.coverage;
-
-import static aQute.bnd.make.coverage.Coverage.*;
-
-import java.io.*;
-import java.util.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.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());
-			if ( classTag != null)
-				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
deleted file mode 100644
index be717e2..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/make/metatype/MetaTypeReader.java
+++ /dev/null
@@ -1,322 +0,0 @@
-package aQute.bnd.make.metatype;
-
-import java.io.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.annotation.metatype.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Clazz.MethodDef;
-import aQute.bnd.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 && optionValues != 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() {
-			@Override
-			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();
-			}
-		}
-
-	}
-
-	@Override
-	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
deleted file mode 100644
index 4f30469..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/make/metatype/MetatypePlugin.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package aQute.bnd.make.metatype;
-
-import java.util.*;
-
-import aQute.bnd.annotation.metatype.*;
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Clazz.QUERY;
-import aQute.bnd.service.*;
-
-/**
- * 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
deleted file mode 100644
index 85125ce..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/BsnToMavenPath.java
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index bf5e15c..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/MavenCommand.java
+++ /dev/null
@@ -1,618 +0,0 @@
-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.header.*;
-import aQute.bnd.maven.support.*;
-import aQute.bnd.maven.support.Pom.Scope;
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Descriptors.PackageRef;
-import aQute.lib.collections.*;
-import aQute.lib.io.*;
-import aQute.lib.settings.*;
-import aQute.libg.command.*;
-
-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);
-		if (!temp.exists() && !temp.mkdirs()) {
-			throw new IOException("Could not create directory " + temp);
-		}
-		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.printf("Usage:%n");
-		System.err
-				.printf("  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>%n");
-	}
-
-	/**
-	 * 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.remove("email");
-			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");
-		if (!original.exists() && !original.mkdirs()) {
-			throw new IOException("Could not create directory " + original);
-		}
-		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");
-		if (!bundle.exists() && !bundle.mkdirs()) {
-			throw new IOException("Could not create directory " + bundle);
-		}
-
-		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");
-		if (!tmp.exists() && !tmp.mkdirs()) {
-			throw new IOException("Could not create directory " + tmp);
-		}
-
-		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
deleted file mode 100644
index e9e928e..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/MavenDependencyGraph.java
+++ /dev/null
@@ -1,130 +0,0 @@
-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<URI,Artifact>				cache			= new HashMap<URI,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);
-		}
-
-		@Override
-		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 {
-				URI url = new URL(path + ".pom").toURI();
-				if (cache.containsKey(url)) {
-					return cache.get(url);
-				}
-				return new Artifact(url.toURL());
-			}
-			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
deleted file mode 100644
index 592b3f9..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/MavenDeploy.java
+++ /dev/null
@@ -1,195 +0,0 @@
-package aQute.bnd.maven;
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import aQute.bnd.build.*;
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-import aQute.libg.command.*;
-import aQute.service.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, String jarName, InputStream jarStream) 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", jarName, repository);
-		File target = project.getTarget();
-		File tmp = Processor.getFile(target, repository);
-		if (!tmp.exists() && !tmp.mkdirs()) {
-			throw new IOException("Could not create directory " + tmp);
-		}
-
-		Jar original = new Jar(jarName, jarStream);
-		try {
-			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();
-				}
-			}
-		}
-		finally {
-			original.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, @SuppressWarnings("unused") 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
deleted file mode 100644
index 8d19093..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/MavenDeployCmd.java
+++ /dev/null
@@ -1,226 +0,0 @@
-package aQute.bnd.maven;
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import aQute.bnd.build.*;
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.libg.command.*;
-import aQute.service.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.printf("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);
-		if (!tmp.exists() && !tmp.mkdirs()) {
-			throw new IOException("Could not create directory " + tmp);
-		}
-
-		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");
-				if (!jdoc.exists() && !jdoc.mkdirs()) {
-					throw new IOException("Could not create directory " + jdoc);
-				}
-				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, @SuppressWarnings("unused") 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
deleted file mode 100644
index 7be8c9e..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/MavenGroup.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package aQute.bnd.maven;
-
-import java.util.*;
-
-import aQute.bnd.service.*;
-import aQute.service.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
deleted file mode 100644
index d8d54e0..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/MavenRepository.java
+++ /dev/null
@@ -1,224 +0,0 @@
-package aQute.bnd.maven;
-
-import java.io.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-import aQute.bnd.version.*;
-import aQute.lib.collections.*;
-import aQute.service.reporter.*;
-
-public class MavenRepository implements RepositoryPlugin, Plugin, BsnToMavenPath {
-
-	public final static String	NAME	= "name";
-
-	File						root;
-	Reporter					reporter;
-	String						name;
-
-	@Override
-	public String toString() {
-		return "maven:" + root;
-	}
-
-	public boolean canWrite() {
-		return false;
-	}
-
-	private 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 PutResult put(InputStream stream, PutOptions options) throws Exception {
-		throw new UnsupportedOperationException("Maven does not support the put command");
-	}
-
-	public SortedSet<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);
-		}
-		if ( versions.isEmpty())
-			return SortedList.empty();
-		
-		return new SortedList<Version>(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];
-				case EXACT :
-					// TODO exact
-					break;
-			}
-		}
-		return null;
-	}
-
-	public void setRoot(File f) {
-		root = f;
-	}
-
-	public String getLocation() {
-		return root.toString();
-	}
-
-	public File get(String bsn, Version version, Map<String,String> properties, DownloadListener ... listeners) throws Exception {
-		File file = get(bsn, version.toString(), Strategy.EXACT, properties);
-		if ( file == null)
-			return null;
-		
-		for (DownloadListener l : listeners) {
-			try {
-				l.success(file);
-			}
-			catch (Exception e) {
-				reporter.exception(e, "Download listener for %s", file);
-			}
-		}
-		return file;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java b/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java
deleted file mode 100644
index 33d9d44..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java
+++ /dev/null
@@ -1,249 +0,0 @@
-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.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.version.*;
-import aQute.lib.io.*;
-import aQute.lib.tag.*;
-
-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
deleted file mode 100644
index 3eda682..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/PomParser.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package aQute.bnd.maven;
-
-import java.io.*;
-import java.util.*;
-
-import javax.xml.parsers.*;
-import javax.xml.xpath.*;
-
-import org.w3c.dom.*;
-
-import aQute.bnd.osgi.*;
-import aQute.lib.io.*;
-
-/**
- * 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
deleted file mode 100644
index b3582a3..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/PomResource.java
+++ /dev/null
@@ -1,162 +0,0 @@
-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.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.lib.io.*;
-import aQute.lib.tag.*;
-
-public class PomResource extends WriteResource {
-	final Manifest				manifest;
-	private Map<String,String>	scm;
-	final static Pattern		NAME_URL	= Pattern.compile("(.*)(http://.*)");
-
-	public PomResource(Manifest manifest) {
-		this.manifest = manifest;
-	}
-
-	@Override
-	public long lastModified() {
-		return 0;
-	}
-
-	@Override
-	public void write(OutputStream out) throws IOException {
-		PrintWriter ps = 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
deleted file mode 100644
index d784767..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/support/CachedPom.java
+++ /dev/null
@@ -1,19 +0,0 @@
-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;
-	}
-
-	@Override
-	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
deleted file mode 100644
index 416f255..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/support/Maven.java
+++ /dev/null
@@ -1,89 +0,0 @@
-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
deleted file mode 100644
index 4e153c3..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenEntry.java
+++ /dev/null
@@ -1,348 +0,0 @@
-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;
-	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();
-		if (!this.dir.exists() && !this.dir.mkdirs()) {
-			throw new ExceptionInInitializerError("Could not create directory " + this.dir);
-		}
-		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 {
-				if (!dir.exists() && !dir.mkdirs()) {
-					throw new IOException("Could not create directory " + dir);
-				}
-				// 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
-	 */
-	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
deleted file mode 100644
index 345d3eb..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenRemoteRepository.java
+++ /dev/null
@@ -1,146 +0,0 @@
-package aQute.bnd.maven.support;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-import aQute.bnd.service.*;
-import aQute.bnd.version.*;
-import aQute.lib.io.*;
-import aQute.service.reporter.*;
-
-public class MavenRemoteRepository implements RepositoryPlugin, RegistryPlugin, Plugin {
-	Reporter	reporter;
-	URI[]		repositories;
-	Registry	registry;
-	Maven		maven;
-
-	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 PutResult put(InputStream stream, PutOptions options) throws Exception {
-		throw new UnsupportedOperationException("cannot do put");
-	}
-
-	public List<String> list(String regex) throws Exception {
-		throw new UnsupportedOperationException("cannot do list");
-	}
-
-	public SortedSet<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);
-	}
-
-	public File get(String bsn, Version version, Map<String,String> properties, DownloadListener ... listeners) throws Exception {
-		File f= get(bsn, version.toString(), Strategy.EXACT, properties);
-		if ( f == null)
-			return null;
-		
-		for (DownloadListener l : listeners) {
-			try {
-				l.success(f);
-			}
-			catch (Exception e) {
-				reporter.exception(e, "Download listener for %s", f);
-			}
-		}
-		return f;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/Pom.java b/bundleplugin/src/main/java/aQute/bnd/maven/support/Pom.java
deleted file mode 100644
index a778d8b..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/support/Pom.java
+++ /dev/null
@@ -1,350 +0,0 @@
-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;
-	}
-
-	@Override
-	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
deleted file mode 100644
index eedff8c..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/support/ProjectPom.java
+++ /dev/null
@@ -1,205 +0,0 @@
-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*\\})");
-
-	@Override
-	protected String replace(String in) {
-		System.err.println("Replce: " + in);
-		if (in == null) {
-			System.err.println("null??");
-			in = "<<???>>";
-		}
-		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
deleted file mode 100644
index dd1939f..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/support/Repo.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package aQute.bnd.maven.support;
-
-public class Repo {
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/packageinfo b/bundleplugin/src/main/java/aQute/bnd/maven/support/packageinfo
deleted file mode 100644
index a3d9bcc..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/maven/support/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 2.0
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/About.java b/bundleplugin/src/main/java/aQute/bnd/osgi/About.java
deleted file mode 100755
index f2b7240..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/About.java
+++ /dev/null
@@ -1,39 +0,0 @@
-package aQute.bnd.osgi;
-
-import aQute.bnd.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 {
-	// Empty
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/AbstractResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/AbstractResource.java
deleted file mode 100644
index e023985..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/AbstractResource.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package aQute.bnd.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/bnd/osgi/Analyzer.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
deleted file mode 100755
index 7548f51..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
+++ /dev/null
@@ -1,2644 +0,0 @@
-package aQute.bnd.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.text.*;
-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.header.*;
-import aQute.bnd.osgi.Descriptors.Descriptor;
-import aQute.bnd.osgi.Descriptors.PackageRef;
-import aQute.bnd.osgi.Descriptors.TypeRef;
-import aQute.bnd.service.*;
-import aQute.bnd.version.*;
-import aQute.bnd.version.Version;
-import aQute.lib.base64.*;
-import aQute.lib.collections.*;
-import aQute.lib.filter.*;
-import aQute.lib.hex.*;
-import aQute.lib.io.*;
-import aQute.libg.cryptography.*;
-import aQute.libg.generics.*;
-import aQute.libg.reporter.*;
-
-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 MultiMap<PackageRef,PackageRef>	apiUses					= 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;
-	final protected AnalyzerMessages				msgs					= ReporterMessages.base(this,
-																					AnalyzerMessages.class);
-
-	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();
-			apiUses.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");
-					getExportVersionsFromPackageInfo(packageRef, resource, classpathExports);
-				}
-			}
-
-			// Handle the bundle activator
-
-			String s = getProperty(BUNDLE_ACTIVATOR);
-			if (s != null) {
-				activator = getTypeRefFromFQN(s);
-				referTo(activator);
-				trace("activator %s %s", s, 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
-
-			boolean api = isTrue(getProperty(EXPERIMENTS)) || true; // brave,
-																	// lets see
-
-			doUses(exports, api ? apiUses : uses, imports);
-
-			//
-			// Verify that no exported package has a reference to a private
-			// package
-			// This can cause a lot of harm.
-			// TODO restrict the check to public API only, but even then
-			// exported packages
-			// should preferably not refer to private packages.
-			//
-			Set<PackageRef> privatePackages = getPrivates();
-
-			// References to java are not imported so they would show up as
-			// private
-			// packages, lets kill them as well.
-
-			for (Iterator<PackageRef> p = privatePackages.iterator(); p.hasNext();)
-				if (p.next().isJava())
-					p.remove();
-
-			for (PackageRef exported : exports.keySet()) {
-				List<PackageRef> used = uses.get(exported);
-				if (used != null) {
-					Set<PackageRef> privateReferences = new HashSet<PackageRef>(apiUses.get(exported));
-					privateReferences.retainAll(privatePackages);
-					if (!privateReferences.isEmpty())
-						msgs.Export_Has_PrivateReferences_(exported, privateReferences.size(), privateReferences);
-				}
-			}
-
-			//
-			// 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 {
-				Processor previous = beginHandleErrors(plugin.toString());
-				boolean reanalyze = plugin.analyzeJar(this);
-				endHandleErrors(previous);
-				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 {
-		try {
-			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?
-				}
-			}
-
-			// Copy old values into new manifest, when they
-			// exist in the old one, but not in the new one
-			merge(manifest, dot.getManifest());
-
-			//
-			// 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");
-
-			// 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);
-
-			// We should not set the manifest here, this is in general done
-			// by the caller.
-			// dot.setManifest(manifest);
-			return manifest;
-		}
-		catch (Exception e) {
-			// This should not really happen. The code should never throw
-			// exceptions in normal situations. So if it happens we need more
-			// information. So to help diagnostics. We do a full property dump
-			throw new IllegalStateException("Calc manifest failed, state=\n" + getFlattenedProperties(), e);
-		}
-	}
-
-	/**
-	 * 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(@SuppressWarnings("unused")
-	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 Set<PackageRef> getPrivates() {
-		HashSet<PackageRef> privates = new HashSet<PackageRef>(contained.keySet());
-		privates.removeAll(exports.keySet());
-		privates.removeAll(imports.keySet());
-		return privates;
-	}
-
-	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 Map<PackageRef,List<PackageRef>> getUses() {
-		return uses;
-	}
-
-	public Map<PackageRef,List<PackageRef>> getAPIUses() {
-		return apiUses;
-	}
-
-	public Packages getClasspathExports() {
-		return classpathExports;
-	}
-
-	/**
-	 * Get the version for this bnd
-	 * 
-	 * @return version or unknown.
-	 */
-	public String getBndVersion() {
-		return getBndInfo("version", "<unknown>");
-	}
-
-	static SimpleDateFormat df = new SimpleDateFormat("EEE MMM dd hh:mm:ss z yyyy");
-	public long getBndLastModified() {
-		String time = getBndInfo("lastmodified", "0");
-		if ( time.matches("\\d+"))
-			return Long.parseLong(time);
-		
-		try {
-			Date parse = df.parse(time);
-			if ( parse != null)
-				return parse.getTime();
-		} catch( ParseException e) {
-			// Ignore
-		}
-		return 0;
-	}
-
-	public String getBndInfo(String key, String defaultValue) {
-		if (bndInfo == null) {
-			try {
-				Properties bndInfoLocal = new Properties();
-				URL url = Analyzer.class.getResource("bnd.info");
-				if (url != null) {
-					InputStream in = url.openStream();
-					try {
-						bndInfoLocal.load(in);
-					}
-					finally {
-						in.close();
-					}
-				}
-				bndInfo = bndInfoLocal;
-			}
-			catch (Exception e) {
-				e.printStackTrace();
-				return defaultValue;
-			}
-		}
-		String value = bndInfo.getProperty(key);
-		if (value == null)
-			return defaultValue;
-		return value;
-	}
-
-	/**
-	 * 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));
-			}
-		}
-	}
-
-	@Override
-	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;
-	}
-
-	@Override
-	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) {
-		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);
-
-			// We had an NPE on usedByExportedPackage in GF.
-			// I guess this can happen with hard coded
-			// imports that do not match reality ...
-			if (usedByExportedPackage == null || usedByExportedPackage.isEmpty()) {
-				continue;
-			}
-
-			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 == null ? null : 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, Map<PackageRef,List<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, Map<PackageRef,List<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 getExportVersionsFromPackageInfo(PackageRef packageRef, Resource r, Packages classpathExports)
-			throws Exception {
-		if (r == null)
-			return;
-
-		Properties p = new Properties();
-		try {
-			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 (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);
-				}
-			}
-		}
-		catch (Exception e) {
-			msgs.NoSuchFile_(r);
-		}
-	}
-
-	@Override
-	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);
-	}
-
-	@Override
-	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");
-							getExportVersionsFromPackageInfo(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");
-								getExportVersionsFromPackageInfo(packageRef, pinfo, classpathExports);
-							}
-						}
-						if (info != null)
-							contained.merge(packageRef, false, info);
-
-						// Look at the referred packages
-						// and copy them to our baseline
-						Set<PackageRef> refs = Create.set();
-						for (PackageRef p : clazz.getReferred()) {
-							referred.put(p);
-							refs.add(p);
-						}
-						refs.remove(packageRef);
-						uses.addAll(packageRef, refs);
-
-						// Collect the API
-						apiUses.addAll(packageRef, clazz.getAPIUses());
-					}
-				}
-			}
-		}
-
-		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()) {
-			try {
-				VersionRange vr = new VersionRange(version);
-				return version;
-			} catch( Exception e) {
-				// ignore
-			}
-		}
-
-		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;
-		}
-
-		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 (qualifier == null) {
-				if (!isInteger(minor)) {
-					qualifier = minor;
-					minor = "0";
-				} else if (!isInteger(micro)) {
-					qualifier = micro;
-					micro = "0";
-				}
-			}
-			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;
-	}
-
-	/**
-	 * TRhe cleanup version got confused when people used numeric dates like
-	 * 201209091230120 as qualifiers. These are too large for Integers. This
-	 * method checks if the all digit string fits in an integer.
-	 * <pre>
-	 * maxint = 2,147,483,647 = 10 digits
-	 * </pre>	 
-	 * @param integer
-	 * @return if this fits in an integer
-	 */
-	private static boolean isInteger(String minor) {
-		return minor.length() < 10 || (minor.length() == 10 && minor.compareTo("2147483647") < 0);
-	}
-
-	private static String removeLeadingZeroes(String group) {
-		if (group == null)
-			return "0";
-
-		int n = 0;
-		while (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;[==,+)}";
-
-	public String getVersionPolicy(boolean implemented) {
-		if (implemented) {
-			return getProperty(PROVIDER_POLICY, DEFAULT_PROVIDER_POLICY);
-		}
-
-		return getProperty(CONSUMER_POLICY, DEFAULT_CONSUMER_POLICY);
-	}
-
-	/**
-	 * 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("annotation"))
-				typeName = "annotated";
-			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());
-
-		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
-			// #252, we should not be negated to make it a constant
-			if (instruction.isLiteral() && !instruction.isNegated()) {
-				result.merge(getPackageRef(instruction.getLiteral()), true, instructions.get(instruction));
-				i.remove();
-				continue;
-			}
-
-			// Not matching a negated instruction looks
-			// like an error ... Though so, but
-			// in the second phase of Export-Package
-			// the !package will never match anymore.
-			if (instruction.isNegated()) {
-				i.remove();
-				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(@SuppressWarnings("unused")
-	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();
-
-		Entry<String,Attrs> name = getBundleSymbolicName();
-		if (name != null) {
-			String bsn = name.getKey();
-			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) {
-			File op = output.getParentFile();
-			if (!op.exists() && !op.mkdirs()) {
-				throw new IOException("Could not create directory " + op);
-			}
-			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;
-		}
-		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);
-	}
-
-	/**
-	 * Remove the own references and optional java references from the uses lib
-	 * 
-	 * @param apiUses
-	 * @param removeJava
-	 * @return
-	 */
-	public Map<PackageRef,List<PackageRef>> cleanupUses(Map<PackageRef,List<PackageRef>> apiUses, boolean removeJava) {
-		MultiMap<PackageRef,PackageRef> map = new MultiMap<PackageRef,PackageRef>(apiUses);
-		for (Entry<PackageRef,List<PackageRef>> e : map.entrySet()) {
-			e.getValue().remove(e.getKey());
-			if (!removeJava)
-				continue;
-
-			for (Iterator<PackageRef> i = e.getValue().iterator(); i.hasNext();) {
-				if (i.next().isJava())
-					i.remove();
-			}
-		}
-		return map;
-	}
-
-	/**
-	 * Return the classes for a given source package.
-	 * 
-	 * @param source
-	 *            the source package
-	 * @return a set of classes for the requested package.
-	 */
-	public Set<Clazz> getClassspace(PackageRef source) {
-		Set<Clazz> result = new HashSet<Clazz>();
-		for (Clazz c : getClassspace().values()) {
-			if (c.getClassName().getPackageRef() == source)
-				result.add(c);
-		}
-		return result;
-	}
-
-	/**
-	 * Create a cross reference from package source, to packages in dest
-	 * 
-	 * @param source
-	 * @param dest
-	 * @param sourceModifiers
-	 * @return
-	 * @throws Exception
-	 */
-	public Map<Clazz.Def,List<TypeRef>> getXRef(final PackageRef source, final Collection<PackageRef> dest,
-			final int sourceModifiers) throws Exception {
-		final MultiMap<Clazz.Def,TypeRef> xref = new MultiMap<Clazz.Def,TypeRef>(Clazz.Def.class, TypeRef.class, true);
-
-		for (final Clazz clazz : getClassspace().values()) {
-			if ((clazz.accessx & sourceModifiers) == 0)
-				continue;
-
-			if (source != null && source != clazz.getClassName().getPackageRef())
-				continue;
-
-			clazz.parseClassFileWithCollector(new ClassDataCollector() {
-				Clazz.Def	member;
-
-				@Override
-				public void extendsClass(TypeRef zuper) throws Exception {
-					if (dest.contains(zuper.getPackageRef()))
-						xref.add(clazz.getExtends(zuper), zuper);
-				}
-
-				@Override
-				public void implementsInterfaces(TypeRef[] interfaces) throws Exception {
-					for (TypeRef i : interfaces) {
-						if (dest.contains(i.getPackageRef()))
-							xref.add(clazz.getImplements(i), i);
-					}
-				}
-
-				@Override
-				public void referTo(TypeRef to, int modifiers) {
-					if (to.isJava())
-						return;
-
-					if (!dest.contains(to.getPackageRef()))
-						return;
-
-					if (member != null && ((modifiers & sourceModifiers) != 0)) {
-						xref.add(member, to);
-					}
-
-				}
-
-				@Override
-				public void method(Clazz.MethodDef defined) {
-					member = defined;
-				}
-
-				@Override
-				public void field(Clazz.FieldDef defined) {
-					member = defined;
-				}
-
-			});
-
-		}
-		return xref;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/AnalyzerMessages.java b/bundleplugin/src/main/java/aQute/bnd/osgi/AnalyzerMessages.java
deleted file mode 100644
index 95b32df..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/AnalyzerMessages.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package aQute.bnd.osgi;
-
-import java.util.*;
-
-import aQute.bnd.osgi.Descriptors.PackageRef;
-import aQute.service.reporter.*;
-
-public interface AnalyzerMessages extends Messages {
-
-	WARNING Export_Has_PrivateReferences_(PackageRef exported, int count, Collection<PackageRef> local);
-/**/
-}
-
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Annotation.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Annotation.java
deleted file mode 100644
index aca0a11..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Annotation.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package aQute.bnd.osgi;
-
-import java.lang.annotation.*;
-import java.util.*;
-
-import aQute.bnd.annotation.metatype.*;
-import aQute.bnd.osgi.Descriptors.TypeRef;
-
-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;
-	}
-
-	@Override
-	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();
-		try {
-			Class<T> c = (Class<T>) getClass().getClassLoader().loadClass(cname);
-			return getAnnotation(c);
-		}
-		catch (ClassNotFoundException e) {
-		}
-		catch (NoClassDefFoundError e) {
-		}
-		return null;
-	}
-
-	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/bnd/osgi/Builder.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Builder.java
deleted file mode 100755
index 0970bd3..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Builder.java
+++ /dev/null
@@ -1,1527 +0,0 @@
-package aQute.bnd.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.header.*;
-import aQute.bnd.make.*;
-import aQute.bnd.make.component.*;
-import aQute.bnd.make.metatype.*;
-import aQute.bnd.maven.*;
-import aQute.bnd.osgi.Descriptors.PackageRef;
-import aQute.bnd.osgi.Descriptors.TypeRef;
-import aQute.bnd.service.*;
-import aQute.bnd.service.diff.*;
-import aQute.lib.collections.*;
-import aQute.libg.generics.*;
-
-/**
- * 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());
-
-		doDigests(dot);
-		
-		sign(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.setDigestAlgorithms(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();
-		File fp = f.getParentFile();
-		if (!fp.exists() && !fp.mkdirs()) {
-			throw new IOException("Could not create directory " + fp);
-		}
-		OutputStream out = new FileOutputStream(f);
-		try {
-			Jar.writeManifest(dot.getManifest(), out);
-		}
-		finally {
-			out.close();
-		}
-		changedFile(f);
-	}
-
-	protected void changedFile(@SuppressWarnings("unused") File f) {}
-
-	/**
-	 * Sign the jar file. -sign : <alias> [ ';' 'password:=' <password> ] [ ';'
-	 * 'keystore:=' <keystore> ] [ ';' 'sign-password:=' <pw> ] ( ',' ... )*
-	 * 
-	 * @return
-	 */
-
-	void sign(@SuppressWarnings("unused") 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
-	 */
-	@Override
-	protected Jar getExtra() throws Exception {
-		Parameters conditionals = getParameters(CONDITIONAL_PACKAGE);
-		if (conditionals.isEmpty())
-			return null;
-		trace("do Conditional Package %s", conditionals);
-		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) {
-					copy(jar, cpe, pref.getPath(), false);
-// Now use copy so that bnd.info is processed, next line should be 
-// removed in the future TODO
-//					jar.addDirectory(map, false);
-					break;
-				}
-			}
-		}
-		if (jar.getDirectories().size() == 0) {
-			trace("extra dirs %s", jar.getDirectories());
-			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.
-	 */
-
-	@Override
-	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(@SuppressWarnings("unused") 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) {
-
-		// 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) {
-		trace("copy d=" + dest + " s=" + srce +" p="+ path);
-		dest.copy(srce, path, overwrite);
-		
-		// bnd.info sources must be preprocessed
-		String bndInfoPath = path + "/bnd.info";
-		Resource r = dest.getResource(bndInfoPath);
-		if ( r != null && !(r instanceof PreprocessResource)) {
-			trace("preprocessing bnd.info");
-			PreprocessResource pp = new PreprocessResource(this, r);
-			dest.putResource(bndInfoPath, pp);
-		}
-		
-		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_ATTRIBUTE)) {
-			String literal = extra.get(LITERAL_ATTRIBUTE);
-			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();
-			cr.lastModified = lastModified;
-		}
-		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);
-				if ( file.exists())
-					lastModified = Math.max(lastModified, file.lastModified());
-				
-				Resource r = new CommandResource(command, this, lastModified, getBase());
-
-				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);
-		
-		updateModified(lastModified, "Include-Resource: cmd");
-	}
-
-	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);
-			}
-		}
-		if (fs.length == 0) {
-			File empty = new File(dir, Constants.EMPTY_HEADER);
-			files.put(appendPath(path, empty.getName()), empty);
-		}
-	}
-
-	private void noSuchFile(Jar jar, @SuppressWarnings("unused") 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 if (from.getName().equals(Constants.EMPTY_HEADER)) {
-				jar.putResource(path, new EmbeddedResource(new byte[0], 0));
-			} 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);
-	}
-
-	@Override
-	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() && !file.getName().startsWith(".")) {
-				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[]) {
-		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-Package 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) {
-
-				if (cpEntry.equals("")) // Meaning we actually have a CPE
-					return true;
-
-				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. It is
-	 * possible that the resource is a classpath entry. In that case an empty
-	 * string is returned.
-	 * 
-	 * @param resource
-	 *            The resource to look for
-	 * @return A suffix on the classpath or "" if the resource is a class path
-	 *         entry
-	 * @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 (sourcePath.equals(resourcePath))
-					return ""; // Matches a classpath entry
-
-				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(@SuppressWarnings("unused") 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);
-	}
-
-	
-	public void addSourcepath(Collection<File> sourcepath) {
-		for (File f : sourcepath) {
-			addSourcepath(f);
-		}
-	}
-
-	/**
-	 * Base line against a previous version. Should be overridden in the ProjectBuilder where we have access to the repos
-	 * 
-	 * @throws Exception
-	 */
-
-	protected void doBaseline(Jar dot) throws Exception {}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/BundleId.java b/bundleplugin/src/main/java/aQute/bnd/osgi/BundleId.java
deleted file mode 100644
index 67f9b4a..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/BundleId.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package aQute.bnd.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);
-	}
-
-	@Override
-	public boolean equals(Object o) {
-		return this == o || ((o instanceof BundleId) && compareTo((BundleId) o) == 0);
-	}
-
-	@Override
-	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/bnd/osgi/ClassDataCollector.java b/bundleplugin/src/main/java/aQute/bnd/osgi/ClassDataCollector.java
deleted file mode 100644
index 17aa62e..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/ClassDataCollector.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package aQute.bnd.osgi;
-
-import aQute.bnd.osgi.Descriptors.TypeRef;
-
-@SuppressWarnings("unused")
-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 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) {}
-
-	public void referenceMethod(int access, TypeRef className, String method, String descriptor) {}
-
-	/**
-	 * A reference to a type from method or field. The modifiers indicate the
-	 * access level of the parent method/field.
-	 * 
-	 * @param typeRef
-	 * @param modifiers
-	 */
-	public void referTo(TypeRef typeRef, int modifiers) {}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java
deleted file mode 100755
index 391bf45..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Clazz.java
+++ /dev/null
@@ -1,1737 +0,0 @@
-package aQute.bnd.osgi;
-
-import java.io.*;
-import java.lang.annotation.*;
-import java.lang.reflect.*;
-import java.nio.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.osgi.Descriptors.Descriptor;
-import aQute.bnd.osgi.Descriptors.PackageRef;
-import aQute.bnd.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, @SuppressWarnings("unused")
-		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 abstract 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 TypeRef getOwnerType() {
-			return className;
-		}
-
-		public abstract String getName();
-
-		public abstract TypeRef getType();
-
-		public abstract TypeRef[] getPrototype();
-
-		public Object getClazz() {
-			return Clazz.this;
-		}
-	}
-
-	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);
-		}
-
-		@Override
-		public String getName() {
-			return name;
-		}
-
-		@Override
-		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);
-		}
-
-		@Override
-		public TypeRef[] getPrototype() {
-			return null;
-		}
-
-		public String getSignature() {
-			return signature;
-		}
-
-		@Override
-		public String toString() {
-			return name;
-		}
-	}
-
-	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>");
-		}
-
-		@Override
-		public TypeRef[] getPrototype() {
-			return descriptor.getPrototype();
-		}
-	}
-
-	public class TypeDef extends Def {
-		TypeRef	type;
-		boolean	interf;
-
-		public TypeDef(TypeRef type, boolean interf) {
-			super(Modifier.PUBLIC);
-			this.type = type;
-			this.interf = interf;
-		}
-
-		public TypeRef getReference() {
-			return type;
-		}
-
-		public boolean getImplements() {
-			return interf;
-		}
-
-		@Override
-		public String getName() {
-			if (interf)
-				return "<implements>";
-			return "<extends>";
-		}
-
-		@Override
-		public TypeRef getType() {
-			return type;
-		}
-
-		@Override
-		public TypeRef[] getPrototype() {
-			return null;
-		}
-	}
-
-	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<TypeRef>		annotations;
-	int					forName		= 0;
-	int					class$		= 0;
-	TypeRef[]			interfaces;
-	TypeRef				zuper;
-	ClassDataCollector	cd			= null;
-	Resource			resource;
-	FieldDef			last		= null;
-	boolean				deprecated;
-	Set<PackageRef>		api;
-	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>();
-
-		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);
-
-		// All name& type and class constant records contain descriptors we must
-		// treat
-		// as references, though not API
-
-		for (Object o : pool) {
-			if (o == null)
-				continue;
-
-			if (o instanceof Assoc && ((Assoc) o).tag == 12) {
-				referTo(((Assoc) o).b, 0); // Descriptor
-			} else if (o instanceof ClassConstant) {
-				String binaryClassName = (String) pool[((ClassConstant) o).cname];
-				TypeRef typeRef = analyzer.getTypeRef(binaryClassName);
-				referTo(typeRef, 0);
-			}
-		}
-
-		/*
-		 * Parse after the constant pool, code thanks to Hans Christian
-		 * Falkenberg
-		 */
-
-		accessx = in.readUnsignedShort(); // access
-		if (Modifier.isPublic(accessx))
-			api = new HashSet<PackageRef>();
-
-		int this_class = in.readUnsignedShort();
-		className = analyzer.getTypeRef((String) pool[intPool[this_class]]);
-		referTo(className, Modifier.PUBLIC);
-
-		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, accessx);
-				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()]]);
-					referTo(interfaces[i], accessx);
-				}
-				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()));
-
-				referTo(descriptor_index, access_flags);
-				doAttributes(in, ElementType.FIELD, false, access_flags);
-			}
-
-			//
-			// 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();
-				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);
-				}
-				referTo(descriptor_index, access_flags);
-
-				if ("<init>".equals(name)) {
-					doAttributes(in, ElementType.CONSTRUCTOR, crawl, access_flags);
-				} else {
-					doAttributes(in, ElementType.METHOD, crawl, access_flags);
-				}
-			}
-			if (cd != null)
-				cd.memberEnd();
-
-			doAttributes(in, ElementType.TYPE, false, accessx);
-
-			//
-			// Parse all the descriptors we found
-			//
-
-			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(@SuppressWarnings("unused")
-	Object[] pool, @SuppressWarnings("unused")
-	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();
-		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();
-		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
-	 * @param access_flags
-	 * @throws Exception
-	 */
-	private void doAttributes(DataInputStream in, ElementType member, boolean crawl, int access_flags) throws Exception {
-		int attributesCount = in.readUnsignedShort();
-		for (int j = 0; j < attributesCount; j++) {
-			// skip name CONSTANT_Utf8 pointer
-			doAttribute(in, member, crawl, access_flags);
-		}
-	}
-
-	/**
-	 * Process a single attribute, if not recognized, skip it.
-	 * 
-	 * @param in
-	 *            the data stream
-	 * @param access_flags
-	 * @throws Exception
-	 */
-	private void doAttribute(DataInputStream in, ElementType member, boolean crawl, int access_flags) 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, access_flags);
-		else if ("RuntimeVisibleParameterAnnotations".equals(attributeName))
-			doParameterAnnotations(in, member, RetentionPolicy.RUNTIME, access_flags);
-		else if ("RuntimeInvisibleAnnotations".equals(attributeName))
-			doAnnotations(in, member, RetentionPolicy.CLASS, access_flags);
-		else if ("RuntimeInvisibleParameterAnnotations".equals(attributeName))
-			doParameterAnnotations(in, member, RetentionPolicy.CLASS, access_flags);
-		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, access_flags);
-		else if ("ConstantValue".equals(attributeName))
-			doConstantValue(in);
-		else if ("AnnotationDefault".equals(attributeName))
-			doElementValue(in, member, RetentionPolicy.RUNTIME, cd!=null, access_flags);
-		else if ("Exceptions".equals(attributeName))
-			doExceptions(in, access_flags);
-		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
-	 * @param access_flags
-	 */
-
-	void doSignature(DataInputStream in, ElementType member, int access_flags) throws IOException {
-		int signature_index = in.readUnsignedShort();
-		String signature = (String) pool[signature_index];
-
-		parseDescriptor(signature, access_flags);
-
-		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);
-	}
-
-	void doExceptions(DataInputStream in, int access_flags) throws IOException {
-		int exception_count = in.readUnsignedShort();
-		for (int i = 0; i < exception_count; i++) {
-			int index = in.readUnsignedShort();
-			if (api != null && (Modifier.isPublic(access_flags) || Modifier.isProtected(access_flags))) {
-				ClassConstant cc = (ClassConstant) pool[index];
-				String descr = (String) pool[cc.cname];
-
-				TypeRef clazz = analyzer.getTypeRef(descr);
-				referTo(clazz, access_flags);
-			}
-		}
-	}
-
-	/**
-	 * <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, 0);
-	}
-
-	/**
-	 * 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, 0);
-						}
-						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, int access_flags)
-			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, access_flags);
-		}
-	}
-
-	private void doAnnotations(DataInputStream in, ElementType member, RetentionPolicy policy, int access_flags)
-			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, access_flags);
-			else {
-				Annotation annotion = doAnnotation(in, member, policy, true, access_flags);
-				cd.annotation(annotion);
-			}
-		}
-	}
-
-	private Annotation doAnnotation(DataInputStream in, ElementType member, RetentionPolicy policy, boolean collect,
-			int access_flags) 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);
-
-		TypeRef name = analyzer.getTypeRef((String) pool[type_index]);
-		if (policy == RetentionPolicy.RUNTIME) {
-			referTo(type_index, 0);
-			hasRuntimeAnnotations = true;
-			if (api != null && (Modifier.isPublic(access_flags) || Modifier.isProtected(access_flags)))
-				api.add(name.getPackageRef());
-		} else {
-			hasClassAnnotations = true;
-		}
-		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, access_flags);
-			if (collect) {
-				if (elements == null)
-					elements = new LinkedHashMap<String,Object>();
-				elements.put(element, value);
-			}
-		}
-		if (collect)
-			return new Annotation(name, elements, member, policy);
-		return null;
-	}
-
-	private Object doElementValue(DataInputStream in, ElementType member, RetentionPolicy policy, boolean collect,
-			int access_flags) 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) {
-					referTo(type_name_index, 0);
-					if (api != null && (Modifier.isPublic(access_flags) || Modifier.isProtected(access_flags))) {
-						TypeRef name = analyzer.getTypeRef((String) pool[type_name_index]);
-						api.add(name.getPackageRef());
-					}
-				}
-				int const_name_index = in.readUnsignedShort();
-				return pool[const_name_index];
-
-			case 'c' : // Class
-				int class_info_index = in.readUnsignedShort();
-				if (policy == RetentionPolicy.RUNTIME) {
-					referTo(class_info_index, 0);
-					if (api != null && (Modifier.isPublic(access_flags) || Modifier.isProtected(access_flags))) {
-						TypeRef name = analyzer.getTypeRef((String) pool[class_info_index]);
-						api.add(name.getPackageRef());
-					}
-				}
-				return pool[class_info_index];
-
-			case '@' : // Annotation type
-				return doAnnotation(in, member, policy, collect, access_flags);
-
-			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, access_flags);
-				}
-				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, int modifiers) {
-		if (xref != null)
-			xref.add(typeRef);
-		if (typeRef.isPrimitive())
-			return;
-
-		PackageRef packageRef = typeRef.getPackageRef();
-		if (packageRef.isPrimitivePackage())
-			return;
-
-		imports.add(packageRef);
-
-		if (api != null && (Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers)))
-			api.add(packageRef);
-
-		if (cd != null)
-			cd.referTo(typeRef, modifiers);
-
-	}
-
-	void referTo(int index, int modifiers) {
-		String descriptor = (String) pool[index];
-		parseDescriptor(descriptor, modifiers);
-	}
-
-	/**
-	 * 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, int modifiers) {
-		// 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, modifiers);
-		}
-
-		if (descriptor.charAt(rover) == '(') {
-			rover = parseReferences(descriptor, rover + 1, ')', modifiers);
-			rover++;
-		}
-		parseReferences(descriptor, rover, (char) 0, modifiers);
-	}
-
-	/**
-	 * 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 modifiers) {
-		int r = rover;
-		while (r < descriptor.length() && descriptor.charAt(r) != delimiter) {
-			r = parseReference(descriptor, r, modifiers);
-		}
-		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 modifiers) {
-		int r = rover;
-		char c = descriptor.charAt(r);
-		while (c == '[')
-			c = descriptor.charAt(++r);
-
-		if (c == '<') {
-			r = parseReferences(descriptor, r + 1, '>', modifiers);
-		} 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, '>', modifiers);
-				} else
-					sb.append(c);
-				r++;
-			}
-			TypeRef ref = analyzer.getTypeRef(sb.toString());
-			if (cd != null)
-				cd.addReference(ref);
-
-			referTo(ref, modifiers);
-		} 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, int modifiers) {
-		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, modifiers); // class
-																		// reference
-				c = descriptor.charAt(index);
-			}
-
-			// Interface Bounds
-			while (c == ':') {
-				index++;
-				index = parseReference(descriptor, index, modifiers);
-				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;
-	}
-
-	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 hasRuntimeAnnotations;
-			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);
-	}
-
-	@Override
-	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;
-		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;
-	}
-
-	public Set<PackageRef> getAPIUses() {
-		if (api == null)
-			return Collections.emptySet();
-		return api;
-	}
-
-	public Clazz.TypeDef getExtends(TypeRef type) {
-		return new TypeDef(type, false);
-	}
-
-	public Clazz.TypeDef getImplements(TypeRef type) {
-		return new TypeDef(type, true);
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/CombinedResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/CombinedResource.java
deleted file mode 100644
index 1b10348..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/CombinedResource.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package aQute.bnd.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) {
-			@Override
-			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/bnd/osgi/CommandResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/CommandResource.java
deleted file mode 100644
index 19c1a21..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/CommandResource.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package aQute.bnd.osgi;
-
-import java.io.*;
-
-import aQute.libg.command.*;
-
-public class CommandResource extends WriteResource {
-	final long		lastModified;
-	final Builder	domain;
-	final String	command;
-	final File wd;
-
-	public CommandResource(String command, Builder domain, long lastModified, File wd) {
-		this.lastModified = lastModified;
-		this.domain = domain;
-		this.command = command;
-		this.wd = wd;
-	}
-
-	@Override
-	public void write(OutputStream out) throws IOException, Exception {
-		StringBuilder errors = new StringBuilder();
-		StringBuilder stdout = new StringBuilder();
-			domain.trace("executing command %s", command);
-			Command cmd = new Command("sh");
-			cmd.setCwd(wd);
-			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, "UTF-8");
-			int result = cmd.execute(command, stdout, errors);
-			osw.append(stdout);
-			osw.flush();
-			if (result != 0) {
-				throw new Exception("executing command failed" + command + "\n"+ stdout + "\n" + errors);
-			}
-	}
-
-	@Override
-	public long lastModified() {
-		return lastModified;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Constants.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Constants.java
deleted file mode 100644
index 4319538..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Constants.java
+++ /dev/null
@@ -1,323 +0,0 @@
-package aQute.bnd.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";
-	/**
-	 * @deprecated Use {@link Constants#TESTCASES}.
-	 */
-	@Deprecated
-	String							TESTSUITES									= "Test-Suites";
-	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, BUNDLE_ICON
-																				};
-
-	String							BASELINE									= "-baseline";
-	String							BASELINEREPO								= "-baselinerepo";
-	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							DSANNOTATIONS								= "-dsannotations";
-	String							DONOTCOPY									= "-donotcopy";
-	String							DEBUG										= "-debug";
-	String							EXPERIMENTS									= "-experiments";
-	String							EXPORT_CONTENTS								= "-exportcontents";
-	String							FAIL_OK										= "-failok";
-	String							INCLUDE										= "-include";
-	String							INCLUDERESOURCE								= "-includeresource";
-	String							MAKE										= "-make";
-	String							METATYPE									= "-metatype";
-	String							MANIFEST									= "-manifest";
-	String							PROFILE										= "-profile";
-	String							SAVEMANIFEST								= "-savemanifest";
-	String							NAMESECTION									= "-namesection";
-	String							NODEFAULTVERSION							= "-nodefaultversion";
-	String							NOEXTRAHEADERS								= "-noextraheaders";
-	String							NOMANIFEST									= "-nomanifest";
-	String							NOUSES										= "-nouses";
-	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							RUNREPOS									= "-runrepos";
-
-	/**
-	 * @deprecated This is for support of the legacy OBR requirement format, use
-	 *             {@link #RUNREQUIRES} for new format.
-	 */
-	@Deprecated
-	String							RUNREQUIRE									= "-runrequire";
-
-	String							RUNREQUIRES									= "-runrequires";
-
-	String							RUNEE										= "-runee";
-	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							RUNFW										= "-runfw";
-	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";
-	String							PROVIDER_POLICY								= "-provider-policy";
-	String							CONSUMER_POLICY								= "-consumer-policy";
-	String							WAB											= "-wab";
-	String							WABLIB										= "-wablib";
-	String							REQUIRE_BND									= "-require-bnd";
-
-	// Deprecated
-	String							CLASSPATH									= "-classpath";
-	String							OUTPUT										= "-output";
-
-	String							options[]									= {
-			BASELINE, 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, RUNFW, RUNTRACE,
-			TESTCONTINUOUS, SNAPSHOT, NAMESECTION, DIGESTS, DSANNOTATIONS, EXPERIMENTS, BASELINE, BASELINEREPO, PROFILE
-																				};
-
-	// 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, DSANNOTATIONS, SERVICE_COMPONENT
-																				};
-
-	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							LITERAL_ATTRIBUTE							= "literal";
-	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, LITERAL_ATTRIBUTE
-
-																				// 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_GREEDY							= "greedy:";
-	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:";
-
-	public final static String		COMPONENT_NAMESPACE							= "xmlns:";
-
-	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, COMPONENT_GREEDY, COMPONENT_NAMESPACE
-																				};
-
-	public final static Set<String>	SET_COMPONENT_DIRECTIVES					= new HashSet<String>(
-																						Arrays.asList(componentDirectives));
-
-	public final static Set<String>	SET_COMPONENT_DIRECTIVES_1_1				= //
-																				new HashSet<String>(Arrays.asList(
-																						COMPONENT_VERSION,
-																						COMPONENT_CONFIGURATION_POLICY,
-																						COMPONENT_MODIFIED,
-																						COMPONENT_ACTIVATE,
-																						COMPONENT_DEACTIVATE));
-
-	public final static Set<String>	SET_COMPONENT_DIRECTIVES_1_2				= new HashSet<String>(
-																						Arrays.asList(COMPONENT_GREEDY));
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Descriptors.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Descriptors.java
deleted file mode 100644
index 683f96d..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Descriptors.java
+++ /dev/null
@@ -1,567 +0,0 @@
-package aQute.bnd.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;
-
-		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??
-		}
-
-		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;
-		}
-
-		@Override
-		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);
-		}
-
-		@Override
-		public boolean equals(Object o) {
-			assert o instanceof PackageRef;
-			return o == this;
-		}
-
-		@Override
-		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();
-		}
-
-		@Override
-		public String toString() {
-			return fqn;
-		}
-
-		public boolean isObject() {
-			return fqn.equals("java.lang.Object");
-		}
-
-		@Override
-		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());
-		}
-
-		@Override
-		public int hashCode() {
-			return super.hashCode();
-		}
-
-	}
-
-	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();
-		}
-
-		@Override
-		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();
-		}
-
-		@Override
-		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());
-		}
-
-		@Override
-		public int hashCode() {
-			return super.hashCode();
-		}
-
-	}
-
-	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;
-
-		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;
-		}
-
-		@Override
-		public boolean equals(Object other) {
-			if (other == null || other.getClass() != getClass())
-				return false;
-
-			return Arrays.equals(prototype, ((Descriptor) other).prototype) && type == ((Descriptor) other).type;
-		}
-
-		@Override
-		public int hashCode() {
-			return prototype == null ? type.hashCode() : type.hashCode() ^ Arrays.hashCode(prototype);
-		}
-
-		@Override
-		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/bnd/osgi/Domain.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Domain.java
deleted file mode 100644
index e904aa8..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Domain.java
+++ /dev/null
@@ -1,376 +0,0 @@
-package aQute.bnd.osgi;
-
-import static aQute.bnd.osgi.Constants.*;
-
-import java.io.*;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.jar.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.version.*;
-import aQute.lib.converter.*;
-import aQute.service.reporter.*;
-
-/**
- * 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> {
-	final Properties	translation	= new Properties();
-
-	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 String translate(String key) {
-		return translate(key, null);
-	}
-	
-	
-	public String translate(String key, String deflt) {
-		String value = get(key);
-		if ( value == null)
-			return deflt;
-		
-		if ( value.indexOf('%')>=0) {
-			value = value.trim().substring(1);
-			return translation.getProperty(value,value);
-		}
-		return null;
-	}
-
-	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 getRequireBundle() {
-		return getParameters(Constants.REQUIRE_BUNDLE);
-	}
-
-
-
-	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));
-		ic.putAll(getParameters(WAB));
-		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 Map.Entry<String,Attrs> getBundleSymbolicName() {
-		Parameters p = getParameters(BUNDLE_SYMBOLICNAME);
-		if (p.isEmpty())
-			return null;
-		return p.entrySet().iterator().next();
-	}
-
-	public Map.Entry<String,Attrs> getFragmentHost() {
-		Parameters p = getParameters(FRAGMENT_HOST);
-		if (p.isEmpty())
-			return null;
-		return p.entrySet().iterator().next();
-	}
-
-	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));
-	}
-
-	/**
-	 * Find an icon with the requested size in the list of icons.
-	 * 
-	 * @param requestedSize
-	 *            the number of pixels desired
-	 * @return null or a the selected URI (which may be relative)
-	 */
-	public String getIcon(int requestedSize) throws Exception {
-		String spec = get(Constants.BUNDLE_ICON);
-		if (spec == null)
-			return null;
-
-		Parameters p = OSGiHeader.parseHeader(spec);
-		int dist = Integer.MAX_VALUE;
-		String selected = null;
-
-		for (Entry<String,Attrs> e : p.entrySet()) {
-			String url = e.getKey();
-			if (selected == null)
-				selected = url;
-			if (e.getValue() != null) {
-				String s = e.getValue().get("size");
-				if (s != null) {
-					int size = Converter.cnv(Integer.class, s);
-					if (size != 0 && Math.abs(requestedSize - size) < dist) {
-						dist = Math.abs(requestedSize - size);
-						selected = url;
-					}
-				}
-			}
-		}
-		return selected;
-	}
-
-	public void setConditionalPackage(String string) {
-		set(CONDITIONAL_PACKAGE, string);
-
-	}
-
-	public void setTranslation(Jar jar) throws Exception {
-
-		Manifest m = jar.getManifest();
-		if (m == null)
-			return;
-
-		String path = m.getMainAttributes().getValue(Constants.BUNDLE_LOCALIZATION);
-		if (path == null)
-			path = org.osgi.framework.Constants.BUNDLE_LOCALIZATION_DEFAULT_BASENAME;
-
-		path += ".properties";
-
-		Resource propsResource = jar.getResource(path);
-		if (propsResource != null) {
-			InputStream in = propsResource.openInputStream();
-			try {
-				translation.load(in);
-			}
-			finally {
-				in.close();
-			}
-		}
-	}
-
-	public Parameters getRequireCapability() {
-		return getParameters(Constants.REQUIRE_CAPABILITY);
-	}
-
-	public Parameters getProvideCapability() {
-		return getParameters(Constants.PROVIDE_CAPABILITY);
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/EmbeddedResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/EmbeddedResource.java
deleted file mode 100755
index ae3c449..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/EmbeddedResource.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package aQute.bnd.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);
-	}
-
-	@Override
-	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/bnd/osgi/FileResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/FileResource.java
deleted file mode 100755
index 66635d1..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/FileResource.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package aQute.bnd.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);
-	}
-
-	@Override
-	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/bnd/osgi/Instruction.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Instruction.java
deleted file mode 100755
index d350c8a..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Instruction.java
+++ /dev/null
@@ -1,185 +0,0 @@
-package aQute.bnd.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;
-						}
-						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);
-		return getMatcher(value).matches();
-	}
-
-	public boolean isNegated() {
-		return negated;
-	}
-
-	public String getPattern() {
-		return match;
-	}
-
-	public String getInput() {
-		return input;
-	}
-
-	@Override
-	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/bnd/osgi/Instructions.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Instructions.java
deleted file mode 100644
index b157f88..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Instructions.java
+++ /dev/null
@@ -1,222 +0,0 @@
-package aQute.bnd.osgi;
-
-import java.util.*;
-
-import aQute.bnd.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(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(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(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;
-			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(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();
-	}
-
-	@Override
-	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
-				return true; // we allow it explicitly
-			}
-		}
-		return false;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java
deleted file mode 100755
index 9ee4048..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java
+++ /dev/null
@@ -1,861 +0,0 @@
-package aQute.bnd.osgi;
-
-import static aQute.lib.io.IO.*;
-
-import java.io.*;
-import java.net.*;
-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.service.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;
-	String[]								algorithms;
-
-	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();
-		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;
-	}
-
-	@Override
-	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();
-
-		if (!doNotTouchManifest && !nomanifest && algorithms != null) {
-
-			// ok, we have a request to create digests
-			// of the resources. Since we have to output
-			// the manifest first, we have a slight problem.
-			// We can also not make multiple passes over the resource
-			// because some resources are not idempotent and/or can
-			// take significant time. So we just copy the jar
-			// to a temporary file, read it in again, calculate
-			// the checksums and save.
-
-			String[] algs = algorithms;
-			algorithms = null;
-			try {
-				File f = File.createTempFile(getName(), ".jar");
-				System.out.println("Created tmp file " + f);
-				write(f);
-				Jar tmp = new Jar(f);
-				try {
-					tmp.calcChecksums(algorithms);
-					tmp.write(out);
-				}
-				finally {
-					f.delete();
-					tmp.close();
-				}
-			}
-			finally {
-				algorithms = algs;
-			}
-			return;
-		}
-
-		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(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);
-			if (path.endsWith(Constants.EMPTY_HEADER))
-				return;
-			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();
-		if (!dir.exists() && !dir.mkdirs()) {
-			throw new IOException("Could not create directory " + dir);
-		}
-		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());
-			File fp = f.getParentFile();
-			if (!fp.exists() && !fp.mkdirs()) {
-				throw new IOException("Could not create directory " + fp);
-			}
-			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);
-	}
-
-	/**
-	 * Return a data uri from the JAR. The data must be less than 32k
-	 * 
-	 * @param jar
-	 *            The jar to load the data from
-	 * @param path
-	 *            the path in the jar
-	 * @param mime
-	 *            the mime type
-	 * @return a URI or null if conversion could not take place
-	 */
-
-	public URI getDataURI(String path, String mime, int max) throws Exception {
-		Resource r = getResource(path);
-
-		if (r.size() >= max || r.size() <= 0)
-			return null;
-
-		byte[] data = new byte[(int) r.size()];
-		DataInputStream din = new DataInputStream(r.openInputStream());
-		try {
-			din.readFully(data);
-			String encoded = Base64.encodeBase64(data);
-			return new URI("data:" + mime + ";base64," + encoded);
-		}
-		finally {
-			din.close();
-		}
-	}
-
-	public void setDigestAlgorithms(String[] algorithms) {
-		this.algorithms = algorithms;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/JarResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/JarResource.java
deleted file mode 100755
index 1734fc9..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/JarResource.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package aQute.bnd.osgi;
-
-import java.io.*;
-
-public class JarResource extends WriteResource {
-	Jar		jar;
-	long	size	= -1;
-
-	public JarResource(Jar jar) {
-		this.jar = jar;
-	}
-
-	@Override
-	public long lastModified() {
-		return jar.lastModified();
-	}
-
-	@Override
-	public void write(OutputStream out) throws Exception {
-		try {
-			jar.write(out);
-		}
-		catch (Exception e) {
-			e.printStackTrace();
-			throw e;
-		}
-	}
-
-	public Jar getJar() {
-		return jar;
-	}
-
-	@Override
-	public String toString() {
-		return ":" + jar.getName() + ":";
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
deleted file mode 100755
index 6146a00..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
+++ /dev/null
@@ -1,990 +0,0 @@
-package aQute.bnd.osgi;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.net.*;
-import java.text.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.version.*;
-import aQute.lib.collections.*;
-import aQute.lib.io.*;
-
-/**
- * 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 {
-	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);
-			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
-				});
-				Object result = m.invoke(target, new Object[] {
-					args
-				});
-				return result == null ? null : result.toString();
-			}
-			catch (NoSuchMethodException e) {
-				// Ignore
-			}
-			catch (InvocationTargetException e) {
-				if (e.getCause() instanceof IllegalArgumentException) {
-					domain.error("%s, for cmd: %s, arguments; %s", e.getCause().getMessage(), method,
-							Arrays.toString(args));
-				} else {
-					domain.warning("Exception in replace: %s", 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];
-		return "";
-	}
-
-	public final static String	_nowHelp	= "${now;pattern|'long'}, returns current time";
-
-	public Object _now(String args[]) {
-		verifyCommand(args, _nowHelp, null, 1, 2);
-		Date now = new Date();
-
-		if (args.length == 2) {
-			if ("long".equals(args[1]))
-				return now.getTime();
-
-			DateFormat df = new SimpleDateFormat(args[1]);
-			return df.format(now);
-		}
-		return new Date();
-	}
-
-	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;
-		}
-		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;
-		}
-		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;
-		}
-		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;
-		}
-		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();
-		TimeZone tz = TimeZone.getTimeZone("UTC");
-
-		if (args.length > 1) {
-			format = args[1];
-		}
-		if (args.length > 2) {
-			tz = TimeZone.getTimeZone(args[2]);
-		}
-		if (args.length > 3) {
-			now = Long.parseLong(args[3]);
-		}
-		if (args.length > 4) {
-			domain.warning("Too many arguments for tstamp: " + Arrays.toString(args));
-		}
-
-		SimpleDateFormat sdf = new SimpleDateFormat(format);
-		sdf.setTimeZone(tz);
-
-		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);
-
-		Collection<File> files = new ArrayList<File>(new SortedList<File>(dir.listFiles()));
-
-		for (int i = 2; i < args.length; i++) {
-			Instructions filters = new Instructions(args[i]);
-			files = 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);
-		}
-
-		@Override
-		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/bnd/osgi/OpCodes.java b/bundleplugin/src/main/java/aQute/bnd/osgi/OpCodes.java
deleted file mode 100755
index 4299556..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/OpCodes.java
+++ /dev/null
@@ -1,1250 +0,0 @@
-package aQute.bnd.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/bnd/osgi/Packages.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Packages.java
deleted file mode 100644
index a7f6290..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Packages.java
+++ /dev/null
@@ -1,235 +0,0 @@
-package aQute.bnd.osgi;
-
-import java.util.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.Descriptors.PackageRef;
-
-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(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(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(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;
-			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(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;
-	}
-
-	@Override
-	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;
-	}
-
-	@Override
-	@Deprecated
-	public boolean equals(Object other) {
-		return super.equals(other);
-	}
-
-	@Override
-	@Deprecated
-	public int hashCode() {
-		return super.hashCode();
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/PreprocessResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/PreprocessResource.java
deleted file mode 100644
index c1f847c..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/PreprocessResource.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package aQute.bnd.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());
-	}
-
-	@Override
-	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/bnd/osgi/Processor.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Processor.java
deleted file mode 100755
index e30ddcd..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Processor.java
+++ /dev/null
@@ -1,1697 +0,0 @@
-package aQute.bnd.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.header.*;
-import aQute.bnd.service.*;
-import aQute.lib.collections.*;
-import aQute.lib.io.*;
-import aQute.libg.generics.*;
-import aQute.service.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;
-	String							profile;
-	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 child) {
-		this(child.properties);
-		this.parent = child;
-	}
-
-	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;
-		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;
-		return p;
-	}
-
-	public SetLocation warning(String string, Object... args) {
-		Processor p = current();
-		String s = formatArrays(string, args);
-		if (!p.warnings.contains(s))
-			p.warnings.add(s);
-		p.signal();
-		return location(s);
-	}
-
-	public SetLocation error(String string, Object... args) {
-		Processor p = current();
-		try {
-			if (p.isFailOk())
-				return p.warning(string, args);
-			String s = formatArrays(string, args == null ? new Object[0] : args);
-			if (!p.errors.contains(s))
-				p.errors.add(s);
-			return location(s);
-		}
-		finally {
-			p.signal();
-		}
-	}
-
-	public void progress(float progress, String format, Object... args) {
-		format = String.format("[%2d] %s", (int) progress, format);
-		trace(format, args);
-	}
-
-	public void progress(String format, Object... args) {
-		progress(-1f, format, args);
-	}
-
-	public SetLocation exception(Throwable t, String format, Object... args) {
-		return error(format, t, args);
-	}
-
-	public SetLocation error(String string, Throwable t, Object... args) {
-		Processor p = current();
-		try {
-			if (p.exceptions)
-				t.printStackTrace();
-			if (p.isFailOk()) {
-				return p.warning(string + ": " + t, args);
-			}
-			p.errors.add("Exception: " + t.getMessage());
-			String s = formatArrays(string, args == null ? new Object[0] : args);
-			if (!p.errors.contains(s))
-				p.errors.add(s);
-			return location(s);
-		}
-		finally {
-			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 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 = loader.loadClass(key);
-					Object plugin = c.newInstance();
-					customize(plugin, entry.getValue());
-					if (plugin instanceof Closeable) {
-						addClose((Closeable) plugin);
-					}
-					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;
-	}
-
-	@Override
-	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(@SuppressWarnings("unused")
-	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);
-			}
-		}
-
-		profile = getProperty(PROFILE); // Used in property access
-		
-		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;
-
-		// Use the key as is first, if found ok
-
-		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();
-			}
-		}
-
-		// Check if we found a value, if not, try to prefix
-		// it with a profile if found and search again. profiles
-		// are a simple name that is prefixed like [profile]. This
-		// allows different variables to be used in different profiles.
-
-		if (value == null && profile != null) {
-			String pkey = "[" + profile + "]" + key;
-			if (filter != null && filter.contains(key)) {
-				value = (String) getProperties().get(pkey);
-			} else {
-				while (source != null) {
-					value = (String) source.getProperties().get(pkey);
-					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, @SuppressWarnings("unused")
-	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());
-		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, @SuppressWarnings("unused")
-	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);
-		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);
-		}
-
-		@Override
-		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(String.format("-----------------%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()
-	 */
-
-	@Override
-	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;
-	}
-
-	/**
-	 * Create a location object and add it to the locations
-	 * 
-	 * @param s
-	 * @return
-	 */
-	List<Location>	locations	= new ArrayList<Location>();
-
-	static class SetLocationImpl extends Location implements SetLocation {
-		public SetLocationImpl(String s) {
-			this.message = s;
-		}
-
-		public SetLocation file(String file) {
-			this.file = file;
-			return this;
-		}
-
-		public SetLocation header(String header) {
-			this.header = header;
-			return this;
-		}
-
-		public SetLocation context(String context) {
-			this.context = context;
-			return this;
-		}
-
-		public SetLocation method(String methodName) {
-			this.methodName = methodName;
-			return this;
-		}
-
-		public SetLocation line(int n) {
-			this.line = n;
-			return this;
-		}
-
-		public SetLocation reference(String reference) {
-			this.reference = reference;
-			return this;
-		}
-
-	}
-
-	private SetLocation location(String s) {
-		SetLocationImpl loc = new SetLocationImpl(s);
-		locations.add(loc);
-		return loc;
-	}
-
-	public Location getLocation(String msg) {
-		for (Location l : locations)
-			if ((l.message != null) && l.message.equals(msg))
-				return l;
-
-		return null;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Resource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Resource.java
deleted file mode 100755
index 8be81aa..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Resource.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package aQute.bnd.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/bnd/osgi/URLResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/URLResource.java
deleted file mode 100755
index 5d47067..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/URLResource.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package aQute.bnd.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();
-	}
-
-	@Override
-	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/bnd/osgi/Verifier.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Verifier.java
deleted file mode 100755
index 77b324d..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Verifier.java
+++ /dev/null
@@ -1,915 +0,0 @@
-package aQute.bnd.osgi;
-
-import java.io.*;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.jar.*;
-import java.util.regex.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.Descriptors.PackageRef;
-import aQute.bnd.osgi.Descriptors.TypeRef;
-import aQute.lib.base64.*;
-import aQute.lib.io.*;
-import aQute.libg.cryptography.*;
-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, @SuppressWarnings("unused") int source, int target) {
-			this.name = name;
-			this.target = target;
-		}
-
-		@Override
-		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]{1,9}(\\.[0-9]{1,9}(\\.[0-9]{1,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(@SuppressWarnings("unused") Attrs.Type type, @SuppressWarnings("unused") 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;
-	}
-
-	@Override
-	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/bnd/osgi/WriteResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/WriteResource.java
deleted file mode 100644
index ed72c41..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/WriteResource.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package aQute.bnd.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() {
-			@Override
-			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/bnd/osgi/ZipResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/ZipResource.java
deleted file mode 100755
index 1101945..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/ZipResource.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package aQute.bnd.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);
-	}
-
-	@Override
-	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/bnd/osgi/eclipse/EclipseClasspath.java b/bundleplugin/src/main/java/aQute/bnd/osgi/eclipse/EclipseClasspath.java
deleted file mode 100755
index 5415985..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/eclipse/EclipseClasspath.java
+++ /dev/null
@@ -1,238 +0,0 @@
-package aQute.bnd.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.service.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, @SuppressWarnings("unused") 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;
-			}
-			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/bnd/osgi/packageinfo b/bundleplugin/src/main/java/aQute/bnd/osgi/packageinfo
deleted file mode 100644
index a2afe57..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 2.1.0
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/CapReq.java b/bundleplugin/src/main/java/aQute/bnd/osgi/resource/CapReq.java
deleted file mode 100644
index d5fe2c6..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/CapReq.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package aQute.bnd.osgi.resource;
-
-import java.util.*;
-
-import org.osgi.resource.*;
-
-class CapReq implements Capability, Requirement {
-	
-	static enum MODE { Capability, Requirement }
-	
-	private final MODE mode;
-	private final String	namespace;
-	private final Resource	resource;
-	private final Map<String,String>	directives;
-	private final Map<String,Object>	attributes;
-
-	CapReq(MODE mode, String namespace, Resource resource, Map<String, String> directives, Map<String, Object> attributes) {
-		this.mode = mode;
-		this.namespace = namespace;
-		this.resource = resource;
-		this.directives = new HashMap<String,String>(directives);
-		this.attributes = new HashMap<String,Object>(attributes);
-	}
-
-	public String getNamespace() {
-		return namespace;
-	}
-
-	public Map<String,String> getDirectives() {
-		return Collections.unmodifiableMap(directives);
-	}
-
-	public Map<String,Object> getAttributes() {
-		return Collections.unmodifiableMap(attributes);
-	}
-
-	public Resource getResource() {
-		return resource;
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
-		result = prime * result + ((directives == null) ? 0 : directives.hashCode());
-		result = prime * result + ((mode == null) ? 0 : mode.hashCode());
-		result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
-		result = prime * result + ((resource == null) ? 0 : resource.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		CapReq other = (CapReq) obj;
-		if (attributes == null) {
-			if (other.attributes != null)
-				return false;
-		} else if (!attributes.equals(other.attributes))
-			return false;
-		if (directives == null) {
-			if (other.directives != null)
-				return false;
-		} else if (!directives.equals(other.directives))
-			return false;
-		if (mode != other.mode)
-			return false;
-		if (namespace == null) {
-			if (other.namespace != null)
-				return false;
-		} else if (!namespace.equals(other.namespace))
-			return false;
-		if (resource == null) {
-			if (other.resource != null)
-				return false;
-		} else if (!resource.equals(other.resource))
-			return false;
-		return true;
-	}
-
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		if (mode == MODE.Capability) {
-			Object value = attributes.get(namespace);
-			builder.append(namespace).append('=').append(value);
-		} else {
-			String filter = directives.get(Namespace.REQUIREMENT_FILTER_DIRECTIVE);
-			builder.append(filter);
-			if (Namespace.RESOLUTION_OPTIONAL.equals(directives.get(Namespace.REQUIREMENT_RESOLUTION_DIRECTIVE))) {
-				builder.append("%OPT");
-			}
-		}
-		return builder.toString();
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/CapReqBuilder.java b/bundleplugin/src/main/java/aQute/bnd/osgi/resource/CapReqBuilder.java
deleted file mode 100644
index 593dd39..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/CapReqBuilder.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package aQute.bnd.osgi.resource;
-
-import java.util.*;
-
-import org.osgi.framework.namespace.*;
-import org.osgi.resource.*;
-
-import aQute.bnd.osgi.resource.CapReq.MODE;
-import aQute.libg.filters.*;
-
-public class CapReqBuilder {
-
-	private final String				namespace;
-	private Resource					resource;
-	private final Map<String,Object>	attributes	= new HashMap<String,Object>();
-	private final Map<String,String>	directives	= new HashMap<String,String>();
-
-	public CapReqBuilder(String namespace) {
-		this.namespace = namespace;
-	}
-
-	public static CapReqBuilder clone(Capability capability) {
-		CapReqBuilder builder = new CapReqBuilder(capability.getNamespace());
-		builder.addAttributes(capability.getAttributes());
-		builder.addDirectives(capability.getDirectives());
-		return builder;
-	}
-
-	public static CapReqBuilder clone(Requirement requirement) {
-		CapReqBuilder builder = new CapReqBuilder(requirement.getNamespace());
-		builder.addAttributes(requirement.getAttributes());
-		builder.addDirectives(requirement.getDirectives());
-		return builder;
-	}
-
-	public String getNamespace() {
-		return namespace;
-	}
-
-	public CapReqBuilder setResource(Resource resource) {
-		this.resource = resource;
-		return this;
-	}
-
-	public CapReqBuilder addAttribute(String name, Object value) {
-		if (value != null)
-			attributes.put(name, value);
-		return this;
-	}
-
-	public CapReqBuilder addAttributes(Map< ? extends String, ? extends Object> attributes) {
-		this.attributes.putAll(attributes);
-		return this;
-	}
-
-	public CapReqBuilder addDirective(String name, String value) {
-		if (value != null)
-			directives.put(name, value);
-		return this;
-	}
-
-	public CapReqBuilder addDirectives(Map< ? extends String, ? extends String> directives) {
-		this.directives.putAll(directives);
-		return this;
-	}
-
-	public Capability buildCapability() {
-		// TODO check the thrown exception
-		if (resource == null)
-			throw new IllegalStateException("Cannot build Capability with null Resource.");
-		return new CapReq(MODE.Capability, namespace, resource, directives, attributes);
-	}
-
-	public Requirement buildRequirement() {
-		// TODO check the thrown exception
-		if (resource == null)
-			throw new IllegalStateException("Cannot build Requirement with null Resource.");
-		return new CapReq(MODE.Requirement, namespace, resource, directives, attributes);
-	}
-
-	public Requirement buildSyntheticRequirement() {
-		return new CapReq(MODE.Requirement, namespace, null, directives, attributes);
-	}
-
-	public static final CapReqBuilder createPackageRequirement(String pkgName, String range) {
-		Filter filter;
-		SimpleFilter pkgNameFilter = new SimpleFilter(PackageNamespace.PACKAGE_NAMESPACE, pkgName);
-		if (range != null)
-			filter = new AndFilter().addChild(pkgNameFilter).addChild(
-					new LiteralFilter(Filters.fromVersionRange(range)));
-		else
-			filter = pkgNameFilter;
-
-		return new CapReqBuilder(PackageNamespace.PACKAGE_NAMESPACE).addDirective(
-				Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter.toString());
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/Filters.java b/bundleplugin/src/main/java/aQute/bnd/osgi/resource/Filters.java
deleted file mode 100644
index f12e7c8..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/Filters.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package aQute.bnd.osgi.resource;
-
-import org.osgi.framework.namespace.*;
-
-import aQute.bnd.version.*;
-import aQute.libg.filters.*;
-
-public class Filters {
-	
-	public static final String DEFAULT_VERSION_ATTR = IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE;
-	
-	/**
-	 * Generate an LDAP-style version filter from a version range, e.g.
-	 * {@code [1.0,2.0)} generates {@code (&(version>=1.0)(!(version>=2.0))}
-	 * 
-	 * @param range
-	 * @return The generated filter.
-	 * @throws IllegalArgumentException
-	 *             If the supplied range is invalid.
-	 */
-	public static String fromVersionRange(String range) throws IllegalArgumentException {
-		return fromVersionRange(range, DEFAULT_VERSION_ATTR);
-	}
-
-	/**
-	 * Generate an LDAP-style version filter from a version range, using a
-	 * specific attribute name for the version; for example can be used to
-	 * generate a range using the {@code bundle-version} attribute such as
-	 * {@code (&(bundle-version>=1.0)(!(bundle-version>=2.0))}.
-	 * 
-	 * @param range
-	 * @param versionAttr
-	 * @return The generated filter
-	 * @throws IllegalArgumentException
-	 *             If the supplied range is invalid.
-	 */
-	public static String fromVersionRange(String range, String versionAttr) throws IllegalArgumentException {
-		if (range == null)
-			return null;
-		VersionRange parsedRange = new VersionRange(range);
-		
-		Filter left;
-		if (parsedRange.includeLow())
-			left = new SimpleFilter(versionAttr, Operator.GreaterThanOrEqual, parsedRange.getLow().toString());
-		else
-			left = new NotFilter(new SimpleFilter(versionAttr, Operator.LessThanOrEqual, parsedRange.getLow().toString()));
-		
-		Filter right;
-		if (!parsedRange.isRange())
-			right = null;
-		else if (parsedRange.includeHigh())
-			right = new SimpleFilter(versionAttr, Operator.LessThanOrEqual, parsedRange.getHigh().toString());
-		else
-			right = new NotFilter(new SimpleFilter(versionAttr, Operator.GreaterThanOrEqual, parsedRange.getHigh().toString()));
-		
-		Filter result;
-		if (right != null)
-			result = new AndFilter().addChild(left).addChild(right);
-		else
-			result = left;
-		
-		return result.toString();
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/ResourceBuilder.java b/bundleplugin/src/main/java/aQute/bnd/osgi/resource/ResourceBuilder.java
deleted file mode 100644
index 69e95b0..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/ResourceBuilder.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package aQute.bnd.osgi.resource;
-
-import java.util.*;
-
-import org.osgi.resource.*;
-
-public class ResourceBuilder {
-
-	private final ResourceImpl		resource		= new ResourceImpl();
-	private final List<Capability>	capabilities	= new LinkedList<Capability>();
-	private final List<Requirement>	requirements	= new LinkedList<Requirement>();
-
-	private boolean					built			= false;
-
-	public ResourceBuilder addCapability(Capability capability) {
-		CapReqBuilder builder = CapReqBuilder.clone(capability);
-		return addCapability(builder);
-	}
-	
-	public ResourceBuilder addCapability(CapReqBuilder builder) {
-		if (built)
-			throw new IllegalStateException("Resource already built");
-
-		Capability cap = builder.setResource(resource).buildCapability();
-		capabilities.add(cap);
-
-		return this;
-	}
-	
-	public ResourceBuilder addRequirement(Requirement requirement) {
-		CapReqBuilder builder = CapReqBuilder.clone(requirement);
-		return addRequirement(builder);
-	}
-	
-	public ResourceBuilder addRequirement(CapReqBuilder builder) {
-		if (built)
-			throw new IllegalStateException("Resource already built");
-
-		Requirement req = builder.setResource(resource).buildRequirement();
-		requirements.add(req);
-
-		return this;
-	}
-
-	public Resource build() {
-		if (built)
-			throw new IllegalStateException("Resource already built");
-		built = true;
-
-		resource.setCapabilities(capabilities);
-		resource.setRequirements(requirements);
-		return resource;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/ResourceImpl.java b/bundleplugin/src/main/java/aQute/bnd/osgi/resource/ResourceImpl.java
deleted file mode 100644
index f8c3a84..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/ResourceImpl.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package aQute.bnd.osgi.resource;
-
-import java.util.*;
-
-import org.osgi.framework.namespace.*;
-import org.osgi.resource.*;
-
-class ResourceImpl implements Resource {
-
-	private List<Capability>				allCapabilities;
-	private Map<String,List<Capability>>	capabilityMap;
-
-	private List<Requirement>				allRequirements;
-	private Map<String,List<Requirement>>	requirementMap;
-
-	void setCapabilities(List<Capability> capabilities) {
-		allCapabilities = capabilities;
-
-		capabilityMap = new HashMap<String,List<Capability>>();
-		for (Capability capability : capabilities) {
-			List<Capability> list = capabilityMap.get(capability.getNamespace());
-			if (list == null) {
-				list = new LinkedList<Capability>();
-				capabilityMap.put(capability.getNamespace(), list);
-			}
-			list.add(capability);
-		}
-	}
-
-	public List<Capability> getCapabilities(String namespace) {
-		return namespace == null ? allCapabilities : capabilityMap.get(namespace);
-	}
-
-	void setRequirements(List<Requirement> requirements) {
-		allRequirements = requirements;
-
-		requirementMap = new HashMap<String,List<Requirement>>();
-		for (Requirement requirement : requirements) {
-			List<Requirement> list = requirementMap.get(requirement.getNamespace());
-			if (list == null) {
-				list = new LinkedList<Requirement>();
-				requirementMap.put(requirement.getNamespace(), list);
-			}
-			list.add(requirement);
-		}
-	}
-
-	public List<Requirement> getRequirements(String namespace) {
-		return namespace == null ? allRequirements : requirementMap.get(namespace);
-	}
-
-	@Override
-	public String toString() {
-		final StringBuilder builder = new StringBuilder();
-		List<Capability> identities = getCapabilities(IdentityNamespace.IDENTITY_NAMESPACE);
-		if (identities != null && identities.size() == 1) {
-			Capability idCap = identities.get(0);
-			Object id = idCap.getAttributes().get(IdentityNamespace.IDENTITY_NAMESPACE);
-			Object version = idCap.getAttributes().get(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE);
-			
-			builder.append(id).append(" ver=").append(version);
-		} else {
-			// Generic toString
-			builder.append("ResourceImpl [caps=");
-			builder.append(allCapabilities);
-			builder.append(", reqs=");
-			builder.append(allRequirements);
-			builder.append("]");
-		}
-		return builder.toString();
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/packageinfo b/bundleplugin/src/main/java/aQute/bnd/osgi/resource/packageinfo
deleted file mode 100644
index b1793a2..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.1.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/BadLocationException.java b/bundleplugin/src/main/java/aQute/bnd/properties/BadLocationException.java
deleted file mode 100644
index 30647db..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/BadLocationException.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package aQute.bnd.properties;
-
-public class BadLocationException extends Exception {
-
-	private static final long	serialVersionUID	= 1L;
-
-	public BadLocationException() {
-		super();
-	}
-
-	public BadLocationException(String var0) {
-		super(var0);
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/CopyOnWriteTextStore.java b/bundleplugin/src/main/java/aQute/bnd/properties/CopyOnWriteTextStore.java
deleted file mode 100644
index edcba0e..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/CopyOnWriteTextStore.java
+++ /dev/null
@@ -1,147 +0,0 @@
-package aQute.bnd.properties;
-
-/**
- * Copy-on-write <code>ITextStore</code> wrapper.
- * <p>
- * This implementation uses an unmodifiable text store for the initial content.
- * Upon first modification attempt, the unmodifiable store is replaced with a
- * modifiable instance which must be supplied in the constructor.
- * </p>
- * <p>
- * This class is not intended to be subclassed.
- * </p>
- * 
- * @since 3.2
- * @noextend This class is not intended to be subclassed by clients.
- */
-public class CopyOnWriteTextStore implements ITextStore {
-
-	/**
-	 * An unmodifiable String based text store. It is not possible to modify the
-	 * content other than using {@link #set}. Trying to {@link #replace} a text
-	 * range will throw an <code>UnsupportedOperationException</code>.
-	 */
-	private static class StringTextStore implements ITextStore {
-
-		/** Represents the content of this text store. */
-		private String	fText	= "";	//$NON-NLS-1$
-
-		/**
-		 * Create an empty text store.
-		 */
-		StringTextStore() {
-			super();
-		}
-
-		/**
-		 * Create a text store with initial content.
-		 * 
-		 * @param text
-		 *            the initial content
-		 */
-		StringTextStore(String text) {
-			super();
-			set(text);
-		}
-
-		/*
-		 * @see org.eclipse.jface.text.ITextStore#get(int)
-		 */
-		public char get(int offset) {
-			return fText.charAt(offset);
-		}
-
-		/*
-		 * @see org.eclipse.jface.text.ITextStore#get(int, int)
-		 */
-		public String get(int offset, int length) {
-			return fText.substring(offset, offset + length);
-		}
-
-		/*
-		 * @see org.eclipse.jface.text.ITextStore#getLength()
-		 */
-		public int getLength() {
-			return fText.length();
-		}
-
-		/*
-		 * @see org.eclipse.jface.text.ITextStore#replace(int, int,
-		 * java.lang.String)
-		 */
-		public void replace(int offset, int length, String text) {
-			// modification not supported
-			throw new UnsupportedOperationException();
-		}
-
-		/*
-		 * @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
-		 */
-		public void set(String text) {
-			fText = text != null ? text : ""; //$NON-NLS-1$
-		}
-
-	}
-
-	/** The underlying "real" text store */
-	protected ITextStore		fTextStore	= new StringTextStore();
-
-	/** A modifiable <code>ITextStore</code> instance */
-	private final ITextStore	fModifiableTextStore;
-
-	/**
-	 * Creates an empty text store. The given text store will be used upon first
-	 * modification attempt.
-	 * 
-	 * @param modifiableTextStore
-	 *            a modifiable <code>ITextStore</code> instance, may not be
-	 *            <code>null</code>
-	 */
-	public CopyOnWriteTextStore(ITextStore modifiableTextStore) {
-		fTextStore = new StringTextStore();
-		fModifiableTextStore = modifiableTextStore;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ITextStore#get(int)
-	 */
-	public char get(int offset) {
-		return fTextStore.get(offset);
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ITextStore#get(int, int)
-	 */
-	public String get(int offset, int length) {
-		return fTextStore.get(offset, length);
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ITextStore#getLength()
-	 */
-	public int getLength() {
-		return fTextStore.getLength();
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ITextStore#replace(int, int,
-	 * java.lang.String)
-	 */
-	public void replace(int offset, int length, String text) {
-		if (fTextStore != fModifiableTextStore) {
-			String content = fTextStore.get(0, fTextStore.getLength());
-			fTextStore = fModifiableTextStore;
-			fTextStore.set(content);
-		}
-		fTextStore.replace(offset, length, text);
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
-	 */
-	public void set(String text) {
-		fTextStore = new StringTextStore(text);
-		fModifiableTextStore.set(""); //$NON-NLS-1$
-	}
-
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/Document.java b/bundleplugin/src/main/java/aQute/bnd/properties/Document.java
deleted file mode 100644
index 3818b72..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/Document.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package aQute.bnd.properties;
-
-public class Document implements IDocument {
-
-	public final static String[]	DELIMITERS	= {
-			"\r", "\n", "\r\n"
-												};
-
-	private LineTracker				lineTracker	= new LineTracker();
-	private ITextStore				textStore	= new CopyOnWriteTextStore(new GapTextStore());
-
-	public Document(String text) {
-		setText(text);
-	}
-
-	public int getNumberOfLines() {
-		return lineTracker.getNumberOfLines();
-	}
-
-	public IRegion getLineInformation(int line) throws BadLocationException {
-		return lineTracker.getLineInformation(line);
-	}
-
-	public String get(int offset, int length) throws BadLocationException {
-		return textStore.get(offset, length);
-	}
-
-	public String getLineDelimiter(int line) throws BadLocationException {
-		return lineTracker.getLineDelimiter(line);
-	}
-
-	public int getLength() {
-		return textStore.getLength();
-	}
-
-	public void replace(int offset, int length, String text) throws BadLocationException {
-		textStore.replace(offset, length, text);
-		lineTracker.set(get());
-	}
-
-	public char getChar(int pos) {
-		return textStore.get(pos);
-	}
-
-	public void setText(String text) {
-		textStore.set(text);
-		lineTracker.set(text);
-	}
-
-	public String get() {
-		return textStore.get(0, textStore.getLength());
-	}
-
-	protected static class DelimiterInfo {
-		public int		delimiterIndex;
-		public int		delimiterLength;
-		public String	delimiter;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/GapTextStore.java b/bundleplugin/src/main/java/aQute/bnd/properties/GapTextStore.java
deleted file mode 100644
index a32c219..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/GapTextStore.java
+++ /dev/null
@@ -1,419 +0,0 @@
-package aQute.bnd.properties;
-
-/**
- * Implements a gap managing text store. The gap text store relies on the
- * assumption that consecutive changes to a document are co-located. The start
- * of the gap is always moved to the location of the last change.
- * <p>
- * <strong>Performance:</strong> Typing-style changes perform in constant time
- * unless re-allocation becomes necessary. Generally, a change that does not
- * cause re-allocation will cause at most one
- * {@linkplain System#arraycopy(Object, int, Object, int, int) arraycopy}
- * operation of a length of about <var>d</var>, where <var>d</var> is the
- * distance from the previous change. Let <var>a(x)</var> be the algorithmic
- * performance of an <code>arraycopy</code> operation of the length
- * <var>x</var>, then such a change then performs in <i>O(a(x))</i>,
- * {@linkplain #get(int, int) get(int, <var>length</var>)} performs in
- * <i>O(a(length))</i>, {@link #get(int)} in <i>O(1)</i>.
- * <p>
- * How frequently the array needs re-allocation is controlled by the constructor
- * parameters.
- * </p>
- * <p>
- * This class is not intended to be subclassed.
- * </p>
- * 
- * @see CopyOnWriteTextStore for a copy-on-write text store wrapper
- * @noextend This class is not intended to be subclassed by clients.
- */
-public class GapTextStore implements ITextStore {
-	/**
-	 * The minimum gap size allocated when re-allocation occurs.
-	 * 
-	 * @since 3.3
-	 */
-	private final int	fMinGapSize;
-	/**
-	 * The maximum gap size allocated when re-allocation occurs.
-	 * 
-	 * @since 3.3
-	 */
-	private final int	fMaxGapSize;
-	/**
-	 * The multiplier to compute the array size from the content length
-	 * (1&nbsp;&lt;=&nbsp;fSizeMultiplier&nbsp;&lt;=&nbsp;2).
-	 * 
-	 * @since 3.3
-	 */
-	private final float	fSizeMultiplier;
-
-	/** The store's content */
-	private char[]		fContent	= new char[0];
-	/** Starting index of the gap */
-	private int			fGapStart	= 0;
-	/** End index of the gap */
-	private int			fGapEnd		= 0;
-	/**
-	 * The current high water mark. If a change would cause the gap to grow
-	 * larger than this, the array is re-allocated.
-	 * 
-	 * @since 3.3
-	 */
-	private int			fThreshold	= 0;
-
-	/**
-	 * Creates a new empty text store using the specified low and high
-	 * watermarks.
-	 * 
-	 * @param lowWatermark
-	 *            unused - at the lower bound, the array is only resized when
-	 *            the content does not fit
-	 * @param highWatermark
-	 *            if the gap is ever larger than this, it will automatically be
-	 *            shrunken (&gt;=&nbsp;0)
-	 * @deprecated use {@link GapTextStore#GapTextStore(int, int, float)}
-	 *             instead
-	 */
-	public GapTextStore(int lowWatermark, int highWatermark) {
-		/*
-		 * Legacy constructor. The API contract states that highWatermark is the
-		 * upper bound for the gap size. Albeit this contract was not previously
-		 * adhered to, it is now: The allocated gap size is fixed at half the
-		 * highWatermark. Since the threshold is always twice the allocated gap
-		 * size, the gap will never grow larger than highWatermark. Previously,
-		 * the gap size was initialized to highWatermark, causing re-allocation
-		 * if the content length shrunk right after allocation. The fixed gap
-		 * size is now only half of the previous value, circumventing that
-		 * problem (there was no API contract specifying the initial gap size).
-		 * The previous implementation did not allow the gap size to become
-		 * smaller than lowWatermark, which doesn't make any sense: that area of
-		 * the gap was simply never ever used.
-		 */
-		this(highWatermark / 2, highWatermark / 2, 0f);
-	}
-
-	/**
-	 * Equivalent to {@linkplain GapTextStore#GapTextStore(int, int, float) new
-	 * GapTextStore(256, 4096, 0.1f)}.
-	 * 
-	 * @since 3.3
-	 */
-	public GapTextStore() {
-		this(256, 4096, 0.1f);
-	}
-
-	/**
-	 * Creates an empty text store that uses re-allocation thresholds relative
-	 * to the content length. Re-allocation is controlled by the
-	 * <em>gap factor</em>, which is the quotient of the gap size and the array
-	 * size. Re-allocation occurs if a change causes the gap factor to go
-	 * outside <code>[0,&nbsp;maxGapFactor]</code>. When re-allocation occurs,
-	 * the array is sized such that the gap factor is
-	 * <code>0.5 * maxGapFactor</code>. The gap size computed in this manner is
-	 * bounded by the <code>minSize</code> and <code>maxSize</code> parameters.
-	 * <p>
-	 * A <code>maxGapFactor</code> of <code>0</code> creates a text store that
-	 * never has a gap at all (if <code>minSize</code> is 0); a
-	 * <code>maxGapFactor</code> of <code>1</code> creates a text store that
-	 * doubles its size with every re-allocation and that never shrinks.
-	 * </p>
-	 * <p>
-	 * The <code>minSize</code> and <code>maxSize</code> parameters are absolute
-	 * bounds to the allocated gap size. Use <code>minSize</code> to avoid
-	 * frequent re-allocation for small documents. Use <code>maxSize</code> to
-	 * avoid a huge gap being allocated for large documents.
-	 * </p>
-	 * 
-	 * @param minSize
-	 *            the minimum gap size to allocate (&gt;=&nbsp;0; use 0 for no
-	 *            minimum)
-	 * @param maxSize
-	 *            the maximum gap size to allocate (&gt;=&nbsp;minSize; use
-	 *            {@link Integer#MAX_VALUE} for no maximum)
-	 * @param maxGapFactor
-	 *            is the maximum fraction of the array that is occupied by the
-	 *            gap (
-	 *            <code>0&nbsp;&lt;=&nbsp;maxGapFactor&nbsp;&lt;=&nbsp;1</code>)
-	 * @since 3.3
-	 */
-	public GapTextStore(int minSize, int maxSize, float maxGapFactor) {
-		fMinGapSize = minSize;
-		fMaxGapSize = maxSize;
-		fSizeMultiplier = 1 / (1 - maxGapFactor / 2);
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ITextStore#get(int)
-	 */
-	public final char get(int offset) {
-		if (offset < fGapStart)
-			return fContent[offset];
-
-		return fContent[offset + gapSize()];
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ITextStore#get(int, int)
-	 */
-	public final String get(int offset, int length) {
-		if (fGapStart <= offset)
-			return new String(fContent, offset + gapSize(), length);
-
-		final int end = offset + length;
-
-		if (end <= fGapStart)
-			return new String(fContent, offset, length);
-
-		StringBuffer buf = new StringBuffer(length);
-		buf.append(fContent, offset, fGapStart - offset);
-		buf.append(fContent, fGapEnd, end - fGapStart);
-		return buf.toString();
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ITextStore#getLength()
-	 */
-	public final int getLength() {
-		return fContent.length - gapSize();
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ITextStore#set(java.lang.String)
-	 */
-	public final void set(String text) {
-		/*
-		 * Moves the gap to the end of the content. There is no sensible
-		 * prediction of where the next change will occur, but at least the next
-		 * change will not trigger re-allocation. This is especially important
-		 * when using the GapTextStore within a CopyOnWriteTextStore, where the
-		 * GTS is only initialized right before a modification.
-		 */
-		replace(0, getLength(), text);
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ITextStore#replace(int, int,
-	 * java.lang.String)
-	 */
-	public final void replace(int offset, int length, String text) {
-		if (text == null) {
-			adjustGap(offset, length, 0);
-		} else {
-			int textLength = text.length();
-			adjustGap(offset, length, textLength);
-			if (textLength != 0)
-				text.getChars(0, textLength, fContent, offset);
-		}
-	}
-
-	/**
-	 * Moves the gap to <code>offset + add</code>, moving any content after
-	 * <code>offset + remove</code> behind the gap. The gap size is kept between
-	 * 0 and {@link #fThreshold}, leading to re-allocation if needed. The
-	 * content between <code>offset</code> and <code>offset + add</code> is
-	 * undefined after this operation.
-	 * 
-	 * @param offset
-	 *            the offset at which a change happens
-	 * @param remove
-	 *            the number of character which are removed or overwritten at
-	 *            <code>offset</code>
-	 * @param add
-	 *            the number of character which are inserted or overwriting at
-	 *            <code>offset</code>
-	 */
-	private void adjustGap(int offset, int remove, int add) {
-		final int oldGapSize = gapSize();
-		final int newGapSize = oldGapSize - add + remove;
-		final boolean reuseArray = 0 <= newGapSize && newGapSize <= fThreshold;
-
-		final int newGapStart = offset + add;
-		final int newGapEnd;
-
-		if (reuseArray)
-			newGapEnd = moveGap(offset, remove, oldGapSize, newGapSize, newGapStart);
-		else
-			newGapEnd = reallocate(offset, remove, oldGapSize, newGapSize, newGapStart);
-
-		fGapStart = newGapStart;
-		fGapEnd = newGapEnd;
-	}
-
-	/**
-	 * Moves the gap to <code>newGapStart</code>.
-	 * 
-	 * @param offset
-	 *            the change offset
-	 * @param remove
-	 *            the number of removed / overwritten characters
-	 * @param oldGapSize
-	 *            the old gap size
-	 * @param newGapSize
-	 *            the gap size after the change
-	 * @param newGapStart
-	 *            the offset in the array to move the gap to
-	 * @return the new gap end
-	 * @since 3.3
-	 */
-	private int moveGap(int offset, int remove, int oldGapSize, int newGapSize, int newGapStart) {
-		/*
-		 * No re-allocation necessary. The area between the change offset and
-		 * gap can be copied in at most one operation. Don't copy parts that
-		 * will be overwritten anyway.
-		 */
-		final int newGapEnd = newGapStart + newGapSize;
-		if (offset < fGapStart) {
-			int afterRemove = offset + remove;
-			if (afterRemove < fGapStart) {
-				final int betweenSize = fGapStart - afterRemove;
-				arrayCopy(afterRemove, fContent, newGapEnd, betweenSize);
-			}
-			// otherwise, only the gap gets enlarged
-		} else {
-			final int offsetShifted = offset + oldGapSize;
-			final int betweenSize = offsetShifted - fGapEnd; // in the typing
-																// case,
-																// betweenSize
-																// is 0
-			arrayCopy(fGapEnd, fContent, fGapStart, betweenSize);
-		}
-		return newGapEnd;
-	}
-
-	/**
-	 * Reallocates a new array and copies the data from the previous one.
-	 * 
-	 * @param offset
-	 *            the change offset
-	 * @param remove
-	 *            the number of removed / overwritten characters
-	 * @param oldGapSize
-	 *            the old gap size
-	 * @param newGapSize
-	 *            the gap size after the change if no re-allocation would occur
-	 *            (can be negative)
-	 * @param newGapStart
-	 *            the offset in the array to move the gap to
-	 * @return the new gap end
-	 * @since 3.3
-	 */
-	private int reallocate(int offset, int remove, final int oldGapSize, int newGapSize, final int newGapStart) {
-		// the new content length (without any gap)
-		final int newLength = fContent.length - newGapSize;
-		// the new array size based on the gap factor
-		int newArraySize = (int) (newLength * fSizeMultiplier);
-		newGapSize = newArraySize - newLength;
-
-		// bound the gap size within min/max
-		if (newGapSize < fMinGapSize) {
-			newGapSize = fMinGapSize;
-			newArraySize = newLength + newGapSize;
-		} else if (newGapSize > fMaxGapSize) {
-			newGapSize = fMaxGapSize;
-			newArraySize = newLength + newGapSize;
-		}
-
-		// the upper threshold is always twice the gapsize
-		fThreshold = newGapSize * 2;
-		final char[] newContent = allocate(newArraySize);
-		final int newGapEnd = newGapStart + newGapSize;
-
-		/*
-		 * Re-allocation: The old content can be copied in at most 3 operations
-		 * to the newly allocated array. Either one of change offset and the gap
-		 * may come first. - unchanged area before the change offset / gap -
-		 * area between the change offset and the gap (either one may be first)
-		 * - rest area after the change offset / after the gap
-		 */
-		if (offset < fGapStart) {
-			// change comes before gap
-			arrayCopy(0, newContent, 0, offset);
-			int afterRemove = offset + remove;
-			if (afterRemove < fGapStart) {
-				// removal is completely before the gap
-				final int betweenSize = fGapStart - afterRemove;
-				arrayCopy(afterRemove, newContent, newGapEnd, betweenSize);
-				final int restSize = fContent.length - fGapEnd;
-				arrayCopy(fGapEnd, newContent, newGapEnd + betweenSize, restSize);
-			} else {
-				// removal encompasses the gap
-				afterRemove += oldGapSize;
-				final int restSize = fContent.length - afterRemove;
-				arrayCopy(afterRemove, newContent, newGapEnd, restSize);
-			}
-		} else {
-			// gap comes before change
-			arrayCopy(0, newContent, 0, fGapStart);
-			final int offsetShifted = offset + oldGapSize;
-			final int betweenSize = offsetShifted - fGapEnd;
-			arrayCopy(fGapEnd, newContent, fGapStart, betweenSize);
-			final int afterRemove = offsetShifted + remove;
-			final int restSize = fContent.length - afterRemove;
-			arrayCopy(afterRemove, newContent, newGapEnd, restSize);
-		}
-
-		fContent = newContent;
-		return newGapEnd;
-	}
-
-	/**
-	 * Allocates a new <code>char[size]</code>.
-	 * 
-	 * @param size
-	 *            the length of the new array.
-	 * @return a newly allocated char array
-	 * @since 3.3
-	 */
-	private char[] allocate(int size) {
-		return new char[size];
-	}
-
-	/*
-	 * Executes System.arraycopy if length != 0. A length < 0 cannot happen ->
-	 * don't hide coding errors by checking for negative lengths.
-	 * @since 3.3
-	 */
-	private void arrayCopy(int srcPos, char[] dest, int destPos, int length) {
-		if (length != 0)
-			System.arraycopy(fContent, srcPos, dest, destPos, length);
-	}
-
-	/**
-	 * Returns the gap size.
-	 * 
-	 * @return the gap size
-	 * @since 3.3
-	 */
-	private int gapSize() {
-		return fGapEnd - fGapStart;
-	}
-
-	/**
-	 * Returns a copy of the content of this text store. For internal use only.
-	 * 
-	 * @return a copy of the content of this text store
-	 */
-	protected String getContentAsString() {
-		return new String(fContent);
-	}
-
-	/**
-	 * Returns the start index of the gap managed by this text store. For
-	 * internal use only.
-	 * 
-	 * @return the start index of the gap managed by this text store
-	 */
-	protected int getGapStartIndex() {
-		return fGapStart;
-	}
-
-	/**
-	 * Returns the end index of the gap managed by this text store. For internal
-	 * use only.
-	 * 
-	 * @return the end index of the gap managed by this text store
-	 */
-	protected int getGapEndIndex() {
-		return fGapEnd;
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/IDocument.java b/bundleplugin/src/main/java/aQute/bnd/properties/IDocument.java
deleted file mode 100644
index 267003d..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/IDocument.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package aQute.bnd.properties;
-
-public interface IDocument {
-
-	int getNumberOfLines();
-
-	IRegion getLineInformation(int lineNum) throws BadLocationException;
-
-	String get();
-
-	String get(int offset, int length) throws BadLocationException;
-
-	String getLineDelimiter(int line) throws BadLocationException;
-
-	int getLength();
-
-	void replace(int offset, int length, String data) throws BadLocationException;
-
-	char getChar(int offset) throws BadLocationException;
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/IRegion.java b/bundleplugin/src/main/java/aQute/bnd/properties/IRegion.java
deleted file mode 100644
index 2712d71..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/IRegion.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package aQute.bnd.properties;
-
-public interface IRegion {
-
-	int getLength();
-
-	int getOffset();
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/ITextStore.java b/bundleplugin/src/main/java/aQute/bnd/properties/ITextStore.java
deleted file mode 100644
index 19791de..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/ITextStore.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package aQute.bnd.properties;
-
-/**
- * Interface for storing and managing text.
- * <p>
- * Provides access to the stored text and allows to manipulate it.
- * </p>
- * <p>
- * Clients may implement this interface or use
- * {@link org.eclipse.jface.text.GapTextStore} or
- * {@link org.eclipse.jface.text.CopyOnWriteTextStore}.
- * </p>
- */
-public interface ITextStore {
-
-	/**
-	 * Returns the character at the specified offset.
-	 * 
-	 * @param offset
-	 *            the offset in this text store
-	 * @return the character at this offset
-	 */
-	char get(int offset);
-
-	/**
-	 * Returns the text of the specified character range.
-	 * 
-	 * @param offset
-	 *            the offset of the range
-	 * @param length
-	 *            the length of the range
-	 * @return the text of the range
-	 */
-	String get(int offset, int length);
-
-	/**
-	 * Returns number of characters stored in this text store.
-	 * 
-	 * @return the number of characters stored in this text store
-	 */
-	int getLength();
-
-	/**
-	 * Replaces the specified character range with the given text.
-	 * <code>replace(getLength(), 0, "some text")</code> is a valid call and
-	 * appends text to the end of the text store.
-	 * 
-	 * @param offset
-	 *            the offset of the range to be replaced
-	 * @param length
-	 *            the number of characters to be replaced
-	 * @param text
-	 *            the substitution text
-	 */
-	void replace(int offset, int length, String text);
-
-	/**
-	 * Replace the content of the text store with the given text. Convenience
-	 * method for <code>replace(0, getLength(), text</code>.
-	 * 
-	 * @param text
-	 *            the new content of the text store
-	 */
-	void set(String text);
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/Line.java b/bundleplugin/src/main/java/aQute/bnd/properties/Line.java
deleted file mode 100644
index 6ff1c07..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/Line.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package aQute.bnd.properties;
-
-/**
- * Describes a line as a particular number of characters beginning at a
- * particular offset, consisting of a particular number of characters, and being
- * closed with a particular line delimiter.
- */
-final class Line implements IRegion {
-
-	/** The offset of the line */
-	public int			offset;
-	/** The length of the line */
-	public int			length;
-	/** The delimiter of this line */
-	public final String	delimiter;
-
-	/**
-	 * Creates a new Line.
-	 * 
-	 * @param offset
-	 *            the offset of the line
-	 * @param end
-	 *            the last including character offset of the line
-	 * @param delimiter
-	 *            the line's delimiter
-	 */
-	public Line(int offset, int end, String delimiter) {
-		this.offset = offset;
-		this.length = (end - offset) + 1;
-		this.delimiter = delimiter;
-	}
-
-	/**
-	 * Creates a new Line.
-	 * 
-	 * @param offset
-	 *            the offset of the line
-	 * @param length
-	 *            the length of the line
-	 */
-	public Line(int offset, int length) {
-		this.offset = offset;
-		this.length = length;
-		this.delimiter = null;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.IRegion#getOffset()
-	 */
-	public int getOffset() {
-		return offset;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.IRegion#getLength()
-	 */
-	public int getLength() {
-		return length;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/LineTracker.java b/bundleplugin/src/main/java/aQute/bnd/properties/LineTracker.java
deleted file mode 100644
index df65c78..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/LineTracker.java
+++ /dev/null
@@ -1,382 +0,0 @@
-package aQute.bnd.properties;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import aQute.bnd.properties.Document.DelimiterInfo;
-
-public class LineTracker {
-
-	/** The line information */
-	private final List<Line>	fLines	= new ArrayList<Line>();
-	/** The length of the tracked text */
-	private int					fTextLength;
-
-	/**
-	 * Creates a new line tracker.
-	 */
-	protected LineTracker() {}
-
-	/**
-	 * Binary search for the line at a given offset.
-	 * 
-	 * @param offset
-	 *            the offset whose line should be found
-	 * @return the line of the offset
-	 */
-	private int findLine(int offset) {
-
-		if (fLines.size() == 0)
-			return -1;
-
-		int left = 0;
-		int right = fLines.size() - 1;
-		int mid = 0;
-		Line line = null;
-
-		while (left < right) {
-
-			mid = (left + right) / 2;
-
-			line = fLines.get(mid);
-			if (offset < line.offset) {
-				if (left == mid)
-					right = left;
-				else
-					right = mid - 1;
-			} else if (offset > line.offset) {
-				if (right == mid)
-					left = right;
-				else
-					left = mid + 1;
-			} else if (offset == line.offset) {
-				left = right = mid;
-			}
-		}
-
-		line = fLines.get(left);
-		if (line.offset > offset)
-			--left;
-		return left;
-	}
-
-	/**
-	 * Returns the number of lines covered by the specified text range.
-	 * 
-	 * @param startLine
-	 *            the line where the text range starts
-	 * @param offset
-	 *            the start offset of the text range
-	 * @param length
-	 *            the length of the text range
-	 * @return the number of lines covered by this text range
-	 * @exception BadLocationException
-	 *                if range is undefined in this tracker
-	 */
-	private int getNumberOfLines(int startLine, int offset, int length) throws BadLocationException {
-
-		if (length == 0)
-			return 1;
-
-		int target = offset + length;
-
-		Line l = fLines.get(startLine);
-
-		if (l.delimiter == null)
-			return 1;
-
-		if (l.offset + l.length > target)
-			return 1;
-
-		if (l.offset + l.length == target)
-			return 2;
-
-		return getLineNumberOfOffset(target) - startLine + 1;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ILineTracker#getLineLength(int)
-	 */
-	public final int getLineLength(int line) throws BadLocationException {
-		int lines = fLines.size();
-
-		if (line < 0 || line > lines)
-			throw new BadLocationException();
-
-		if (lines == 0 || lines == line)
-			return 0;
-
-		Line l = fLines.get(line);
-		return l.length;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ILineTracker#getLineNumberOfOffset(int)
-	 */
-	public final int getLineNumberOfOffset(int position) throws BadLocationException {
-		if (position < 0 || position > fTextLength)
-			throw new BadLocationException();
-
-		if (position == fTextLength) {
-
-			int lastLine = fLines.size() - 1;
-			if (lastLine < 0)
-				return 0;
-
-			Line l = fLines.get(lastLine);
-			return (l.delimiter != null ? lastLine + 1 : lastLine);
-		}
-
-		return findLine(position);
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ILineTracker#getLineInformationOfOffset(int)
-	 */
-	public final IRegion getLineInformationOfOffset(int position) throws BadLocationException {
-		if (position > fTextLength)
-			throw new BadLocationException();
-
-		if (position == fTextLength) {
-			int size = fLines.size();
-			if (size == 0)
-				return new Region(0, 0);
-			Line l = fLines.get(size - 1);
-			return (l.delimiter != null ? new Line(fTextLength, 0) : new Line(fTextLength - l.length, l.length));
-		}
-
-		return getLineInformation(findLine(position));
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ILineTracker#getLineInformation(int)
-	 */
-	public final IRegion getLineInformation(int line) throws BadLocationException {
-		int lines = fLines.size();
-
-		if (line < 0 || line > lines)
-			throw new BadLocationException();
-
-		if (lines == 0)
-			return new Line(0, 0);
-
-		if (line == lines) {
-			Line l = fLines.get(line - 1);
-			return new Line(l.offset + l.length, 0);
-		}
-
-		Line l = fLines.get(line);
-		return (l.delimiter != null ? new Line(l.offset, l.length - l.delimiter.length()) : l);
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ILineTracker#getLineOffset(int)
-	 */
-	public final int getLineOffset(int line) throws BadLocationException {
-		int lines = fLines.size();
-
-		if (line < 0 || line > lines)
-			throw new BadLocationException();
-
-		if (lines == 0)
-			return 0;
-
-		if (line == lines) {
-			Line l = fLines.get(line - 1);
-			if (l.delimiter != null)
-				return l.offset + l.length;
-			throw new BadLocationException();
-		}
-
-		Line l = fLines.get(line);
-		return l.offset;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ILineTracker#getNumberOfLines()
-	 */
-	public final int getNumberOfLines() {
-		int lines = fLines.size();
-
-		if (lines == 0)
-			return 1;
-
-		Line l = fLines.get(lines - 1);
-		return (l.delimiter != null ? lines + 1 : lines);
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ILineTracker#getNumberOfLines(int, int)
-	 */
-	public final int getNumberOfLines(int position, int length) throws BadLocationException {
-
-		if (position < 0 || position + length > fTextLength)
-			throw new BadLocationException();
-
-		if (length == 0) // optimization
-			return 1;
-
-		return getNumberOfLines(getLineNumberOfOffset(position), position, length);
-	}
-
-	/*
-	 * @see
-	 * org.eclipse.jface.text.ILineTracker#computeNumberOfLines(java.lang.String
-	 * )
-	 */
-	public final int computeNumberOfLines(String text) {
-		int count = 0;
-		int start = 0;
-		DelimiterInfo delimiterInfo = nextDelimiterInfo(text, start);
-		while (delimiterInfo != null && delimiterInfo.delimiterIndex > -1) {
-			++count;
-			start = delimiterInfo.delimiterIndex + delimiterInfo.delimiterLength;
-			delimiterInfo = nextDelimiterInfo(text, start);
-		}
-		return count;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ILineTracker#getLineDelimiter(int)
-	 */
-	public final String getLineDelimiter(int line) throws BadLocationException {
-		int lines = fLines.size();
-
-		if (line < 0 || line > lines)
-			throw new BadLocationException();
-
-		if (lines == 0)
-			return null;
-
-		if (line == lines)
-			return null;
-
-		Line l = fLines.get(line);
-		return l.delimiter;
-	}
-
-	/**
-	 * Returns the information about the first delimiter found in the given text
-	 * starting at the given offset.
-	 * 
-	 * @param text
-	 *            the text to be searched
-	 * @param offset
-	 *            the offset in the given text
-	 * @return the information of the first found delimiter or <code>null</code>
-	 */
-	protected DelimiterInfo nextDelimiterInfo(String text, int offset) {
-
-		char ch;
-		int length = text.length();
-		for (int i = offset; i < length; i++) {
-
-			ch = text.charAt(i);
-			if (ch == '\r') {
-
-				if (i + 1 < length) {
-					if (text.charAt(i + 1) == '\n') {
-						DelimiterInfo fDelimiterInfo = new DelimiterInfo();
-						fDelimiterInfo.delimiter = Document.DELIMITERS[2];
-						fDelimiterInfo.delimiterIndex = i;
-						fDelimiterInfo.delimiterLength = 2;
-						return fDelimiterInfo;
-					}
-				}
-				DelimiterInfo fDelimiterInfo = new DelimiterInfo();
-				fDelimiterInfo.delimiter = Document.DELIMITERS[0];
-				fDelimiterInfo.delimiterIndex = i;
-				fDelimiterInfo.delimiterLength = 1;
-				return fDelimiterInfo;
-
-			} else if (ch == '\n') {
-				DelimiterInfo fDelimiterInfo = new DelimiterInfo();
-				fDelimiterInfo.delimiter = Document.DELIMITERS[1];
-				fDelimiterInfo.delimiterIndex = i;
-				fDelimiterInfo.delimiterLength = 1;
-				return fDelimiterInfo;
-			}
-		}
-
-		return null;
-	}
-
-	/**
-	 * Creates the line structure for the given text. Newly created lines are
-	 * inserted into the line structure starting at the given position. Returns
-	 * the number of newly created lines.
-	 * 
-	 * @param text
-	 *            the text for which to create a line structure
-	 * @param insertPosition
-	 *            the position at which the newly created lines are inserted
-	 *            into the tracker's line structure
-	 * @param offset
-	 *            the offset of all newly created lines
-	 * @return the number of newly created lines
-	 */
-	private int createLines(String text, int insertPosition, int offset) {
-
-		int count = 0;
-		int start = 0;
-		DelimiterInfo delimiterInfo = nextDelimiterInfo(text, 0);
-
-		while (delimiterInfo != null && delimiterInfo.delimiterIndex > -1) {
-
-			int index = delimiterInfo.delimiterIndex + (delimiterInfo.delimiterLength - 1);
-
-			if (insertPosition + count >= fLines.size())
-				fLines.add(new Line(offset + start, offset + index, delimiterInfo.delimiter));
-			else
-				fLines.add(insertPosition + count, new Line(offset + start, offset + index, delimiterInfo.delimiter));
-
-			++count;
-			start = index + 1;
-			delimiterInfo = nextDelimiterInfo(text, start);
-		}
-
-		if (start < text.length()) {
-			if (insertPosition + count < fLines.size()) {
-				// there is a line below the current
-				Line l = fLines.get(insertPosition + count);
-				int delta = text.length() - start;
-				l.offset -= delta;
-				l.length += delta;
-			} else {
-				fLines.add(new Line(offset + start, offset + text.length() - 1, null));
-				++count;
-			}
-		}
-
-		return count;
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ILineTracker#replace(int, int,
-	 * java.lang.String)
-	 */
-	public final void replace(@SuppressWarnings("unused") int position, @SuppressWarnings("unused") int length, @SuppressWarnings("unused") String text) throws BadLocationException {
-		throw new UnsupportedOperationException();
-	}
-
-	/*
-	 * @see org.eclipse.jface.text.ILineTracker#set(java.lang.String)
-	 */
-	public final void set(String text) {
-		fLines.clear();
-		if (text != null) {
-			fTextLength = text.length();
-			createLines(text, 0, 0);
-		}
-	}
-
-	/**
-	 * Returns the internal data structure, a {@link List} of {@link Line}s.
-	 * Used only by {@link TreeLineTracker#TreeLineTracker(ListLineTracker)}.
-	 * 
-	 * @return the internal list of lines.
-	 */
-	final List<Line> getLines() {
-		return fLines;
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/LineType.java b/bundleplugin/src/main/java/aQute/bnd/properties/LineType.java
deleted file mode 100644
index 58dd96b..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/LineType.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package aQute.bnd.properties;
-
-public enum LineType {
-	blank, comment, entry, eof
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/PropertiesLineReader.java b/bundleplugin/src/main/java/aQute/bnd/properties/PropertiesLineReader.java
deleted file mode 100644
index 720dde0..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/PropertiesLineReader.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package aQute.bnd.properties;
-
-import static aQute.bnd.properties.LineType.*;
-
-public class PropertiesLineReader {
-
-	private final IDocument	document;
-	private final int		lineCount;
-
-	private int				lineNum		= 0;
-
-	private IRegion			lastRegion	= null;
-	private String			lastKey		= null;
-	private String			lastValue	= null;
-
-	public PropertiesLineReader(IDocument document) {
-		this.document = document;
-		this.lineCount = document.getNumberOfLines();
-	}
-
-	public PropertiesLineReader(String data) {
-		this(new Document(data));
-	}
-
-	public LineType next() throws Exception {
-		int index = 0;
-		char[] chars = null;
-
-		StringBuilder keyData = new StringBuilder();
-		StringBuilder valueData = new StringBuilder();
-		StringBuilder currentBuffer = keyData;
-
-		boolean started = false;
-
-		mainLoop: while (true) {
-			if (chars == null)
-				chars = grabLine(false);
-			if (chars == null)
-				return eof;
-
-			if (index >= chars.length)
-				break;
-
-			char c = chars[index];
-			if (c == '\\') {
-				index++;
-				if (index == chars.length) {
-					chars = grabLine(true);
-					index = 0;
-					if (chars == null || chars.length == 0)
-						break; // The last line ended with a backslash
-				}
-				currentBuffer.append(chars[index]);
-				index++;
-				continue mainLoop;
-			}
-
-			if (c == '=' || c == ':')
-				currentBuffer = valueData;
-
-			if (!started && (c == '#' || c == '!'))
-				return comment;
-
-			if (Character.isWhitespace(c)) {
-				if (started) {
-					// whitespace ends the key
-					currentBuffer = valueData;
-				}
-			} else {
-				started = true;
-				currentBuffer.append(c);
-			}
-
-			index++;
-		}
-
-		if (!started)
-			return blank;
-
-		lastKey = keyData.toString();
-		return entry;
-	}
-
-	private char[] grabLine(boolean continued) throws BadLocationException {
-		if (lineNum >= lineCount) {
-			lastRegion = null;
-			return null;
-		}
-
-		IRegion lineInfo = document.getLineInformation(lineNum);
-		char[] chars = document.get(lineInfo.getOffset(), lineInfo.getLength()).toCharArray();
-
-		if (continued) {
-			int length = lastRegion.getLength();
-			length += document.getLineDelimiter(lineNum - 1).length();
-			length += lineInfo.getLength();
-			lastRegion = new Region(lastRegion.getOffset(), length);
-		} else {
-			lastRegion = lineInfo;
-		}
-
-		lineNum++;
-		return chars;
-	}
-
-	public IRegion region() {
-		if (lastRegion == null)
-			throw new IllegalStateException("Last region not available: either before start or after end of document.");
-		return lastRegion;
-	}
-
-	public String key() {
-		if (lastKey == null)
-			throw new IllegalStateException(
-					"Last key not available: either before state or after end of document, or last line type was not 'entry'.");
-		return lastKey;
-	}
-
-	public String value() {
-		if (lastValue == null)
-			throw new IllegalStateException(
-					"Last value not available: either before state or after end of document, or last line type was not 'entry'.");
-		return lastValue;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/Region.java b/bundleplugin/src/main/java/aQute/bnd/properties/Region.java
deleted file mode 100644
index d94a06f..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/Region.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package aQute.bnd.properties;
-
-public class Region implements IRegion {
-
-	private final int	offset;
-	private final int	length;
-
-	public Region(int offset, int length) {
-		this.offset = offset;
-		this.length = length;
-	}
-
-	public int getOffset() {
-		return offset;
-
-	}
-
-	public int getLength() {
-		return length;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/packageinfo b/bundleplugin/src/main/java/aQute/bnd/properties/packageinfo
deleted file mode 100644
index 7a6a5c0..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 2.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/Actionable.java b/bundleplugin/src/main/java/aQute/bnd/service/Actionable.java
deleted file mode 100644
index 4e805a5..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/Actionable.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package aQute.bnd.service;
-
-import java.util.*;
-
-/**
- * An interface to allow bnd to provide commands on elements. This interface can
- * provide information about the implementer but it can also provide information
- * about its elements. These elements are identified by a <i>target</i>. A
- * target is one or more objects that uniquely identify a child in the
- * container. The exact protocol for the target is left to the implementers,
- * this interface is just a conduit between the bnd world (no Eclipse etc) and
- * the GUI world, using only bnd and java interfaces.
- */
-public interface Actionable {
-	/**
-	 * Return a map with command names (potentially localized) and a Runnable.
-	 * The caller can execute the caller at will.
-	 * 
-	 * @param target
-	 *            the target object, null if commands for the encompassing
-	 *            entity is sought (e.g. the repo itself).
-	 * @return A Map with the actions or null if no actions are available.
-	 * @throws Exception
-	 */
-	Map<String,Runnable> actions(Object... target) throws Exception;
-
-	/**
-	 * Return a tooltip for the given target or the encompassing entity if null
-	 * is passed.
-	 * 
-	 * @param target
-	 *            the target, any number of parameters to identify
-	 * @return the tooltip or null
-	 * @throws Exception
-	 */
-	String tooltip(Object... target) throws Exception;
-
-	/**
-	 * Provide a title for an element.
-	 * 
-	 * @param target
-	 *            the target, any number of parameters to identify
-	 * @return the text for this element
-	 * @throws Exception
-	 */
-
-	String title(Object... target) throws Exception;
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/AnalyzerPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/AnalyzerPlugin.java
deleted file mode 100644
index 9c3e51d..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/AnalyzerPlugin.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package aQute.bnd.service;
-
-import aQute.bnd.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
deleted file mode 100644
index 31db491..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/BndListener.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package aQute.bnd.service;
-
-import java.io.*;
-import java.util.concurrent.atomic.*;
-
-import aQute.service.reporter.*;
-
-public class BndListener {
-	final AtomicInteger	inside	= new AtomicInteger();
-
-	public void changed(@SuppressWarnings("unused") File file) {}
-
-	public void begin() {
-		inside.incrementAndGet();
-	}
-
-	public void end() {
-		inside.decrementAndGet();
-	}
-
-	public boolean isInside() {
-		return inside.get() != 0;
-	}
-
-	public void signal(@SuppressWarnings("unused") Reporter reporter) {
-
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/CommandPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/CommandPlugin.java
deleted file mode 100644
index 9511637..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/CommandPlugin.java
+++ /dev/null
@@ -1,32 +0,0 @@
-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
deleted file mode 100644
index a57fa5f..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/Compiler.java
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index 1fb073b..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/DependencyContributor.java
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index fbdac78..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/Deploy.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package aQute.bnd.service;
-
-import java.io.InputStream;
-
-import aQute.bnd.build.*;
-
-/**
- * Deploy this artifact to maven.
- */
-public interface Deploy {
-	boolean deploy(Project project, String jarName, InputStream jarStream) throws Exception;
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/EclipseJUnitTester.java b/bundleplugin/src/main/java/aQute/bnd/service/EclipseJUnitTester.java
deleted file mode 100644
index f5e4174..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/EclipseJUnitTester.java
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 9805f8b..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/IndexProvider.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package aQute.bnd.service;
-
-import java.net.*;
-import java.util.*;
-
-public interface IndexProvider {
-
-	List<URI> 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
deleted file mode 100644
index f858500..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/LauncherPlugin.java
+++ /dev/null
@@ -1,9 +0,0 @@
-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
deleted file mode 100644
index 8541436..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/MakePlugin.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package aQute.bnd.service;
-
-import java.util.*;
-
-import aQute.bnd.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/Plugin.java b/bundleplugin/src/main/java/aQute/bnd/service/Plugin.java
deleted file mode 100644
index 15b7898..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/Plugin.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package aQute.bnd.service;
-
-import java.util.*;
-
-import aQute.service.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
deleted file mode 100644
index 73afa43..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/Refreshable.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package aQute.bnd.service;
-
-import java.io.*;
-
-public interface Refreshable {
-	boolean refresh() throws Exception;
-
-	File getRoot();
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/Registry.java b/bundleplugin/src/main/java/aQute/bnd/service/Registry.java
deleted file mode 100755
index a55c927..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/Registry.java
+++ /dev/null
@@ -1,12 +0,0 @@
-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
deleted file mode 100644
index 8a80660..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/RegistryPlugin.java
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index e87f3b5..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/RemoteRepositoryPlugin.java
+++ /dev/null
@@ -1,23 +0,0 @@
-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 {@link RepositoryPlugin#get(String, aQute.bnd.version.Version, Map)}
-	 * 
-	 * @param bsn the bsn of the revision
-	 * @param version the version of the revision
-	 * @param strategy strategy
-	 * @param properties any properties
-	 * @return
-	 * @throws Exception
-	 */
-	ResourceHandle getHandle(String bsn, String version, 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
deleted file mode 100644
index abd24f4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/RepositoryListenerPlugin.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package aQute.bnd.service;
-
-import java.io.*;
-
-import aQute.bnd.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
deleted file mode 100644
index f213238..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java
+++ /dev/null
@@ -1,205 +0,0 @@
-package aQute.bnd.service;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-
-import aQute.bnd.version.*;
-
-/**
- * A Repository Plugin abstract a bnd repository. This interface allows bnd to
- * find programs from their bsn and revisions from their bsn-version
- * combination. It is also possible to put revisions in a repository if the
- * repository is not read only.
- */
-public interface RepositoryPlugin {
-	/**
-	 * Options used to steer the put operation
-	 */
-	class PutOptions {
-		public static final String	BUNDLE	= "application/vnd.osgi.bundle";
-		public static final String	LIB		= "application/vnd.aQute.lib";
-
-		/**
-		 * The <b>SHA1</b> digest of the artifact to put into the repository.
-		 * When specified the digest of the <b>fetched</b> artifact will be
-		 * calculated and verified against this digest, <b>before</b> putting
-		 * the artifact into the repository. </p> An exception is thrown if the
-		 * specified digest and the calculated digest do not match.
-		 */
-		public byte[]	digest	= null;
-
-		/**
-		 * Specify the mime type of the importing stream. This can be either
-		 * {@link #BUNDLE} or {@link #LIB}. If left open, it is up to the
-		 * repository to guess the content type.
-		 */
-		public String	type;
-	}
-
-	PutOptions	DEFAULTOPTIONS	= new PutOptions();
-
-	/**
-	 * Results returned by the put operation
-	 */
-	class PutResult {
-		/**
-		 * A (potentially public) uri to the revision as it was put in the
-		 * repository.<br/>
-		 * <br/>
-		 * This can be a URI to the given artifact (when it was put into the
-		 * repository). This does not have to be a File URI!
-		 */
-		public URI		artifact	= null;
-
-		/**
-		 * The <b>SHA1</b> digest of the artifact as it was put into the
-		 * repository.<br/>
-		 * <br/>
-		 * This can be null and it can differ from the input digest if the
-		 * repository rewrote the stream for optimization reason. If the
-		 */
-		public byte[]	digest		= null;
-	}
-
-	/**
-	 * Put an artifact (from the InputStream) into the repository.<br/>
-	 * <br/>
-	 * There is NO guarantee that the artifact on the input stream has not been
-	 * modified after it's been put in the repository since that is dependent on
-	 * the implementation of the repository (see
-	 * {@link RepositoryPlugin.PutOptions#allowArtifactChange}).
-	 * 
-	 * @param stream
-	 *            The input stream with the artifact
-	 * @param options
-	 *            The put options. See {@link RepositoryPlugin.PutOptions}, can
-	 *            be {@code null}, which will then take the default options like
-	 *            new PutOptions().
-	 * @return The result of the put, never null. See
-	 *         {@link RepositoryPlugin.PutResult}
-	 * @throws Exception
-	 *             When the repository root directory doesn't exist, when the
-	 *             repository is read-only, when the specified checksum doesn't
-	 *             match the checksum of the fetched artifact (see
-	 *             {@link RepositoryPlugin.PutOptions#digest}), when the
-	 *             implementation wants to modify the artifact but isn't allowed
-	 *             (see {@link RepositoryPlugin.PutOptions#allowArtifactChange}
-	 *             ), or when another error has occurred.
-	 */
-	PutResult put(InputStream stream, PutOptions options) throws Exception;
-
-	/**
-	 * The caller can specify any number of DownloadListener objects that are
-	 * called back when a download is finished (potentially before the get
-	 * method has returned).
-	 */
-
-	interface DownloadListener {
-		/**
-		 * Called when the file is successfully downloaded from a remote
-		 * repository.
-		 * 
-		 * @param file
-		 *            The file that was downloaded
-		 * @throws Exception
-		 *             , are logged and ignored
-		 */
-		void success(File file) throws Exception;
-
-		/**
-		 * Called when the file could not be downloaded from a remote
-		 * repository.
-		 * 
-		 * @param file
-		 *            The file that was intended to be downloaded.
-		 * @throws Exception
-		 *             , are logged and ignored
-		 */
-		void failure(File file, String reason) throws Exception;
-
-		/**
-		 * Can be called back regularly before success/failure but never after.
-		 * Indicates how far the download has progressed in percents. Since
-		 * downloads can be restarted, it is possible that the percentage
-		 * decreases.
-		 * 
-		 * @param file
-		 *            The file that was intended to be downloaded
-		 * @param percentage
-		 *            Percentage of file downloaded (can go down)
-		 * @return true if the download should continue, fails if it should be
-		 *         canceled (and fail)
-		 * @throws Exception
-		 *             , are logged and ignored
-		 */
-		boolean progress(File file, int percentage) throws Exception;
-	}
-
-	/**
-	 * Return a URL to a matching version of the given bundle.
-	 * <p/>
-	 * If download listeners are specified then the returned file is not
-	 * guaranteed to exist before a download listener is notified of success or
-	 * failure. The callback can happen before the method has returned. If the
-	 * returned file is null then download listeners are not called back.
-	 * <p/>
-	 * The intention of the Download Listeners is to allow a caller to obtain
-	 * references to files that do not yet exist but are to be downloaded. If
-	 * the downloads were done synchronously in the call, then no overlap of
-	 * downloads could take place.
-	 * 
-	 * @param bsn
-	 *            Bundle-SymbolicName of the searched bundle
-	 * @param version
-	 *            Version requested
-	 * @param listeners
-	 *            Zero or more download listener that will be notified of the
-	 *            outcome.
-	 * @return A file to the revision or null if not found
-	 * @throws Exception
-	 *             when anything goes wrong, in this case no listeners will be
-	 *             called back.
-	 */
-	File get(String bsn, Version version, Map<String,String> properties, DownloadListener... listeners)
-			throws Exception;
-
-	/**
-	 * Answer if this repository can be used to store files.
-	 * 
-	 * @return true if writable
-	 */
-	boolean canWrite();
-
-	/**
-	 * Return a list of bsns that are present in the repository.
-	 * 
-	 * @param pattern
-	 *            A <ahref="https://en.wikipedia.org/wiki/Glob_%28programming%29">glob pattern</a>
-	 *            to be matched against bsns present in the repository, or {@code null}.
-	 * @return A list of bsns that match the pattern parameter or all if pattern
-	 *         is null; repositories that do not support browsing or querying
-	 *         should return an empty list.
-	 * @throws Exception
-	 */
-	List<String> list(String pattern) throws Exception;
-
-	/**
-	 * Return a list of versions.
-	 * 
-	 * @throws Exception
-	 */
-
-	SortedSet<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
deleted file mode 100644
index 0fd7ec9..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/ResolutionPhase.java
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 42abd9b..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/ResourceHandle.java
+++ /dev/null
@@ -1,16 +0,0 @@
-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
deleted file mode 100644
index 069590c..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/Scripter.java
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index 54b4e80..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/SignerPlugin.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package aQute.bnd.service;
-
-import aQute.bnd.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/Strategy.java b/bundleplugin/src/main/java/aQute/bnd/service/Strategy.java
deleted file mode 100644
index c24cd37..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/Strategy.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package aQute.bnd.service;
-
-public enum Strategy {
-	LOWEST, EXACT, HIGHEST;
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/action/Action.java b/bundleplugin/src/main/java/aQute/bnd/service/action/Action.java
deleted file mode 100644
index c74903d..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/action/Action.java
+++ /dev/null
@@ -1,7 +0,0 @@
-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
deleted file mode 100644
index 7b0c29a..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/action/NamedAction.java
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index ec0efd4..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/action/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 5d3aa12..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/diff/Delta.java
+++ /dev/null
@@ -1,18 +0,0 @@
-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
deleted file mode 100644
index bf23eee..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/diff/Diff.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package aQute.bnd.service.diff;
-
-import java.util.*;
-
-public interface Diff {
-	interface Ignore {
-		boolean contains(Diff diff);
-	}
-
-	class Data {
-
-		public Type		type;
-		public Delta	delta;
-		public String	name;
-		public Data[]	children;
-		public String	comment;
-	}
-
-	Data serialize();
-
-	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
deleted file mode 100644
index 151051b..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/diff/Differ.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package aQute.bnd.service.diff;
-
-import aQute.bnd.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
deleted file mode 100644
index 0b61f86..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/diff/Tree.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package aQute.bnd.service.diff;
-
-public interface Tree extends Comparable<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
deleted file mode 100644
index 91b186c..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/diff/Type.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package aQute.bnd.service.diff;
-
-public enum Type {
-	ACCESS, BUNDLE, API, MANIFEST, PACKAGE, CLASS, INTERFACE, ANNOTATION, ENUM, EXTENDS, IMPLEMENTS, FIELD, METHOD, ANNOTATED, PROPERTY, RESOURCE, SHA, CUSTOM, CLAUSE, HEADER, PARAMETER, CLASS_VERSION, RESOURCES, CONSTANT, RETURN, VERSION, DEPRECATED, REPO, PROGRAM, REVISION;
-
-	public boolean isInherited() {
-		// TODO Auto-generated method stub
-		return false;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/diff/packageinfo b/bundleplugin/src/main/java/aQute/bnd/service/diff/packageinfo
deleted file mode 100644
index a4f1546..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/diff/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/packageinfo b/bundleplugin/src/main/java/aQute/bnd/service/packageinfo
deleted file mode 100644
index 63eb236..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 3.0.0
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/repository/MinimalRepository.java b/bundleplugin/src/main/java/aQute/bnd/service/repository/MinimalRepository.java
deleted file mode 100644
index dab3b0c..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/repository/MinimalRepository.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package aQute.bnd.service.repository;
-
-import java.io.*;
-import java.util.*;
-import java.util.concurrent.*;
-
-import aQute.bnd.version.*;
-import aQute.service.reporter.*;
-
-public interface MinimalRepository {
-	public enum Gestalt {
-		ADD, REMOTE
-	}
-
-	Report add(File f) throws Exception;
-
-	Iterable<String> list(String globbing);
-
-	List<Version> versions(String bsn);
-
-	Future<File> get(String bsn, Version version, Map<String,String> attrs);
-	
-	boolean is(Gestalt gestalt);
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/repository/packageinfo b/bundleplugin/src/main/java/aQute/bnd/service/repository/packageinfo
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/repository/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.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
deleted file mode 100644
index fe81de8..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/url/TaggedData.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package aQute.bnd.service.url;
-
-import java.io.*;
-
-/**
- * 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
deleted file mode 100644
index 5781288..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/url/URLConnector.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package aQute.bnd.service.url;
-
-import java.io.*;
-import java.net.*;
-
-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
deleted file mode 100644
index 7ae9673..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/service/url/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.1
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/signing/JartoolSigner.java b/bundleplugin/src/main/java/aQute/bnd/signing/JartoolSigner.java
deleted file mode 100644
index f878450..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/signing/JartoolSigner.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package aQute.bnd.signing;
-
-import java.io.*;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.concurrent.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-import aQute.libg.command.*;
-import aQute.service.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(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() {
-			@Override
-			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
deleted file mode 100644
index 1841a58..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/signing/Signer.java
+++ /dev/null
@@ -1,188 +0,0 @@
-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.bnd.osgi.*;
-import aQute.lib.base64.*;
-import aQute.lib.io.*;
-
-/**
- * This class is used with the aQute.bnd.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("UTF-8"));
-				out.write("Name: ".getBytes("UTF-8"));
-				out.write(name.getBytes("UTF-8"));
-				out.write("\r\n".getBytes("UTF-8"));
-
-				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("UTF-8"));
-					}
-				}
-			}
-		}
-	}
-
-	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/bnd/version/Version.java b/bundleplugin/src/main/java/aQute/bnd/version/Version.java
deleted file mode 100755
index 5a9d194..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/version/Version.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package aQute.bnd.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{1,9})(\\.(\\d{1,9})(\\.(\\d{1,9})(\\.([-_\\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);
-	}
-
-	@Override
-	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();
-	}
-
-	@Override
-	public boolean equals(Object ot) {
-		if (!(ot instanceof Version))
-			return false;
-
-		return compareTo((Version) ot) == 0;
-	}
-
-	@Override
-	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/bnd/version/VersionRange.java b/bundleplugin/src/main/java/aQute/bnd/version/VersionRange.java
deleted file mode 100755
index 8c9a8dd..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/version/VersionRange.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package aQute.bnd.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 == ']';
-	}
-
-	@Override
-	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/bnd/version/packageinfo b/bundleplugin/src/main/java/aQute/bnd/version/packageinfo
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/version/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
diff --git a/bundleplugin/src/main/java/aQute/configurable/Config.java b/bundleplugin/src/main/java/aQute/configurable/Config.java
deleted file mode 100644
index e652ad7..0000000
--- a/bundleplugin/src/main/java/aQute/configurable/Config.java
+++ /dev/null
@@ -1,17 +0,0 @@
-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
deleted file mode 100644
index 72902e2..0000000
--- a/bundleplugin/src/main/java/aQute/configurable/Configurable.java
+++ /dev/null
@@ -1,312 +0,0 @@
-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);
-				}
-
-				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;
-				}
-				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
deleted file mode 100644
index 9ad81f6..0000000
--- a/bundleplugin/src/main/java/aQute/configurable/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100755
index 33f0a8a..0000000
--- a/bundleplugin/src/main/java/aQute/lib/base64/Base64.java
+++ /dev/null
@@ -1,155 +0,0 @@
-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);
-	}
-
-	@Override
-	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
deleted file mode 100644
index e39f616..0000000
--- a/bundleplugin/src/main/java/aQute/lib/base64/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6072ebd..0000000
--- a/bundleplugin/src/main/java/aQute/lib/codec/Codec.java
+++ /dev/null
@@ -1,10 +0,0 @@
-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
deleted file mode 100644
index c174e52..0000000
--- a/bundleplugin/src/main/java/aQute/lib/codec/HCodec.java
+++ /dev/null
@@ -1,77 +0,0 @@
-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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/lib/codec/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 1bb9f0d..0000000
--- a/bundleplugin/src/main/java/aQute/lib/collections/EnumerationIterator.java
+++ /dev/null
@@ -1,42 +0,0 @@
-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
deleted file mode 100644
index 0050a92..0000000
--- a/bundleplugin/src/main/java/aQute/lib/collections/ExtList.java
+++ /dev/null
@@ -1,56 +0,0 @@
-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 ExtList(int size) {
-		super(size);
-	}
-
-	public ExtList(Collection<T> _) {
-		super(_);
-	}
-
-	public ExtList(Iterable<T> _) {
-		for ( T t : _)
-			add(t);
-	}
-
-	public static ExtList<String> from(String s) {
-		// TODO make sure no \ before comma
-		return from(s, "\\s*,\\s*");
-	}
-	public static ExtList<String> from(String s, String delimeter) {
-		ExtList<String> result = new ExtList<String>();
-		String[] parts = s.split(delimeter);
-		for (String p : parts)
-			result.add(p);
-		return result;
-	}
-
-	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
deleted file mode 100644
index 63ddbeb..0000000
--- a/bundleplugin/src/main/java/aQute/lib/collections/IteratorList.java
+++ /dev/null
@@ -1,12 +0,0 @@
-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
deleted file mode 100644
index 0670712..0000000
--- a/bundleplugin/src/main/java/aQute/lib/collections/LineCollection.java
+++ /dev/null
@@ -1,55 +0,0 @@
-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
deleted file mode 100644
index 6daeaad..0000000
--- a/bundleplugin/src/main/java/aQute/lib/collections/Logic.java
+++ /dev/null
@@ -1,22 +0,0 @@
-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
deleted file mode 100644
index 9bf8481..0000000
--- a/bundleplugin/src/main/java/aQute/lib/collections/MultiMap.java
+++ /dev/null
@@ -1,173 +0,0 @@
-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;
-	}
-
-	public MultiMap(Map<K,List<V>> other) {
-		this();
-		for ( java.util.Map.Entry<K,List<V>> e : other.entrySet()) {
-			addAll(e.getKey(), e.getValue());
-		}
-	}
-	public MultiMap(MultiMap<K,V> other) {
-		keyClass = other.keyClass;
-		valueClass  = other.valueClass;
-		noduplicates = other.noduplicates;
-		for ( java.util.Map.Entry<K,List<V>> e : other.entrySet()) {
-			addAll(e.getKey(), e.getValue());
-		}
-	}
-
-	@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(v))
-					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
deleted file mode 100644
index 189b97f..0000000
--- a/bundleplugin/src/main/java/aQute/lib/collections/SortedList.java
+++ /dev/null
@@ -1,438 +0,0 @@
-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;
-
-		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);
-	}
-
-	@Override
-	@Deprecated
-	public boolean equals(Object other) {
-		return super.equals(other);
-	}
-
-	@Override
-	@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;
-	}
-
-	@Override
-	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);
-	}
-
-	public static <T> SortedSet<T> empty() {
-		return (SortedSet<T>) empty;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/collections/packageinfo b/bundleplugin/src/main/java/aQute/lib/collections/packageinfo
deleted file mode 100644
index 3987f9c..0000000
--- a/bundleplugin/src/main/java/aQute/lib/collections/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 9eae98a..0000000
--- a/bundleplugin/src/main/java/aQute/lib/converter/Converter.java
+++ /dev/null
@@ -1,526 +0,0 @@
-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 {
-	public interface Hook {
-		Object convert(Type dest, Object o) throws Exception;
-	}
-
-	boolean			fatal	= true;
-	Map<Type,Hook>	hooks;
-	List<Hook>		allHooks;
-
-	public <T> T convert(Class<T> type, Object o) throws Exception {
-		// Is it a compatible type?
-		if (type.isAssignableFrom(o.getClass()))
-			return (T) o;
-		return (T) convert((Type) type, o);
-	}
-
-	public <T> T convert(TypeReference<T> type, Object o) throws Exception {
-		return (T) convert(type.getType(), o);
-	}
-
-	public Object convert(Type type, Object o) throws Exception {
-		Class resultType = getRawClass(type);
-		if (o == null) {
-			if (resultType.isPrimitive() || Number.class.isAssignableFrom(resultType))
-				return convert(type, 0);
-
-			return null; // compatible with any
-		}
-
-		if (allHooks != null) {
-			for (Hook hook : allHooks) {
-				Object r = hook.convert(type, o);
-				if (r != null)
-					return r;
-			}
-		}
-
-		if (hooks != null) {
-			Hook hook = hooks.get(type);
-			if (hook != null) {
-				Object value = hook.convert(type, o);
-				if (value != null)
-					return value;
-			}
-		}
-
-		Class< ? > actualType = o.getClass();
-
-		// 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);
-		}
-
-		if (resultType.isAssignableFrom(o.getClass()))
-			return o;
-
-		if (Map.class.isAssignableFrom(actualType) && resultType.isInterface()) {
-			return proxy(resultType, (Map) 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)) {
-				try {
-					return Enum.valueOf((Class<Enum>) resultType, input);
-				} catch( Exception e) {
-					input = input.toUpperCase();
-					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
-				}
-			}
-		}
-
-		// Translate arrays with length 1 by picking the single element
-		if (actualType.isArray() && Array.getLength(o) == 1) {
-			return convert(type, Array.get(o, 0));
-		}
-
-		// Translate collections with size 1 by picking the single element
-		if (o instanceof Collection) {
-			Collection col = (Collection) o;
-			if (col.size() == 1)
-				return convert(type, col.iterator().next());
-		}
-
-		if (o instanceof Map) {
-			String key = null;
-			try {
-				Map<Object,Object> map = (Map) o;
-				Object instance = resultType.newInstance();
-				for (Map.Entry e : map.entrySet()) {
-					key = (String) e.getKey();
-					try {
-						Field f = resultType.getField(key);
-						Object value = convert(f.getGenericType(), e.getValue());
-						f.set(instance, value);
-					}
-					catch (Exception ee) {
-
-						// We cannot find the key, so try the __extra field
-						Field f = resultType.getField("__extra");
-						Map<String,Object> extra = (Map<String,Object>) f.get(instance);
-						if (extra == null) {
-							extra = new HashMap<String,Object>();
-							f.set(instance, extra);
-						}
-						extra.put(key, convert(Object.class, e.getValue()));
-
-					}
-				}
-				return instance;
-			}
-			catch (Exception e) {
-				return error("No conversion found for " + o.getClass() + " to " + type + ", error " + e + " on key "
-						+ key);
-			}
-		}
-
-		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 (key == null)
-				error("Key for map must not be null: " + input);
-			else
-				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;
-	}
-
-	public Converter hook(Type type, Hook hook) {
-		if (type != null) {
-			if (hooks == null)
-				hooks = new HashMap<Type,Converter.Hook>();
-			this.hooks.put(type, hook);
-		} else {
-			if (allHooks == null)
-				allHooks = new ArrayList<Converter.Hook>();
-			allHooks.add(hook);
-		}
-
-		return this;
-	}
-
-	/**
-	 * Convert a map to an interface.
-	 * 
-	 * @param interfc
-	 * @param properties
-	 * @return
-	 */
-	public <T> T proxy(Class<T> interfc, final Map< ? , ? > properties) {
-		return (T) Proxy.newProxyInstance(interfc.getClassLoader(), new Class[] {
-			interfc
-		}, new InvocationHandler() {
-
-			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-				Object o = properties.get(method.getName());
-				if (o == null)
-					o = properties.get(mangleMethodName(method.getName()));
-
-				return convert(method.getGenericReturnType(), o);
-			}
-
-		});
-	}
-
-	public static String mangleMethodName(String id) {
-		StringBuilder sb = new StringBuilder(id);
-		for (int i = 0; i < sb.length(); i++) {
-			char c = sb.charAt(i);
-			boolean twice = i < sb.length() - 1 && sb.charAt(i + 1) == c;
-			if (c == '$' || c == '_') {
-				if (twice)
-					sb.deleteCharAt(i + 1);
-				else if (c == '$')
-					sb.deleteCharAt(i--); // Remove dollars
-				else
-					sb.setCharAt(i, '.'); // Make _ into .
-			}
-		}
-		return sb.toString();
-	}
-
-	public static <T> T cnv(TypeReference<T> tr, Object source) throws Exception {
-		return new Converter().convert(tr, source);
-	}
-
-	public static <T> T cnv(Class<T> tr, Object source) throws Exception {
-		return new Converter().convert(tr, source);
-	}
-
-	public static Object cnv(Type tr, Object source) throws Exception {
-		return new Converter().convert(tr, source);
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/converter/TypeReference.java b/bundleplugin/src/main/java/aQute/lib/converter/TypeReference.java
deleted file mode 100644
index 3271227..0000000
--- a/bundleplugin/src/main/java/aQute/lib/converter/TypeReference.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package aQute.lib.converter;
-
-import java.lang.reflect.*;
-
-public class TypeReference<T> implements Type {
-
-	protected TypeReference() {
-		// Make sure it cannot be directly instantiated
-	}
-	public Type getType() {
-		return ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/converter/packageinfo b/bundleplugin/src/main/java/aQute/lib/converter/packageinfo
deleted file mode 100644
index 3390555..0000000
--- a/bundleplugin/src/main/java/aQute/lib/converter/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 0b25300..0000000
--- a/bundleplugin/src/main/java/aQute/lib/data/AllowNull.java
+++ /dev/null
@@ -1,11 +0,0 @@
-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
deleted file mode 100644
index 9d318b8..0000000
--- a/bundleplugin/src/main/java/aQute/lib/data/Data.java
+++ /dev/null
@@ -1,80 +0,0 @@
-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
deleted file mode 100644
index eb1534e..0000000
--- a/bundleplugin/src/main/java/aQute/lib/data/Numeric.java
+++ /dev/null
@@ -1,15 +0,0 @@
-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
deleted file mode 100644
index 48324e8..0000000
--- a/bundleplugin/src/main/java/aQute/lib/data/Validator.java
+++ /dev/null
@@ -1,13 +0,0 @@
-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
deleted file mode 100644
index 9ad81f6..0000000
--- a/bundleplugin/src/main/java/aQute/lib/data/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0.0
diff --git a/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java b/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java
deleted file mode 100644
index 57b6b37..0000000
--- a/bundleplugin/src/main/java/aQute/lib/deployer/FileRepo.java
+++ /dev/null
@@ -1,816 +0,0 @@
-package aQute.lib.deployer;
-
-import java.io.*;
-import java.security.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Verifier;
-import aQute.bnd.service.*;
-import aQute.bnd.version.*;
-import aQute.lib.collections.*;
-import aQute.lib.hex.*;
-import aQute.lib.io.*;
-import aQute.libg.command.*;
-import aQute.libg.cryptography.*;
-import aQute.libg.reporter.*;
-import aQute.service.reporter.*;
-
-/**
- * A FileRepo is the primary and example implementation of a repository based on
- * a file system. It maintains its files in a bsn/bsn-version.jar style from a
- * given location. It implements all the functions of the
- * {@link RepositoryPlugin}, {@link Refreshable}, {@link Actionable}, and
- * {@link Closeable}. The FileRepo can be extended or used as is. When used as
- * is, it is possible to add shell commands to the life cycle of the FileRepo.
- * This life cycle is as follows:
- * <ul>
- * <li>{@link #CMD_INIT} - Is only executed when the location did not exist</li>
- * <li>{@link #CMD_OPEN} - Called (after init if necessary) to open it once</li>
- * <li>{@link #CMD_REFRESH} - Called when refreshed.</li>
- * <li>{@link #CMD_BEFORE_PUT} - Before the file system is changed</li>
- * <li>{@link #CMD_AFTER_PUT} - After the file system has changed, and the put
- * <li>{@link #CMD_BEFORE_GET} - Before the file is gotten</li>
- * <li>{@link #CMD_AFTER_ACTION} - Before the file is gotten</li>
- * <li>{@link #CMD_CLOSE} - When the repo is closed and no more actions will
- * take place</li> was a success</li>
- * <li>{@link #CMD_ABORT_PUT} - When the put is aborted.</li>
- * <li>{@link #CMD_CLOSE} - To close the repository.</li>
- * </ul>
- * Additionally, it is possible to set the {@link #CMD_SHELL} and the
- * {@link #CMD_PATH}. Notice that you can use the ${global} macro to read global
- * (that is, machine local) settings from the ~/.bnd/settings.json file (can be
- * managed with bnd).
- */
-public class FileRepo implements Plugin, RepositoryPlugin, Refreshable, RegistryPlugin, Actionable, Closeable {
-
-	/**
-	 * If set, will trace to stdout. Works only if no reporter is set.
-	 */
-	public final static String	TRACE				= "trace";
-
-	/**
-	 * Property name for the location of the repo, must be a valid path name
-	 * using forward slashes (see {@link IO#getFile(String)}.
-	 */
-	public final static String	LOCATION			= "location";
-
-	/**
-	 * Property name for the readonly state of the repository. If no, will
-	 * read/write, otherwise it must be a boolean value read by
-	 * {@link Boolean#parseBoolean(String)}. Read only repositories will not
-	 * accept writes.
-	 */
-	public final static String	READONLY			= "readonly";
-
-	/**
-	 * Set the name of this repository (optional)
-	 */
-	public final static String	NAME				= "name";
-
-	/**
-	 * Path property for commands. A comma separated path for directories to be
-	 * searched for command. May contain $ @} which will be replaced by the
-	 * system path. If this property is not set, the system path is assumed.
-	 */
-	public static final String	CMD_PATH			= "cmd.path";
-
-	/**
-	 * The name ( and path) of the shell to execute the commands. By default
-	 * this is sh and searched in the path.
-	 */
-	public static final String	CMD_SHELL			= "cmd.shell";
-
-	/**
-	 * Property for commands. The command only runs when the location does not
-	 * exist. </p>
-	 * 
-	 * @param rootFile
-	 *            the root of the repo (directory exists)
-	 */
-	public static final String	CMD_INIT			= "cmd.init";
-
-	/**
-	 * Property for commands. Command is run before the repo is first used. </p>
-	 * 
-	 * @param $0
-	 *            rootFile the root of the repo (directory exists)
-	 */
-	public static final String	CMD_OPEN			= "cmd.open";
-
-	/**
-	 * Property for commands. The command runs after a put operation. </p>
-	 * 
-	 * @param $0
-	 *            the root of the repo (directory exists)
-	 * @param $1
-	 *            the file that was put
-	 * @param $2
-	 *            the hex checksum of the file
-	 */
-	public static final String	CMD_AFTER_PUT		= "cmd.after.put";
-
-	/**
-	 * Property for commands. The command runs when the repository is refreshed.
-	 * </p>
-	 * 
-	 * @param $
-	 *            {0} the root of the repo (directory exists)
-	 */
-	public static final String	CMD_REFRESH			= "cmd.refresh";
-
-	/**
-	 * Property for commands. The command runs after the file is put. </p>
-	 * 
-	 * @param $0
-	 *            the root of the repo (directory exists)
-	 * @param $1
-	 *            the path to a temporary file
-	 */
-	public static final String	CMD_BEFORE_PUT		= "cmd.before.put";
-
-	/**
-	 * Property for commands. The command runs when a put is aborted after file
-	 * changes were made. </p>
-	 * 
-	 * @param $0
-	 *            the root of the repo (directory exists)
-	 * @param $1
-	 *            the temporary file that was used (optional)
-	 */
-	public static final String	CMD_ABORT_PUT		= "cmd.abort.put";
-
-	/**
-	 * Property for commands. The command runs after the file is put. </p>
-	 * 
-	 * @param $0
-	 *            the root of the repo (directory exists)
-	 */
-	public static final String	CMD_CLOSE			= "cmd.close";
-
-	/**
-	 * Property for commands. Will be run after an action has been executed.
-	 * </p>
-	 * 
-	 * @param $0
-	 *            the root of the repo (directory exists)
-	 * @param $1
-	 *            the path to the file that the action was executed on
-	 * @param $2
-	 *            the action executed
-	 */
-	public static final String	CMD_AFTER_ACTION	= "cmd.after.action";
-
-	/**
-	 * Called before a before get.
-	 * 
-	 * @param $0
-	 *            the root of the repo (directory exists)
-	 * @param $1
-	 *            the bsn
-	 * @param $2
-	 *            the version
-	 */
-	public static final String	CMD_BEFORE_GET		= "cmd.before.get";
-
-	/**
-	 * Options used when the options are null
-	 */
-	static final PutOptions		DEFAULTOPTIONS		= new PutOptions();
-
-	public static final int	MAX_MAJOR	= 999999999;
-
-	
-	String						shell;
-	String						path;
-	String						init;
-	String						open;
-	String						refresh;
-	String						beforePut;
-	String						afterPut;
-	String						abortPut;
-	String						beforeGet;
-	String						close;
-	String						action;
-
-	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;
-	boolean						inited;
-	boolean						trace;
-
-	public FileRepo() {}
-
-	public FileRepo(String name, File location, boolean canWrite) {
-		this.name = name;
-		this.root = location;
-		this.canWrite = canWrite;
-	}
-
-	/**
-	 * Initialize the repository Subclasses should first call this method and
-	 * then if it returns true, do their own initialization
-	 * 
-	 * @return true if initialized, false if already had been initialized.
-	 * @throws Exception
-	 */
-	protected boolean init() throws Exception {
-		if (inited)
-			return false;
-
-		inited = true;
-
-		if (reporter == null) {
-			ReporterAdapter reporter = trace ? new ReporterAdapter(System.out) : new ReporterAdapter();
-			reporter.setTrace(trace);
-			reporter.setExceptions(trace);
-			this.reporter = reporter;
-		}
-
-		if (!root.isDirectory()) {
-			root.mkdirs();
-			if (!root.isDirectory())
-				throw new IllegalArgumentException("Location cannot be turned into a directory " + root);
-
-			exec(init, root.getAbsolutePath());
-		}
-		open();
-		return true;
-	}
-
-	/**
-	 * @see aQute.bnd.service.Plugin#setProperties(java.util.Map)
-	 */
-	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 = IO.getFile(IO.home, location);
-		String readonly = map.get(READONLY);
-		if (readonly != null && Boolean.valueOf(readonly).booleanValue())
-			canWrite = false;
-
-		name = map.get(NAME);
-		path = map.get(CMD_PATH);
-		shell = map.get(CMD_SHELL);
-		init = map.get(CMD_INIT);
-		open = map.get(CMD_OPEN);
-		refresh = map.get(CMD_REFRESH);
-		beforePut = map.get(CMD_BEFORE_PUT);
-		abortPut = map.get(CMD_ABORT_PUT);
-		afterPut = map.get(CMD_AFTER_PUT);
-		beforeGet = map.get(CMD_BEFORE_GET);
-		close = map.get(CMD_CLOSE);
-		action = map.get(CMD_AFTER_ACTION);
-
-		trace = map.get(TRACE) != null && Boolean.parseBoolean(map.get(TRACE));
-	}
-
-	/**
-	 * Answer if this repository can write.
-	 */
-	public boolean canWrite() {
-		return canWrite;
-	}
-
-	/**
-	 * Local helper method that tries to insert a file in the repository. This
-	 * method can be overridden but MUST not change the content of the tmpFile.
-	 * This method should also create a latest version of the artifact for
-	 * reference by tools like ant etc. </p> It is allowed to rename the file,
-	 * the tmp file must be beneath the root directory to prevent rename
-	 * problems.
-	 * 
-	 * @param tmpFile
-	 *            source file
-	 * @param digest
-	 * @return a File that contains the content of the tmpFile
-	 * @throws Exception
-	 */
-	protected File putArtifact(File tmpFile, byte[] digest) throws Exception {
-		assert (tmpFile != null);
-
-		Jar tmpJar = new Jar(tmpFile);
-		try {
-			dirty = true;
-
-			String bsn = tmpJar.getBsn();
-			if (bsn == null)
-				throw new IllegalArgumentException("No bsn set in jar: " + tmpFile);
-
-			String versionString = tmpJar.getVersion();
-			if (versionString == null)
-				versionString = "0";
-			else if (!Verifier.isVersion(versionString))
-				throw new IllegalArgumentException("Incorrect version in : " + tmpFile + " " + versionString);
-
-			Version version = new Version(versionString);
-
-			reporter.trace("bsn=%s version=%s", bsn, version);
-
-			File dir = new File(root, bsn);
-			dir.mkdirs();
-			if (!dir.isDirectory())
-				throw new IOException("Could not create directory " + dir);
-
-			String fName = bsn + "-" + version.getWithoutQualifier() + ".jar";
-			File file = new File(dir, fName);
-
-			reporter.trace("updating %s ", file.getAbsolutePath());
-
-			// An open jar on file will fail rename on windows
-			tmpJar.close();
-
-			IO.rename(tmpFile, file);
-
-			fireBundleAdded(file);
-			afterPut(file, bsn, version, Hex.toHexString(digest));
-
-			// TODO like to beforeGet rid of the latest option. This is only
-			// used to have a constant name for the outside users (like ant)
-			// we should be able to handle this differently?
-			File latest = new File(dir, bsn + "-latest.jar");
-			IO.copy(file, latest);
-
-			reporter.trace("updated %s", file.getAbsolutePath());
-
-			return file;
-		}
-		finally {
-			tmpJar.close();
-		}
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see aQute.bnd.service.RepositoryPlugin#put(java.io.InputStream,
-	 * aQute.bnd.service.RepositoryPlugin.PutOptions)
-	 */
-	public PutResult put(InputStream stream, PutOptions options) throws Exception {
-		/* determine if the put is allowed */
-		if (!canWrite) {
-			throw new IOException("Repository is read-only");
-		}
-
-		assert stream != null;
-
-		if (options == null)
-			options = DEFAULTOPTIONS;
-
-		init();
-
-		/*
-		 * copy the artifact from the (new/digest) stream into a temporary file
-		 * in the root directory of the repository
-		 */
-		File tmpFile = IO.createTempFile(root, "put", ".jar");
-		try {
-			DigestInputStream dis = new DigestInputStream(stream, MessageDigest.getInstance("SHA-1"));
-			try {
-				IO.copy(dis, tmpFile);
-
-				byte[] digest = dis.getMessageDigest().digest();
-
-				if (options.digest != null && !Arrays.equals(digest, options.digest))
-					throw new IOException("Retrieved artifact digest doesn't match specified digest");
-
-				/*
-				 * put the artifact into the repository (from the temporary
-				 * file)
-				 */
-				beforePut(tmpFile);
-				File file = putArtifact(tmpFile, digest);
-				file.setReadOnly();
-
-				PutResult result = new PutResult();
-				result.digest = digest;
-				result.artifact = file.toURI();
-
-				return result;
-			}
-			finally {
-				dis.close();
-			}
-		}
-		catch (Exception e) {
-			abortPut(tmpFile);
-			throw e;
-		}
-		finally {
-			IO.delete(tmpFile);
-		}
-	}
-
-	public void setLocation(String string) {
-		root = IO.getFile(string);
-	}
-
-	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 SortedSet<Version> versions(String bsn) throws Exception {
-		init();
-		boolean haslatest = false;
-		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"))
-						haslatest = true;
-					else
-						list.add(new Version(version));
-				}
-			}
-			if ( list.isEmpty() && haslatest)
-				list.add( new Version(MAX_MAJOR,0,0));
-			return new SortedList<Version>(list);
-		}
-		return SortedList.empty();
-	}
-
-	@Override
-	public String toString() {
-		return String.format("%-40s r/w=%s", root.getAbsolutePath(), canWrite());
-	}
-
-	public File getRoot() {
-		return root;
-	}
-
-	public boolean refresh() throws Exception {
-		init();
-		exec(refresh, root);
-		if (dirty) {
-			dirty = false;
-			return true;
-		}
-		return false;
-	}
-
-	public String getName() {
-		if (name == null) {
-			return toString();
-		}
-		return name;
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see aQute.bnd.service.RepositoryPlugin#get(java.lang.String,
-	 * aQute.bnd.version.Version, java.util.Map)
-	 */
-	public File get(String bsn, Version version, Map<String,String> properties, DownloadListener... listeners)
-			throws Exception {
-		init();
-		beforeGet(bsn, version);
-		File file = getLocal(bsn, version, properties);
-		if (file.exists()) {
-			for (DownloadListener l : listeners) {
-				try {
-					l.success(file);
-				}
-				catch (Exception e) {
-					reporter.exception(e, "Download listener for %s", file);
-				}
-			}
-			return file;
-		}
-		return null;
-	}
-
-	public void setRegistry(Registry registry) {
-		this.registry = registry;
-	}
-
-	public String getLocation() {
-		return root.toString();
-	}
-
-	public Map<String,Runnable> actions(Object... target) throws Exception {
-		if (target == null || target.length == 0)
-			return null; // no default actions
-
-		try {
-			String bsn = (String) target[0];
-			Version version = (Version) target[1];
-
-			final File f = get(bsn, version, null);
-			if (f == null)
-				return null;
-
-			Map<String,Runnable> actions = new HashMap<String,Runnable>();
-			actions.put("Delete " + bsn + "-" + status(bsn, version), new Runnable() {
-				public void run() {
-					IO.delete(f);
-					if (f.getParentFile().list().length == 0)
-						IO.delete(f.getParentFile());
-					afterAction(f, "delete");
-				};
-			});
-			return actions;
-		}
-		catch (Exception e) {
-			return null;
-		}
-	}
-
-	protected void afterAction(File f, String key) {
-		exec(action, root, f, key);
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see aQute.bnd.service.Actionable#tooltip(java.lang.Object[])
-	 */
-	@SuppressWarnings("unchecked")
-	public String tooltip(Object... target) throws Exception {
-		if (target == null || target.length == 0)
-			return String.format("%s\n%s", getName(), root);
-
-		try {
-			String bsn = (String) target[0];
-			Version version = (Version) target[1];
-			Map<String,String> map = null;
-			if (target.length > 2)
-				map = (Map<String,String>) target[2];
-
-			File f = getLocal(bsn, version, map);
-			String s = String.format("Path: %s\nSize: %s\nSHA1: %s", f.getAbsolutePath(), readable(f.length(), 0), SHA1
-					.digest(f).asHex());
-			if (f.getName().endsWith(".lib") && f.isFile()) {
-				s += "\n" + IO.collect(f);
-			}
-			return s;
-
-		}
-		catch (Exception e) {
-			return null;
-		}
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * @see aQute.bnd.service.Actionable#title(java.lang.Object[])
-	 */
-	public String title(Object... target) throws Exception {
-		if (target == null || target.length == 0)
-			return getName();
-
-		if (target.length == 1 && target[0] instanceof String)
-			return (String) target[0];
-
-		if (target.length == 2 && target[0] instanceof String && target[1] instanceof Version) {
-			return status((String) target[0], (Version) target[1]);
-		}
-
-		return null;
-	}
-
-	protected File getLocal(String bsn, Version version, Map<String,String> properties) {
-		File dir = new File(root, bsn);
-
-		if ( version.getMajor() == MAX_MAJOR && version.getMinor()== 0 && version.getMicro() == 0 && version.getQualifier() == null) {
-			File fjar = new File(dir, bsn + "-latest.jar");
-			if (fjar.isFile())
-				return fjar.getAbsoluteFile();
-		}
-		
-		File fjar = new File(dir, bsn + "-" + version.getWithoutQualifier() + ".jar");
-		if (fjar.isFile())
-			return fjar.getAbsoluteFile();
-
-		File flib = new File(dir, bsn + "-" + version.getWithoutQualifier() + ".lib");
-		if (flib.isFile())
-			return flib.getAbsoluteFile();
-
-		return fjar.getAbsoluteFile();
-	}
-
-	protected String status(String bsn, Version version) {
-		File file = getLocal(bsn, version, null);
-		StringBuilder sb = new StringBuilder(version.toString());
-		String del = " [";
-
-		if (file.getName().endsWith(".lib")) {
-			sb.append(del).append("L");
-			del = "";
-		}
-		if (!file.getName().endsWith(".jar")) {
-			sb.append(del).append("?");
-			del = "";
-		}
-		if (!file.isFile()) {
-			sb.append(del).append("X");
-			del = "";
-		}
-		if (file.length() == 0) {
-			sb.append(del).append("0");
-			del = "";
-		}
-		if (del.equals(""))
-			sb.append("]");
-		return sb.toString();
-	}
-
-	private static String[]	names	= {
-			"bytes", "Kb", "Mb", "Gb"
-									};
-
-	private Object readable(long length, int n) {
-		if (length < 0)
-			return "<invalid>";
-
-		if (length < 1024 || n >= names.length)
-			return length + names[n];
-
-		return readable(length / 1024, n + 1);
-	}
-
-	public void close() throws IOException {
-		if (inited)
-			exec(close, root.getAbsolutePath());
-	}
-
-	protected void open() {
-		exec(open, root.getAbsolutePath());
-	}
-
-	protected void beforePut(File tmp) {
-		exec(beforePut, root.getAbsolutePath(), tmp.getAbsolutePath());
-	}
-
-	protected void afterPut(File file, String bsn, Version version, String sha) {
-		exec(afterPut, root.getAbsolutePath(), file.getAbsolutePath(), sha);
-	}
-
-	protected void abortPut(File tmpFile) {
-		exec(abortPut, root.getAbsolutePath(), tmpFile.getAbsolutePath());
-	}
-
-	protected void beforeGet(String bsn, Version version) {
-		exec(beforeGet, root.getAbsolutePath(), bsn, version);
-	}
-
-	protected void fireBundleAdded(File file) {
-		if (registry == null)
-			return;
-		List<RepositoryListenerPlugin> listeners = registry.getPlugins(RepositoryListenerPlugin.class);
-		Jar jar = null;
-		for (RepositoryListenerPlugin listener : listeners) {
-			try {
-				if (jar == null)
-					jar = new Jar(file);
-				listener.bundleAdded(this, jar, file);
-			}
-			catch (Exception e) {
-				if (reporter != null)
-					reporter.warning("Repository listener threw an unexpected exception: %s", e);
-			}
-			finally {
-				if (jar != null)
-					jar.close();
-			}
-		}
-	}
-
-	/**
-	 * Execute a command. Used in different stages so that the repository can be
-	 * synced with external tools.
-	 * 
-	 * @param line
-	 * @param target
-	 */
-	void exec(String line, Object... args) {
-		if (line == null) {
-			return;
-		}
-
-		try {
-			if (args != null) {
-				for (int i = 0; i < args.length; i++) {
-					if (i == 0) {
-						// replaceAll backslash magic ensures windows paths
-						// remain intact
-						line = line.replaceAll("\\$\\{@\\}", args[0].toString().replaceAll("\\\\", "\\\\\\\\"));
-					}
-					// replaceAll backslash magic ensures windows paths remain
-					// intact
-					line = line.replaceAll("\\$" + i, args[i].toString().replaceAll("\\\\", "\\\\\\\\"));
-				}
-			}
-			// purge remaining placeholders
-			line = line.replaceAll("\\s*\\$[0-9]\\s*", "");
-
-			int result = 0;
-			StringBuilder stdout = new StringBuilder();
-			StringBuilder stderr = new StringBuilder();
-			if (System.getProperty("os.name").toLowerCase().indexOf("win") >= 0) {
-
-				// FIXME ignoring possible shell setting stdin approach used
-				// below does not work in windows
-				Command cmd = new Command("cmd.exe /C " + line);
-				cmd.setCwd(getRoot());
-				result = cmd.execute(stdout, stderr);
-
-			} else {
-				if (shell == null) {
-					shell = "sh";
-				}
-				Command cmd = new Command(shell);
-				cmd.setCwd(getRoot());
-
-				if (path != null) {
-					cmd.inherit();
-					String oldpath = cmd.var("PATH");
-					path = path.replaceAll("\\s*,\\s*", File.pathSeparator);
-					path = path.replaceAll("\\$\\{@\\}", oldpath);
-					cmd.var("PATH", path);
-				}
-				result = cmd.execute(line, stdout, stderr);
-			}
-			if (result != 0) {
-				reporter.error("Command %s failed with %s %s %s", line, result, stdout, stderr);
-			}
-		}
-		catch (Exception e) {
-			e.printStackTrace();
-			reporter.exception(e, e.getMessage());
-		}
-	}
-
-	/*
-	 * 8 Set the root directory directly
-	 */
-	public void setDir(File repoDir) {
-		this.root = repoDir;
-	}
-
-	/**
-	 * Delete an entry from the repository and cleanup the directory
-	 * 
-	 * @param bsn
-	 * @param version
-	 * @throws Exception
-	 */
-	public void delete(String bsn, Version version) throws Exception {
-		assert bsn != null;
-
-		SortedSet<Version> versions;
-		if (version == null)
-			versions = versions(bsn);
-		else
-			versions = new SortedList<Version>(version);
-
-		for (Version v : versions) {
-			File f = getLocal(bsn, version, null);
-			if (!f.isFile())
-				reporter.error("No artifact found for %s:%s", bsn, version);
-			else
-				IO.delete(f);
-		}
-		if ( versions(bsn).isEmpty())
-			IO.delete( new File(root,bsn));
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/filter/Filter.java b/bundleplugin/src/main/java/aQute/lib/filter/Filter.java
deleted file mode 100755
index 2c4dd09..0000000
--- a/bundleplugin/src/main/java/aQute/lib/filter/Filter.java
+++ /dev/null
@@ -1,349 +0,0 @@
-/**
- * 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;
-
-	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;
-		}
-
-		@Override
-		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;
-	}
-
-	@Override
-	public String toString() {
-		return filter;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		return obj != null && obj instanceof Filter && filter.equals(((Filter) obj).filter);
-	}
-
-	@Override
-	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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/lib/filter/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 36fc73c..0000000
--- a/bundleplugin/src/main/java/aQute/lib/getopt/Arguments.java
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index 370d2d4..0000000
--- a/bundleplugin/src/main/java/aQute/lib/getopt/CommandLine.java
+++ /dev/null
@@ -1,472 +0,0 @@
-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.*;
-import aQute.service.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(80,30,32,70);
-	CommandLineMessages	msg;
-
-	public CommandLine(Reporter reporter) {
-		this.reporter = reporter;
-		msg = ReporterMessages.base(reporter, CommandLineMessages.class);
-	}
-
-	/**
-	 * 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) {
-			msg.NoSuchCommand_(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) {
-				msg.TooManyArguments_(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.contains("...")) {
-					i = Integer.MAX_VALUE;
-					break;
-				}
-
-				// Check if we're running out of args
-
-				if (i > arguments.size()) {
-					if (!optional)
-						msg.MissingArgument_(patterns[i]);
-					return help(target, cmd, optionClass);
-				}
-			}
-
-			// Check if we have unconsumed arguments left
-
-			if (i < arguments.size()) {
-				msg.TooManyArguments_(arguments);
-				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)
-						msg.UnrecognizedOption_(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;
-							}
-						}
-						msg.UnrecognizedOption_(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))
-				msg.OptionNotSet_(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) {
-				msg.Option__WithArgumentNotLastInAvvreviation_(name, name.charAt(0), getTypeDescriptor(type));
-				return;
-			}
-
-			if (args.isEmpty()) {
-				msg.MissingArgument__(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)) {
-					msg.OptionCanOnlyOccurOnce_(name);
-					return;
-				}
-
-				options.put(name, parameter);
-			}
-		}
-	}
-
-	/**
-	 * Provide a help text.
-	 */
-
-	public void help(Formatter f, @SuppressWarnings("unused")
-	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("%nNAME%n  %s \t0- \t1%s%n%n", cmd, description);
-		if (options.isEmpty())
-			f.format("SYNOPSIS%n   %s ", cmd);
-		else
-			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");
-		}
-
-		if (!options.isEmpty()) {
-			f.format("%nOPTIONS%n%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 \t0- \t1%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/CommandLineMessages.java b/bundleplugin/src/main/java/aQute/lib/getopt/CommandLineMessages.java
deleted file mode 100644
index 8d65141..0000000
--- a/bundleplugin/src/main/java/aQute/lib/getopt/CommandLineMessages.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package aQute.lib.getopt;
-
-import java.util.*;
-
-import aQute.service.reporter.*;
-
-public interface CommandLineMessages extends Messages {
-
-	ERROR Option__WithArgumentNotLastInAvvreviation_(String name, char charAt, String typeDescriptor);
-
-	ERROR MissingArgument__(String name, char charAt);
-
-	ERROR OptionCanOnlyOccurOnce_(String name);
-
-	ERROR NoSuchCommand_(String cmd);
-
-	ERROR TooManyArguments_(List<String> arguments);
-
-	ERROR MissingArgument_(String string);
-
-	ERROR UnrecognizedOption_(String name);
-
-	ERROR OptionNotSet_(String name);
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/getopt/Description.java b/bundleplugin/src/main/java/aQute/lib/getopt/Description.java
deleted file mode 100644
index d5baead..0000000
--- a/bundleplugin/src/main/java/aQute/lib/getopt/Description.java
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index f4e9faa..0000000
--- a/bundleplugin/src/main/java/aQute/lib/getopt/OptionArgument.java
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100644
index ff2b168..0000000
--- a/bundleplugin/src/main/java/aQute/lib/getopt/Options.java
+++ /dev/null
@@ -1,15 +0,0 @@
-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
deleted file mode 100644
index 9ad81f6..0000000
--- a/bundleplugin/src/main/java/aQute/lib/getopt/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100755
index ffceded..0000000
--- a/bundleplugin/src/main/java/aQute/lib/hex/Hex.java
+++ /dev/null
@@ -1,62 +0,0 @@
-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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/lib/hex/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c51286f..0000000
--- a/bundleplugin/src/main/java/aQute/lib/index/Index.java
+++ /dev/null
@@ -1,351 +0,0 @@
-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;
-
-	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();
-		}
-
-		@Override
-		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;
-	}
-
-	@Override
-	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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/lib/index/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 9a118d5..0000000
--- a/bundleplugin/src/main/java/aQute/lib/io/IO.java
+++ /dev/null
@@ -1,512 +0,0 @@
-package aQute.lib.io;
-
-import java.io.*;
-import java.net.*;
-import java.nio.*;
-import java.security.*;
-import java.util.*;
-
-public class IO {
-	static final public File	work	= new File(System.getProperty("user.dir"));
-	static final public File	home	= new File(System.getProperty("user.home"));
-
-	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()) {
-			if (!b.exists() && !b.mkdirs()) {
-				throw new IOException("Could not create directory " + b);
-			}
-			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();
-	}
-
-	/**
-	 * Create a temporary file.
-	 * 
-	 * @param directory
-	 *            the directory in which to create the file. Can be null, in
-	 *            which case the system TMP directory is used
-	 * @param pattern
-	 *            the filename prefix pattern. Must be at least 3 characters
-	 *            long
-	 * @param suffix
-	 *            the filename suffix. Can be null, in which case (system)
-	 *            default suffix is used
-	 * @return
-	 * @throws IllegalArgumentException
-	 *             when pattern is null or too short
-	 * @throws IOException
-	 *             when the specified (non-null) directory is not a directory
-	 */
-	public static File createTempFile(File directory, String pattern, String suffix) throws IllegalArgumentException,
-			IOException {
-		if ((pattern == null) || (pattern.length() < 3)) {
-			throw new IllegalArgumentException("Pattern must be at least 3 characters long, got "
-					+ ((pattern == null) ? "null" : pattern.length()));
-		}
-
-		if ((directory != null) && !directory.isDirectory()) {
-			throw new FileNotFoundException("Directory " + directory + " is not a directory");
-		}
-
-		return File.createTempFile(pattern, suffix, directory);
-	}
-
-	public static File getFile(String filename) {
-		return getFile(work, filename);
-	}
-
-	public static File getFile(File base, String file) {
-
-		if (file.startsWith("~/")) {
-			file = file.substring(2);
-			if (!file.startsWith("~/")) {
-				return getFile(home, file);
-			}
-		}
-		if (file.startsWith("~")) {
-			file = file.substring(1);
-			return getFile(home.getParentFile(), file);
-		}
-
-		File f = new File(file);
-		if (f.isAbsolute())
-			return f;
-		int n;
-
-		if (base == null)
-			base = work;
-
-		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();
-	}
-
-	/**
-	 * Deletes the specified file. Folders are recursively deleted.<br>
-	 * If file(s) cannot be deleted, no feedback is provided (fail silently).
-	 * 
-	 * @param f
-	 *            file to be deleted
-	 */
-	public static void delete(File f) {
-		try {
-			deleteWithException(f);
-		}
-		catch (IOException e) {
-			// Ignore a failed delete
-		}
-	}
-
-	/**
-	 * Deletes the specified file. Folders are recursively deleted.<br>
-	 * Throws exception if any of the files could not be deleted.
-	 * 
-	 * @param f
-	 *            file to be deleted
-	 * @throws IOException
-	 *             if the file (or contents of a folder) could not be deleted
-	 */
-	public static void deleteWithException(File f) throws IOException {
-		f = f.getAbsoluteFile();
-		if (!f.exists())
-			return;
-		if (f.getParentFile() == null)
-			throw new IllegalArgumentException("Cannot recursively delete root for safety reasons");
-
-		boolean wasDeleted = true;
-		if (f.isDirectory()) {
-			File[] subs = f.listFiles();
-			for (File sub : subs) {
-				try {
-					deleteWithException(sub);
-				}
-				catch (IOException e) {
-					wasDeleted = false;
-				}
-			}
-		}
-
-		boolean fDeleted = f.delete();
-		if (!fDeleted || !wasDeleted) {
-			throw new IOException("Failed to delete " + f.getAbsoluteFile());
-		}
-	}
-
-	/**
-	 * Deletes <code>to</code> file if it exists, and renames <code>from</code>
-	 * file to <code>to</code>.<br>
-	 * Throws exception the rename operation fails.
-	 * 
-	 * @param from
-	 *            source file
-	 * @param to
-	 *            destination file
-	 * @throws IOException
-	 *             if the rename operation fails
-	 */
-	public static void rename(File from, File to) throws IOException {
-		IO.deleteWithException(to);
-
-		boolean renamed = from.renameTo(to);
-		if (!renamed)
-			throw new IOException("Could not rename " + from.getAbsoluteFile() + " to " + to.getAbsoluteFile());
-	}
-
-	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
deleted file mode 100644
index b48ce5e..0000000
--- a/bundleplugin/src/main/java/aQute/lib/io/LimitedInputStream.java
+++ /dev/null
@@ -1,86 +0,0 @@
-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
deleted file mode 100644
index 71cb898..0000000
--- a/bundleplugin/src/main/java/aQute/lib/io/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.3.0
diff --git a/bundleplugin/src/main/java/aQute/lib/json/ArrayHandler.java b/bundleplugin/src/main/java/aQute/lib/json/ArrayHandler.java
deleted file mode 100644
index 7e3b35e..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/ArrayHandler.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package aQute.lib.json;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-public class ArrayHandler extends Handler {
-	Type	componentType;
-
-	ArrayHandler(@SuppressWarnings("unused") 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
deleted file mode 100644
index 9dfbaf4..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/BooleanHandler.java
+++ /dev/null
@@ -1,34 +0,0 @@
-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(Decoder dec, boolean s) {
-		return s;
-	}
-
-	@Override
-	Object decode(Decoder dec, String s) {
-		return Boolean.parseBoolean(s);
-	}
-
-	@Override
-	Object decode(Decoder dec, Number s) {
-		return s.intValue() != 0;
-	}
-
-	@Override
-	Object decode(Decoder dec) {
-		return false;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/ByteArrayHandler.java b/bundleplugin/src/main/java/aQute/lib/json/ByteArrayHandler.java
deleted file mode 100644
index 349b381..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/ByteArrayHandler.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package aQute.lib.json;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.lib.base64.*;
-import aQute.lib.hex.*;
-
-/**
- * Will now use hex for encoding byte arrays
- */
-public class ByteArrayHandler extends Handler {
-	Pattern	ENCODING	= Pattern
-								.compile("((:?[\\dA-Za-z][\\dA-Za-z])*)|((:?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/)+={1,3})");
-
-	@Override
-	void encode(Encoder app, Object object, Map<Object,Type> visited) throws IOException, Exception {
-		StringHandler.string(app, Hex.toHexString((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(Decoder dec, String s) throws Exception {
-		boolean hex = true;
-		StringBuilder sb = new StringBuilder(s);
-		for (int i = sb.length() - 1; i >= 0; i--) {
-			char c = sb.charAt(i);
-			if (Character.isWhitespace(c))
-				sb.delete(i, i + 1);
-			else {
-				switch (c) {
-					case '0' :
-					case '1' :
-					case '2' :
-					case '3' :
-					case '4' :
-					case '5' :
-					case '6' :
-					case '7' :
-					case '8' :
-					case '9' :
-					case 'A' :
-					case 'B' :
-					case 'C' :
-					case 'D' :
-					case 'E' :
-					case 'F' :
-					case 'a' :
-					case 'b' :
-					case 'c' :
-					case 'd' :
-					case 'e' :
-					case 'f' :
-						break;
-
-					default :
-						hex = false;
-						break;
-				}
-			}
-		}
-		if ( hex)
-			return Hex.toByteArray(sb.toString());
-		else
-			return Base64.decodeBase64(sb.toString());
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/CharacterHandler.java b/bundleplugin/src/main/java/aQute/lib/json/CharacterHandler.java
deleted file mode 100644
index 799f73c..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/CharacterHandler.java
+++ /dev/null
@@ -1,35 +0,0 @@
-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 = c.charValue();
-		app.append(v + "");
-	}
-
-	@Override
-	Object decode(Decoder dec, boolean s) {
-		return s ? 't' : 'f';
-	}
-
-	@Override
-	Object decode(Decoder dec, String s) {
-		return (char) Integer.parseInt(s);
-	}
-
-	@Override
-	Object decode(Decoder dec, Number s) {
-		return (char) s.shortValue();
-	}
-
-	@Override
-	Object decode(Decoder dec) {
-		return 0;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/CollectionHandler.java b/bundleplugin/src/main/java/aQute/lib/json/CollectionHandler.java
deleted file mode 100644
index aacbb0a..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/CollectionHandler.java
+++ /dev/null
@@ -1,57 +0,0 @@
-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 {
-		Iterable< ? > collection = (Iterable< ? >) object;
-
-		app.append("[");
-		String del = "";
-		for (Object o : collection) {
-			app.append(del);
-			app.encode(o, componentType, visited);
-			del = ",";
-		}
-		app.append("]");
-	}
-
-	@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
deleted file mode 100644
index cb3c27e..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/DateHandler.java
+++ /dev/null
@@ -1,32 +0,0 @@
-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(Decoder dec, String s) throws Exception {
-		synchronized (sdf) {
-			return sdf.parse(s);
-		}
-	}
-
-	@Override
-	Object decode(Decoder dec, 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
deleted file mode 100644
index 87cd1bc..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/Decoder.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package aQute.lib.json;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.security.*;
-import java.util.*;
-import java.util.zip.*;
-
-import aQute.lib.converter.*;
-
-public class Decoder implements Closeable {
-	final JSONCodec		codec;
-	Reader				reader;
-	int					current;
-	MessageDigest		digest;
-	Map<String,Object>	extra;
-	String				encoding	= "UTF-8";
-
-	boolean				strict;
-	boolean inflate;
-
-	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 {
-	
-		if ( inflate)
-			in  = new InflaterInputStream(in);
-		
-		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();
-	}
-
-	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);
-	}
-
-	public <T> T get(TypeReference<T> ref) throws Exception {
-		return (T) codec.decode(ref.getType(), 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;
-	}
-	
-	public Decoder inflate() {
-		if ( reader != null)
-			throw new IllegalStateException("Reader already set, inflate must come before from()");
-		inflate = true;
-		return this;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/Encoder.java b/bundleplugin/src/main/java/aQute/lib/json/Encoder.java
deleted file mode 100644
index 034ea6a..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/Encoder.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package aQute.lib.json;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.security.*;
-import java.util.*;
-import java.util.zip.*;
-
-public class Encoder implements Appendable, Closeable, Flushable {
-	final JSONCodec	codec;
-	Appendable		app;
-	MessageDigest	digest;
-	boolean			writeDefaults;
-	String			encoding	= "UTF-8";
-	boolean deflate;
-	
-	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>());
-		flush();
-		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 {
-		if ( deflate)
-			out = new DeflaterOutputStream(out);
-		
-		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;
-	}
-
-	@Override
-	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();
-		}
-	}
-	public Encoder deflate() {
-		if ( app != null)
-			throw new IllegalStateException("Writer already set, deflate must come before to(...)");
-		deflate = true;
-		return this;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/EnumHandler.java b/bundleplugin/src/main/java/aQute/lib/json/EnumHandler.java
deleted file mode 100644
index 9b5eaf3..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/EnumHandler.java
+++ /dev/null
@@ -1,26 +0,0 @@
-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());
-	}
-
-	@Override
-	@SuppressWarnings("unchecked")
-	Object decode(Decoder dec, 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
deleted file mode 100644
index b2c0838..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/FileHandler.java
+++ /dev/null
@@ -1,41 +0,0 @@
-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();
-		}
-	}
-
-	@Override
-	Object decode(Decoder dec, 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
deleted file mode 100644
index 5738b04..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/Handler.java
+++ /dev/null
@@ -1,34 +0,0 @@
-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(@SuppressWarnings("unused") Decoder isr) throws Exception {
-		throw new UnsupportedOperationException("Cannot be mapped to object " + this);
-	}
-
-	Object decodeArray(@SuppressWarnings("unused") Decoder isr) throws Exception {
-		throw new UnsupportedOperationException("Cannot be mapped to array " + this);
-	}
-
-	Object decode(Decoder dec, @SuppressWarnings("unused") String s) throws Exception {
-		throw new UnsupportedOperationException("Cannot be mapped to string " + this);
-	}
-
-	Object decode(Decoder dec, @SuppressWarnings("unused") Number s) throws Exception {
-		throw new UnsupportedOperationException("Cannot be mapped to number " + this);
-	}
-
-	Object decode(Decoder dec, @SuppressWarnings("unused") boolean s) {
-		throw new UnsupportedOperationException("Cannot be mapped to boolean " + this);
-	}
-
-	Object decode(Decoder dec) {
-		return null;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/json/JSONCodec.java b/bundleplugin/src/main/java/aQute/lib/json/JSONCodec.java
deleted file mode 100644
index 02601d4..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/JSONCodec.java
+++ /dev/null
@@ -1,492 +0,0 @@
-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.
- * <p/>
- * Will now use hex for encoding byte arrays
- */
-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();
-
-	boolean											ignorenull;
-
-	/**
-	 * 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 (Iterable.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 (Iterable.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 if (Dictionary.class.isAssignableFrom(rawClass))
-						h = new MapHandler(Hashtable.class, 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(isr, parseString(isr));
-
-			case 'n' :
-				isr.expect("ull");
-				return h.decode(isr);
-
-			case 't' :
-				isr.expect("rue");
-				return h.decode(isr,Boolean.TRUE);
-
-			case 'f' :
-				isr.expect("alse");
-				return h.decode(isr,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(isr,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);
-	}
-
-	/**
-	 * Ignore null values in output and input
-	 * 
-	 * @param ignorenull
-	 * @return
-	 */
-	public JSONCodec setIgnorenull(boolean ignorenull) {
-		this.ignorenull = ignorenull;
-		return this;
-	}
-
-	public boolean isIgnorenull() {
-		return ignorenull;
-	}
-
-}
\ 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
deleted file mode 100644
index 504bb07..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/MapHandler.java
+++ /dev/null
@@ -1,95 +0,0 @@
-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 if (rawClass.isAssignableFrom(Dictionary.class))
-				rawClass = Hashtable.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("}");
-	}
-
-	@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(r,(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);
-			if (value != null || !r.codec.ignorenull)
-				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
deleted file mode 100644
index d8e6160..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/NumberHandler.java
+++ /dev/null
@@ -1,73 +0,0 @@
-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(Decoder dec, boolean s) {
-		return decode(dec,s ? 1d : 0d);
-	}
-
-	@Override
-	Object decode(Decoder dec, String s) {
-		double d = Double.parseDouble(s);
-		return decode(dec, d);
-	}
-
-	@Override
-	Object decode(Decoder dec) {
-		return decode(dec,0d);
-	}
-
-	@Override
-	Object decode(Decoder dec, 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
deleted file mode 100644
index 9b297b7..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/ObjectHandler.java
+++ /dev/null
@@ -1,151 +0,0 @@
-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(@SuppressWarnings("unused") 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("}");
-	}
-
-	@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);
-				if (value != null || !r.codec.ignorenull)
-					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
deleted file mode 100644
index 36218c8..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/SpecialHandler.java
+++ /dev/null
@@ -1,41 +0,0 @@
-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(Decoder dec, 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
deleted file mode 100644
index 47a4eab..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/StringHandler.java
+++ /dev/null
@@ -1,152 +0,0 @@
-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('"');
-	}
-
-	@Override
-	Object decode(Decoder dec, String s) throws Exception {
-		return s;
-	}
-
-	@Override
-	Object decode(Decoder dec, Number s) {
-		return s.toString();
-	}
-
-	@Override
-	Object decode(Decoder dec, boolean s) {
-		return Boolean.toString(s);
-	}
-
-	@Override
-	Object decode(Decoder dec ) {
-		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.
-	 */
-	@Override
-	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.
-	 */
-	@Override
-	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, @SuppressWarnings("unused") 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
deleted file mode 100644
index 63eb236..0000000
--- a/bundleplugin/src/main/java/aQute/lib/json/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 3.0.0
diff --git a/bundleplugin/src/main/java/aQute/lib/justif/Justif.java b/bundleplugin/src/main/java/aQute/lib/justif/Justif.java
deleted file mode 100644
index 26319e8..0000000
--- a/bundleplugin/src/main/java/aQute/lib/justif/Justif.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package aQute.lib.justif;
-
-import java.util.*;
-
-public class Justif {
-	int[]	tabs;
-
-	public Justif(@SuppressWarnings("unused") 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
deleted file mode 100644
index 9ad81f6..0000000
--- a/bundleplugin/src/main/java/aQute/lib/justif/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0.0
diff --git a/bundleplugin/src/main/java/aQute/lib/putjar/DirectoryInputStream.java b/bundleplugin/src/main/java/aQute/lib/putjar/DirectoryInputStream.java
deleted file mode 100644
index 8731037..0000000
--- a/bundleplugin/src/main/java/aQute/lib/putjar/DirectoryInputStream.java
+++ /dev/null
@@ -1,283 +0,0 @@
-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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/lib/putjar/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
diff --git a/bundleplugin/src/main/java/aQute/lib/settings/Settings.java b/bundleplugin/src/main/java/aQute/lib/settings/Settings.java
deleted file mode 100644
index 55a149d..0000000
--- a/bundleplugin/src/main/java/aQute/lib/settings/Settings.java
+++ /dev/null
@@ -1,251 +0,0 @@
-package aQute.lib.settings;
-
-import java.io.*;
-import java.security.*;
-import java.security.spec.*;
-import java.util.*;
-
-import aQute.lib.io.*;
-import aQute.lib.json.*;
-
-/**
- * Maintains persistent settings for bnd (or other apps). The default is
- * ~/.bnd/settings.json). The settings are normal string properties but it
- * specially maintains a public/private key pair and it provides a method to
- * sign a byte array with this pair.
- * <p/>
- * Why not keystore and preferences? Well, keystore is hard to use (you can only
- * store a private key when you have a certificate, but you cannot create a
- * certificate without using com.sun classes) and preferences are not editable.
- */
-public class Settings implements Map<String,String> {
-	static JSONCodec	codec	= new JSONCodec();
-
-	private File		where;
-	private PublicKey	publicKey;
-	private PrivateKey	privateKey;
-	private boolean		loaded;
-	private boolean		dirty;
-
-	public static class Data {
-		public int					version	= 1;
-		public byte[]				secret;
-		public byte[]				id;
-		public Map<String,String>	map		= new HashMap<String,String>();
-	}
-
-	Data	data	= new Data();
-
-	public Settings() {
-		this("~/.bnd/settings.json");
-	}
-
-	public Settings(String where) {
-		assert where != null;
-		this.where = IO.getFile(IO.work, where);
-	}
-
-	public boolean load() {
-		if (this.where.isFile() && this.where.length() > 1) {
-			try {
-				data = codec.dec().from(this.where).get(Data.class);
-				loaded = true;
-				return true;
-			}
-			catch (Exception e) {
-				throw new RuntimeException("Cannot read settings file " + this.where, e);
-			}
-		}
-
-		if (!data.map.containsKey("name"))
-			data.map.put("name", System.getProperty("user.name"));
-		return false;
-	}
-
-	private void check() {
-		if (loaded)
-			return;
-		load();
-		loaded = true;
-	}
-
-	public void save() {
-		if (!this.where.getParentFile().isDirectory() && !this.where.getParentFile().mkdirs())
-			throw new RuntimeException("Cannot create directory in " + this.where.getParent());
-
-		try {
-			codec.enc().to(this.where).put(data).flush();
-			assert this.where.isFile();
-		}
-		catch (Exception e) {
-			throw new RuntimeException("Cannot write settings file " + this.where, e);
-		}
-	}
-
-	public void generate() throws Exception {
-		KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
-		SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
-		keyGen.initialize(1024, random);
-		KeyPair pair = keyGen.generateKeyPair();
-		privateKey = pair.getPrivate();
-		publicKey = pair.getPublic();
-		data.secret = privateKey.getEncoded();
-		data.id = publicKey.getEncoded();
-		save();
-	}
-
-	public String getEmail() {
-		return get("email");
-	}
-
-	public void setEmail(String email) {
-		put("email", email);
-	}
-
-	public void setName(String v) {
-		put("name", v);
-	}
-
-	public String getName() {
-		String name = get("name");
-		if (name != null)
-			return name;
-		return System.getProperty("user.name");
-	}
-
-	/**
-	 * Return an encoded public RSA key. this key can be decoded with an
-	 * X509EncodedKeySpec
-	 * 
-	 * @return an encoded public key.
-	 * @throws Exception
-	 */
-	public byte[] getPublicKey() throws Exception {
-		initKeys();
-		return data.id;
-	}
-
-	/**
-	 * Return an encoded private RSA key. this key can be decoded with an
-	 * PKCS8EncodedKeySpec
-	 * 
-	 * @return an encoded private key.
-	 * @throws Exception
-	 */
-	public byte[] getPrivateKey() throws Exception {
-		initKeys();
-		return data.secret;
-	}
-
-	/*
-	 * Initialize the keys.
-	 */
-	private void initKeys() throws Exception {
-		check();
-		if (publicKey != null)
-			return;
-
-		if (data.id == null || data.secret == null) {
-			generate();
-		} else {
-			PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(data.secret);
-			X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(data.id);
-			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
-			privateKey = keyFactory.generatePrivate(privateKeySpec);
-			publicKey = keyFactory.generatePublic(publicKeySpec);
-		}
-	}
-
-	/**
-	 * Sign a byte array
-	 */
-	public byte[] sign(byte[] con) throws Exception {
-		initKeys();
-
-		Signature hmac = Signature.getInstance("SHA1withRSA");
-		hmac.initSign(privateKey);
-		hmac.update(con);
-		return hmac.sign();
-	}
-
-	/**
-	 * Verify a signed byte array
-	 */
-	public boolean verify(byte[] con) throws Exception {
-		initKeys();
-
-		Signature hmac = Signature.getInstance("SHA1withRSA");
-		hmac.initVerify(publicKey);
-		hmac.update(con);
-		return hmac.verify(con);
-	}
-
-	public void clear() {
-		data = new Data();
-		IO.delete(where);
-	}
-
-	public boolean containsKey(Object key) {
-		check();
-		return data.map.containsKey(key);
-	}
-
-	public boolean containsValue(Object value) {
-		check();
-		return data.map.containsValue(value);
-	}
-
-	public Set<java.util.Map.Entry<String,String>> entrySet() {
-		check();
-		return data.map.entrySet();
-	}
-
-	public String get(Object key) {
-		check();
-
-		return data.map.get(key);
-	}
-
-	public boolean isEmpty() {
-		check();
-		return data.map.isEmpty();
-	}
-
-	public Set<String> keySet() {
-		check();
-		return data.map.keySet();
-	}
-
-	public String put(String key, String value) {
-		check();
-		dirty = true;
-		return data.map.put(key, value);
-	}
-
-	public void putAll(Map< ? extends String, ? extends String> v) {
-		check();
-		dirty = true;
-		data.map.putAll(v);
-	}
-
-	public String remove(Object key) {
-		check();
-		dirty = true;
-		return data.map.remove(key);
-	}
-
-	public int size() {
-		check();
-		return data.map.size();
-	}
-
-	public Collection<String> values() {
-		check();
-		return data.map.values();
-	}
-
-	public boolean isDirty() {
-		return dirty;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/settings/packageinfo b/bundleplugin/src/main/java/aQute/lib/settings/packageinfo
deleted file mode 100644
index 7ae9673..0000000
--- a/bundleplugin/src/main/java/aQute/lib/settings/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.1
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java b/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java
deleted file mode 100644
index fc219c1..0000000
--- a/bundleplugin/src/main/java/aQute/lib/spring/JPAComponent.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package aQute.lib.spring;
-
-import java.util.*;
-
-import aQute.bnd.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 {
-
-	@Override
-	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
deleted file mode 100644
index eff6ef4..0000000
--- a/bundleplugin/src/main/java/aQute/lib/spring/SpringComponent.java
+++ /dev/null
@@ -1,98 +0,0 @@
-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.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.Descriptors.PackageRef;
-import aQute.bnd.service.*;
-
-/**
- * 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
deleted file mode 100644
index 5ec76b0..0000000
--- a/bundleplugin/src/main/java/aQute/lib/spring/SpringXMLType.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package aQute.lib.spring;
-
-import java.util.*;
-
-import aQute.bnd.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 {
-
-	@Override
-	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
deleted file mode 100644
index d01fd57..0000000
--- a/bundleplugin/src/main/java/aQute/lib/spring/XMLType.java
+++ /dev/null
@@ -1,103 +0,0 @@
-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.bnd.osgi.*;
-import aQute.bnd.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
deleted file mode 100644
index e8ca286..0000000
--- a/bundleplugin/src/main/java/aQute/lib/spring/XMLTypeProcessor.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package aQute.lib.spring;
-
-import java.util.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.service.*;
-
-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(@SuppressWarnings("unused") 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/tag/Tag.java b/bundleplugin/src/main/java/aQute/lib/tag/Tag.java
deleted file mode 100755
index cc305d8..0000000
--- a/bundleplugin/src/main/java/aQute/lib/tag/Tag.java
+++ /dev/null
@@ -1,470 +0,0 @@
-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.
-	 */
-	@Override
-	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 == null) && (suri == null)) || ((turi != 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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/lib/tag/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index bde15aa..0000000
--- a/bundleplugin/src/main/java/aQute/libg/asn1/BER.java
+++ /dev/null
@@ -1,467 +0,0 @@
-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
deleted file mode 100644
index 2fb29fb..0000000
--- a/bundleplugin/src/main/java/aQute/libg/asn1/PDU.java
+++ /dev/null
@@ -1,111 +0,0 @@
-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
deleted file mode 100644
index 8f189ed..0000000
--- a/bundleplugin/src/main/java/aQute/libg/asn1/Types.java
+++ /dev/null
@@ -1,66 +0,0 @@
-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/packageinfo b/bundleplugin/src/main/java/aQute/libg/asn1/packageinfo
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/asn1/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c89c5f2..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cafs/CAFS.java
+++ /dev/null
@@ -1,430 +0,0 @@
-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;
-	final static byte[]	CAFE;
-	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;
-
-	static {
-		try {
-		CAFS = "CAFS".getBytes("UTF-8");
-		CAFE = "CAFE".getBytes("UTF-8");
-		} catch (Throwable e) {
-			throw new ExceptionInInitializerError(e);
-		}
-	}
-
-	/**
-	 * 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) {
-				if (home.exists()) {
-					throw new IOException(home + " is not a directory");
-				}
-				if (!home.mkdirs()) {
-					throw new IOException("Could not create directory " + home);
-				}
-			} 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;
-			}
-
-			@Override
-			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));
-			}
-
-			@Override
-			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);
-	}
-
-	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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cafs/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100755
index 86740ca..0000000
--- a/bundleplugin/src/main/java/aQute/libg/classdump/ClassDumper.java
+++ /dev/null
@@ -1,648 +0,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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/classdump/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c199a92..0000000
--- a/bundleplugin/src/main/java/aQute/libg/classloaders/URLClassLoaderWrapper.java
+++ /dev/null
@@ -1,28 +0,0 @@
-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
deleted file mode 100644
index 9ad81f6..0000000
--- a/bundleplugin/src/main/java/aQute/libg/classloaders/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100755
index bab9fee..0000000
--- a/bundleplugin/src/main/java/aQute/libg/clauses/Clause.java
+++ /dev/null
@@ -1,8 +0,0 @@
-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
deleted file mode 100755
index 5701bab..0000000
--- a/bundleplugin/src/main/java/aQute/libg/clauses/Clauses.java
+++ /dev/null
@@ -1,61 +0,0 @@
-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
deleted file mode 100755
index 50b53fa..0000000
--- a/bundleplugin/src/main/java/aQute/libg/clauses/Selector.java
+++ /dev/null
@@ -1,110 +0,0 @@
-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);
-	}
-
-	@Override
-	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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/clauses/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index f48e016..0000000
--- a/bundleplugin/src/main/java/aQute/libg/command/Command.java
+++ /dev/null
@@ -1,311 +0,0 @@
-package aQute.libg.command;
-
-import java.io.*;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
-import aQute.lib.io.*;
-import aQute.service.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 static boolean needsWindowsQuoting(String s) {
-		int len = s.length();
-		if (len == 0) // empty string have to be quoted
-			return true;
-		for (int i = 0; i < len; i++) {
-			switch (s.charAt(i)) {
-				case ' ' :
-				case '\t' :
-				case '\\' :
-				case '"' :
-					return true;
-			}
-		}
-		return false;
-	}
-
-	public static String windowsQuote(String s) {
-		if (!needsWindowsQuoting(s))
-			return s;
-		s = s.replaceAll("([\\\\]*)\"", "$1$1\\\\\"");
-		s = s.replaceAll("([\\\\]*)\\z", "$1$1");
-		return "\"" + s + "\"";
-	}
-
-	public int execute(final InputStream in, Appendable stdout, Appendable stderr) throws Exception {
-		if (reporter != null) {
-			reporter.trace("executing cmd: %s", arguments);
-		}
-		
-		ProcessBuilder p;
-		if (fullCommand != null) {
-			p = new ProcessBuilder(fullCommand);
-		} else {
-			//[cs] Arguments on windows aren't processed correctly. Thus the below junk
-			// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6511002
-			
-			if (System.getProperty("os.name").startsWith("Windows")) {
-				List<String> adjustedStrings = new LinkedList<String>();
-				for (String a : arguments) {
-					adjustedStrings.add(windowsQuote(a));
-				}
-				p = new ProcessBuilder(adjustedStrings);
-			} else {
-				p = new ProcessBuilder(arguments);
-			}
-		}
-		
-		Map<String, String> env = p.environment();
-		for (Entry<String,String> s : variables.entrySet()) {
-			env.put(s.getKey(), s.getValue());
-		}
-		
-		p.directory(cwd);
-		process = p.start();
-
-		// 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;
-		final OutputStream stdin = process.getOutputStream();
-		Thread rdInThread = null;
-
-		if (timeout != 0) {
-			timer = new TimerTask() {
-				//@Override TODO why did this not work? TimerTask implements Runnable
-				public void run() {
-					timedout = true;
-					process.destroy();
-				}
-			};
-			Command.timer.schedule(timer, timeout);
-		}
-
-		final AtomicBoolean finished = new AtomicBoolean(false);
-		InputStream out = process.getInputStream();
-		try {
-			InputStream err = process.getErrorStream();
-			try {
-				Collector cout = new Collector(out, stdout);
-				cout.start();
-				Collector cerr = new Collector(err, stderr);
-				cerr.start();
-
-				if (in != null) {
-					if (in == System.in) {
-						rdInThread = new Thread("Read Input Thread") {
-							@Override
-							public void run() {
-								try {
-									while (!finished.get()) {
-										int n = in.available();
-										if (n == 0) {
-											sleep(100);
-										} else {
-											int c = in.read();
-											if (c < 0) {
-												stdin.close();
-												return;
-											}
-											stdin.write(c);
-											if (c == '\n')
-												stdin.flush();
-										}
-									}
-								}
-								catch (InterruptedIOException e) {
-									// Ignore here
-								}
-								catch (Exception e) {
-									// Who cares?
-								}
-								finally {
-									IO.close(stdin);
-								}
-							}
-						};
-						rdInThread.setDaemon(true);
-						rdInThread.start();
-					} else {
-						IO.copy(in, stdin);
-						stdin.close();
-					}
-				}
-				if (reporter != null)
-					reporter.trace("exited process");
-
-				cerr.join();
-				cout.join();
-				if (reporter != null)
-					reporter.trace("stdout/stderr streams have finished");
-			}
-			finally {
-				err.close();
-			}
-		}
-		finally {
-			out.close();
-			if (timer != null)
-				timer.cancel();
-			Runtime.getRuntime().removeShutdownHook(hook);
-		}
-
-		byte exitValue = (byte) process.waitFor();
-		finished.set(true);
-		if (rdInThread != null) {
-			if (in != null)
-				IO.close(in);
-			rdInThread.interrupt();
-		}
-
-		if (reporter != null)
-			reporter.trace("cmd %s executed with result=%d, result: %s/%s, timedout=%s", arguments, exitValue, stdout,
-					stderr, timedout);
-
-		if (timedout)
-			return Integer.MIN_VALUE;
-
-		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);
-		}
-
-		@Override
-		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);
-				}
-			}
-		}
-	}
-
-	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);
-	}
-
-	@Override
-	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
deleted file mode 100644
index 63eb236..0000000
--- a/bundleplugin/src/main/java/aQute/libg/command/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 3.0.0
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Crypto.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Crypto.java
deleted file mode 100644
index 3d27188..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/Crypto.java
+++ /dev/null
@@ -1,62 +0,0 @@
-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
-	 */
-	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
deleted file mode 100644
index 119a35b..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/Digest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-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;
-	}
-
-	public String asHex() {
-		return Hex.toHexString(digest());
-	}
-
-	@Override
-	public String toString() {
-		return String.format("%s(d=%s)", getAlgorithm(), Hex.toHexString(digest));
-	}
-
-	public abstract String getAlgorithm();
-
-	@Override
-	public boolean equals(Object other) {
-		if (!(other instanceof Digest))
-			return false;
-
-		Digest d = (Digest) other;
-		return Arrays.equals(d.digest, digest);
-	}
-
-	@Override
-	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
deleted file mode 100644
index 2722ab1..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/Digester.java
+++ /dev/null
@@ -1,60 +0,0 @@
-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();
-
-	public T from(File f) throws Exception {
-		IO.copy(f, this);
-		return digest();
-	}
-	public T from(byte[] f) throws Exception {
-		IO.copy(f, this);
-		return digest();
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/cryptography/Key.java b/bundleplugin/src/main/java/aQute/libg/cryptography/Key.java
deleted file mode 100644
index f4fc217..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/Key.java
+++ /dev/null
@@ -1,6 +0,0 @@
-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
deleted file mode 100644
index c6def1b..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/MD5.java
+++ /dev/null
@@ -1,48 +0,0 @@
-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;
-	}
-
-	public static MD5 digest(byte [] data) throws Exception {
-		return getDigester().from(data);
-	}
-
-	public static MD5 digest(File f) throws NoSuchAlgorithmException, Exception {
-		return getDigester().from(f);
-	}
-	public static MD5 digest(InputStream f) throws NoSuchAlgorithmException, Exception {
-		return getDigester().from(f);
-	}
-}
\ 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
deleted file mode 100644
index c1aa2ee..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/RSA.java
+++ /dev/null
@@ -1,47 +0,0 @@
-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
deleted file mode 100644
index c2f1e8d..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/SHA1.java
+++ /dev/null
@@ -1,48 +0,0 @@
-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;
-	}
-
-	public static SHA1 digest(byte [] data) throws Exception {
-		return getDigester().from(data);
-	}
-
-	public static SHA1 digest(File f) throws NoSuchAlgorithmException, Exception {
-		return getDigester().from(f);
-	}
-	public static SHA1 digest(InputStream f) throws NoSuchAlgorithmException, Exception {
-		return getDigester().from(f);
-	}
-}
\ 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
deleted file mode 100644
index 42baf4e..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/SHA256.java
+++ /dev/null
@@ -1,49 +0,0 @@
-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;
-	}
-
-
-	public static SHA256 digest(byte [] data) throws Exception {
-		return getDigester().from(data);
-	}
-
-	public static SHA256 digest(File f) throws NoSuchAlgorithmException, Exception {
-		return getDigester().from(f);
-	}
-	public static SHA256 digest(InputStream f) throws NoSuchAlgorithmException, Exception {
-		return getDigester().from(f);
-	}
-}
\ 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
deleted file mode 100644
index 977eda6..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/Signer.java
+++ /dev/null
@@ -1,44 +0,0 @@
-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
deleted file mode 100644
index 1005e0a..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/Verifier.java
+++ /dev/null
@@ -1,39 +0,0 @@
-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
deleted file mode 100644
index e39f616..0000000
--- a/bundleplugin/src/main/java/aQute/libg/cryptography/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 2c988e6..0000000
--- a/bundleplugin/src/main/java/aQute/libg/fileiterator/FileIterator.java
+++ /dev/null
@@ -1,42 +0,0 @@
-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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/fileiterator/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 9f82899..0000000
--- a/bundleplugin/src/main/java/aQute/libg/filelock/DirectoryLock.java
+++ /dev/null
@@ -1,31 +0,0 @@
-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
deleted file mode 100644
index 9ad81f6..0000000
--- a/bundleplugin/src/main/java/aQute/libg/filelock/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0.0
diff --git a/bundleplugin/src/main/java/aQute/libg/filters/AndFilter.java b/bundleplugin/src/main/java/aQute/libg/filters/AndFilter.java
deleted file mode 100644
index 2561d77..0000000
--- a/bundleplugin/src/main/java/aQute/libg/filters/AndFilter.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package aQute.libg.filters;
-
-import java.util.LinkedList;
-import java.util.List;
-
-public final class AndFilter extends Filter {
-	
-	private final List<Filter> children = new LinkedList<Filter>();
-	
-	public AndFilter addChild(Filter child) {
-		if (child instanceof AndFilter)
-			children.addAll(((AndFilter) child).children);
-		else
-			children.add(child);
-		return this;
-	}
-
-	@Override
-	public void append(StringBuilder builder) {
-		if (children.isEmpty())
-			return;
-		
-		builder.append("(&");
-		for (Filter child : children) {
-			child.append(builder);
-		}
-		builder.append(")");
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/filters/Filter.java b/bundleplugin/src/main/java/aQute/libg/filters/Filter.java
deleted file mode 100644
index e0a4555..0000000
--- a/bundleplugin/src/main/java/aQute/libg/filters/Filter.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package aQute.libg.filters;
-
-public abstract class Filter {
-
-	public abstract void append(StringBuilder builder);
-
-	@Override
-	public String toString() {
-		StringBuilder builder = new StringBuilder();
-		append(builder);
-		return builder.toString();
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/filters/LiteralFilter.java b/bundleplugin/src/main/java/aQute/libg/filters/LiteralFilter.java
deleted file mode 100644
index ca09228..0000000
--- a/bundleplugin/src/main/java/aQute/libg/filters/LiteralFilter.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package aQute.libg.filters;
-
-public class LiteralFilter extends Filter {
-	
-	private String	filterString;
-
-	public LiteralFilter(String filterString) {
-		this.filterString = filterString;
-	}
-
-	@Override
-	public void append(StringBuilder builder) {
-		builder.append(filterString);
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/filters/NotFilter.java b/bundleplugin/src/main/java/aQute/libg/filters/NotFilter.java
deleted file mode 100644
index 0f1061c..0000000
--- a/bundleplugin/src/main/java/aQute/libg/filters/NotFilter.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package aQute.libg.filters;
-
-public final class NotFilter extends Filter {
-
-	private final Filter	child;
-
-	public NotFilter(Filter child) {
-		this.child = child;
-	}
-
-	@Override
-	public void append(StringBuilder builder) {
-		builder.append("(!");
-		child.append(builder);
-		builder.append(")");
-	}
-	
-	
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/filters/Operator.java b/bundleplugin/src/main/java/aQute/libg/filters/Operator.java
deleted file mode 100644
index b17aaff..0000000
--- a/bundleplugin/src/main/java/aQute/libg/filters/Operator.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package aQute.libg.filters;
-
-public enum Operator {
-
-	Equals("="), LessThanOrEqual("<="), GreaterThanOrEqual(">="), ApproxEqual("~=");
-
-	private final String	symbol;
-
-	Operator(String symbol) {
-		this.symbol = symbol;
-	}
-
-	public String getSymbol() {
-		return symbol;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/filters/OrFilter.java b/bundleplugin/src/main/java/aQute/libg/filters/OrFilter.java
deleted file mode 100644
index b3332bd..0000000
--- a/bundleplugin/src/main/java/aQute/libg/filters/OrFilter.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package aQute.libg.filters;
-
-import java.util.LinkedList;
-import java.util.List;
-
-public final class OrFilter extends Filter {
-	
-	private final List<Filter> children = new LinkedList<Filter>();
-	
-	public OrFilter addChild(Filter child) {
-		if (child instanceof OrFilter)
-			children.addAll(((OrFilter) child).children);
-		else
-			children.add(child);
-		return this;
-	}
-
-	@Override
-	public void append(StringBuilder builder) {
-		if (children.isEmpty())
-			return;
-		
-		builder.append("(|");
-		for (Filter child : children) {
-			child.append(builder);
-		}
-		builder.append(")");
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/filters/SimpleFilter.java b/bundleplugin/src/main/java/aQute/libg/filters/SimpleFilter.java
deleted file mode 100644
index f0dea65..0000000
--- a/bundleplugin/src/main/java/aQute/libg/filters/SimpleFilter.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package aQute.libg.filters;
-
-public final class SimpleFilter extends Filter {
-
-	private final String	name;
-	private final Operator	operator;
-	private final String	value;
-
-	/**
-	 * Construct a simple filter with the default "equals" operator, i.e.
-	 * {@code (name=value)}.
-	 */
-	public SimpleFilter(String name, String value) {
-		this(name, Operator.Equals, value);
-	}
-
-	/**
-	 * Construct a simple filter with any of the comparison operators.
-	 */
-	public SimpleFilter(String name, Operator operator, String value) {
-		this.name = name;
-		this.operator = operator;
-		this.value = value;
-	}
-
-	@Override
-	public void append(StringBuilder builder) {
-		builder.append('(');
-		builder.append(name).append(operator.getSymbol()).append(value);
-		builder.append(')');
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/filters/packageinfo b/bundleplugin/src/main/java/aQute/libg/filters/packageinfo
deleted file mode 100644
index a4f1546..0000000
--- a/bundleplugin/src/main/java/aQute/libg/filters/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/forker/Forker.java b/bundleplugin/src/main/java/aQute/libg/forker/Forker.java
deleted file mode 100644
index 14bb0f8..0000000
--- a/bundleplugin/src/main/java/aQute/libg/forker/Forker.java
+++ /dev/null
@@ -1,211 +0,0 @@
-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
-		 */
-		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
-	 */
-	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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/forker/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 3e071b3..0000000
--- a/bundleplugin/src/main/java/aQute/libg/generics/Create.java
+++ /dev/null
@@ -1,53 +0,0 @@
-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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/generics/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 6202524..0000000
--- a/bundleplugin/src/main/java/aQute/libg/glob/Glob.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package aQute.libg.glob;
-
-import java.util.*;
-import java.util.regex.*;
-
-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);
-		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();
-	}
-
-	public void select(List<?> objects) {
-		for ( Iterator<?> i =objects.iterator(); i.hasNext(); ) {
-			String s = i.next().toString();
-			if ( !matcher(s).matches())
-				i.remove();
-		}
-	}
-
-	public static Pattern toPattern(String s) {
-		try {
-			return Pattern.compile( convertGlobToRegEx(s));
-		} catch( Exception e) {
-			// ignore
-		}
-		return null;
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/glob/packageinfo b/bundleplugin/src/main/java/aQute/libg/glob/packageinfo
deleted file mode 100644
index 9ad81f6..0000000
--- a/bundleplugin/src/main/java/aQute/libg/glob/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index 81c9785..0000000
--- a/bundleplugin/src/main/java/aQute/libg/gzip/GZipUtils.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package aQute.libg.gzip;
-
-import java.io.*;
-import java.util.zip.*;
-
-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
deleted file mode 100644
index 9ad81f6..0000000
--- a/bundleplugin/src/main/java/aQute/libg/gzip/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0.0
diff --git a/bundleplugin/src/main/java/aQute/libg/log/Logger.java b/bundleplugin/src/main/java/aQute/libg/log/Logger.java
deleted file mode 100755
index 05d869f..0000000
--- a/bundleplugin/src/main/java/aQute/libg/log/Logger.java
+++ /dev/null
@@ -1,19 +0,0 @@
-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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/log/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index e4776f7..0000000
--- a/bundleplugin/src/main/java/aQute/libg/map/MAP.java
+++ /dev/null
@@ -1,43 +0,0 @@
-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
deleted file mode 100644
index 897578f..0000000
--- a/bundleplugin/src/main/java/aQute/libg/map/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100755
index 30e744b..0000000
--- a/bundleplugin/src/main/java/aQute/libg/qtokens/QuotedTokenizer.java
+++ /dev/null
@@ -1,118 +0,0 @@
-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) == 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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/qtokens/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/reporter/Message.java b/bundleplugin/src/main/java/aQute/libg/reporter/Message.java
deleted file mode 100644
index afaad88..0000000
--- a/bundleplugin/src/main/java/aQute/libg/reporter/Message.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package aQute.libg.reporter;
-
-public @interface Message {
-	String value();
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/reporter/ReporterAdapter.java b/bundleplugin/src/main/java/aQute/libg/reporter/ReporterAdapter.java
deleted file mode 100644
index 8c3f68b..0000000
--- a/bundleplugin/src/main/java/aQute/libg/reporter/ReporterAdapter.java
+++ /dev/null
@@ -1,304 +0,0 @@
-package aQute.libg.reporter;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.libg.generics.*;
-import aQute.service.reporter.*;
-
-/**
- * Mainly used for testing where reporters are needed.
- */
-public class ReporterAdapter implements Reporter, Report, Runnable {
-	final List<String>	errors		= new ArrayList<String>();
-	final List<String>	warnings	= new ArrayList<String>();
-	final List<LocationImpl> locations = new ArrayList<LocationImpl>();
-	
-	static class LocationImpl extends Location implements SetLocation {
-
-
-
-		public LocationImpl(String e) {
-			// TODO Auto-generated constructor stub
-		}
-
-		public SetLocation file(String file) {
-			this.file = file;
-			return this;
-		}
-
-		public SetLocation header(String header) {
-			this.header = header;
-			return this;
-		}
-
-		public SetLocation context(String context) {
-			this.context = context;
-			return this;
-		}
-
-		public SetLocation method(String methodName) {
-			this.methodName = methodName;
-			return this;
-		}
-
-		public SetLocation line(int line) {
-			this.line = line;
-			return this;
-		}
-
-		public SetLocation reference(String reference) {
-			this.reference = reference;
-			return this;
-		}
-		
-	}
-	
-	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 SetLocation error(String s, Object... args) {
-		String e = String.format(s, args);
-		errors.add(e);
-		trace("ERROR: %s", e);
-		return location(e);
-	}
-
-	public SetLocation exception(Throwable t, String s, Object... args) {
-		StackTraceElement[] stackTrace = t.getStackTrace();
-		String method = stackTrace[0].getMethodName();
-		String cname = stackTrace[0].getClassName();
-		String e = String.format("["+shorten(cname) +"."+method+"] " +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);
-		return location(e);
-	}
-
-	private String shorten(String cname) {
-		int index = cname.lastIndexOf('$');
-		if ( index < 0)
-			index = cname.lastIndexOf('.');
-		
-		return cname.substring(index+1);
-	}
-
-	public SetLocation warning(String s, Object... args) {
-		String e = String.format(s, args);
-		warnings.add(e);
-		trace("warning: %s", e);
-		return location(e);
-	}
-
-	private SetLocation location(String e) {
-		LocationImpl loc = new LocationImpl(e);
-		locations.add( loc );
-		return loc;
-	}
-
-	public void progress(float progress, String s, Object... args) {
-		if (out != null) {
-			out.format(s, args);
-			if (!s.endsWith(String.format("%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())
-			System.err.println("Missed the following patterns in the warnings or errors: " + missed);
-
-		report(System.err);
-		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);
-		}
-	}
-
-	public boolean getInfo(Report other) {
-		return getInfo(other,null);
-	}
-	public boolean getInfo(Report other, String prefix) {
-		addErrors(prefix, other.getErrors());
-		addWarnings(prefix, other.getWarnings());
-		return other.isOk();
-	}
-
-	public Location getLocation(String msg) {
-		for ( LocationImpl loc : locations ) {
-			if ((loc.message != null) && loc.message.equals(msg))
-				return loc;
-		}
-		return null;
-	}
-
-	/**
-	 * Handy routine that can be extended by subclasses
-	 * so they can run inside the context
-	 */
-	public void run() {
-		throw new UnsupportedOperationException("Must be implemented by subclass");
-	}
-
-	/**
-	 * Return a messages object bound to this adapter
-	 */
-	
-	public <T> T getMessages(Class<T> c) {
-		return ReporterMessages.base(this, c);
-	}
-	
-	/**
-	 * Add a number of errors
-	 */
-	
-	public void addErrors( String prefix, Collection<String> errors) {
-		if ( prefix == null)
-			prefix = "";
-		else
-			prefix = prefix + ": ";
-		for ( String s: errors) {
-			this.errors.add( prefix + s);
-		}
-	}
-	/**
-	 * Add a number of warnings
-	 */
-	
-	public void addWarnings( String prefix, Collection<String> warnings) {
-		if ( prefix == null)
-			prefix = "";
-		else
-			prefix = prefix + ": ";
-		for ( String s: warnings) {
-			this.warnings.add( prefix  + s);
-		}
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/reporter/ReporterMessages.java b/bundleplugin/src/main/java/aQute/libg/reporter/ReporterMessages.java
deleted file mode 100644
index 17191f8..0000000
--- a/bundleplugin/src/main/java/aQute/libg/reporter/ReporterMessages.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package aQute.libg.reporter;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import aQute.service.reporter.*;
-import aQute.service.reporter.Messages.*;
-import aQute.service.reporter.Reporter.SetLocation;
-
-public class ReporterMessages {
-
-	static class WARNINGImpl implements WARNING {
-		Reporter.SetLocation	loc;
-
-		public SetLocation file(String file) {
-			return loc.file(file);
-		}
-
-		public SetLocation header(String header) {
-			return loc.header(header);
-		}
-
-		public SetLocation context(String context) {
-			return loc.context(context);
-		}
-
-		public SetLocation method(String methodName) {
-			return loc.method(methodName);
-		}
-
-		public SetLocation line(int n) {
-			return loc.line(n);
-		}
-
-		public SetLocation reference(String reference) {
-			return loc.reference(reference);
-		}
-
-		public WARNINGImpl(Reporter.SetLocation loc) {
-			this.loc = loc;
-		}
-	}
-
-	static class ERRORImpl extends WARNINGImpl implements ERROR {
-		public ERRORImpl(SetLocation e) {
-			super(e);
-		}
-	}
-
-	public static <T> T base(final Reporter reporter, Class<T> messages) {
-		return (T) Proxy.newProxyInstance(messages.getClassLoader(), new Class[] {
-			messages
-		}, new InvocationHandler() {
-
-			public Object invoke(Object target, Method method, Object[] args) throws Throwable {
-				String format;
-				Message d = method.getAnnotation(Message.class);
-				if (d == null) {
-					String name = method.getName();
-					StringBuilder sb = new StringBuilder();
-					sb.append(name.charAt(0));
-					for (int i = 1; i < name.length(); i++) {
-						char c = name.charAt(i);
-						switch (c) {
-							case '_' :
-								sb.append(" %s, ");
-								break;
-
-							default :
-								if (Character.isUpperCase(c)) {
-									sb.append(" ");
-									c = Character.toLowerCase(c);
-								}
-								sb.append(c);
-						}
-					}
-					format = sb.toString();
-				} else
-					format = d.value();
-
-				try {
-					if (method.getReturnType() == ERROR.class) {
-						return new ERRORImpl(reporter.error(format, args));
-
-					} else if (method.getReturnType() == WARNING.class) {
-						return new WARNINGImpl(reporter.warning(format, args));
-					} else
-						reporter.trace(format, args);
-				}
-				catch (IllegalFormatException e) {
-					reporter.error("Formatter failed: %s %s %s", method.getName(), format, Arrays.toString(args));
-				}
-				return null;
-			}
-		});
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/reporter/packageinfo b/bundleplugin/src/main/java/aQute/libg/reporter/packageinfo
deleted file mode 100644
index 0117a56..0000000
--- a/bundleplugin/src/main/java/aQute/libg/reporter/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.3
diff --git a/bundleplugin/src/main/java/aQute/libg/sax/ContentFilter.java b/bundleplugin/src/main/java/aQute/libg/sax/ContentFilter.java
deleted file mode 100644
index e08f4de..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sax/ContentFilter.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package aQute.libg.sax;
-
-import org.xml.sax.*;
-
-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
deleted file mode 100644
index 3bfb6b5..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sax/ContentFilterImpl.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package aQute.libg.sax;
-
-import org.xml.sax.*;
-
-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
deleted file mode 100644
index 0b7e914..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sax/SAXElement.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package aQute.libg.sax;
-
-import org.xml.sax.*;
-
-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
deleted file mode 100644
index ab7b470..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sax/SAXUtil.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package aQute.libg.sax;
-
-import javax.xml.parsers.*;
-import javax.xml.transform.*;
-import javax.xml.transform.sax.*;
-
-import org.xml.sax.*;
-
-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
deleted file mode 100644
index 3ba7f5a..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sax/filters/ElementSelectionFilter.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package aQute.libg.sax.filters;
-
-import org.xml.sax.*;
-
-import aQute.libg.sax.*;
-
-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
deleted file mode 100644
index b0d4df8..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sax/filters/MergeContentFilter.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package aQute.libg.sax.filters;
-
-import java.util.*;
-
-import org.xml.sax.*;
-
-import aQute.libg.sax.*;
-
-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
deleted file mode 100644
index a4f1546..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sax/filters/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index a4f1546..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sax/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/sed/Domain.java b/bundleplugin/src/main/java/aQute/libg/sed/Domain.java
deleted file mode 100644
index c030c83..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sed/Domain.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package aQute.libg.sed;
-
-import java.util.*;
-
-public interface Domain {
-	Map<String,String> getMap();
-
-	Domain getParent();
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/sed/Replacer.java b/bundleplugin/src/main/java/aQute/libg/sed/Replacer.java
deleted file mode 100644
index 3c02aaf..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sed/Replacer.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package aQute.libg.sed;
-
-public interface Replacer {
-	String process(String line);
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/sed/ReplacerAdapter.java b/bundleplugin/src/main/java/aQute/libg/sed/ReplacerAdapter.java
deleted file mode 100644
index 1bd8e07..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sed/ReplacerAdapter.java
+++ /dev/null
@@ -1,935 +0,0 @@
-package aQute.libg.sed;
-
-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.glob.*;
-import aQute.libg.reporter.*;
-import aQute.service.reporter.*;
-
-/**
- * Provide a macro Domain. This Domain 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 Domain (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 ReplacerAdapter extends ReporterAdapter implements Replacer {
-	static final Random	random		= new Random();
-	static Pattern		WILDCARD	= Pattern.compile("[*?|[\\\\]\\(\\)]");
-	Domain				domain;
-	List<Object>		targets		= new ArrayList<Object>();
-	boolean				flattening;
-	File				base		= new File(System.getProperty("user.dir"));
-	Reporter			reporter	= this;
-
-	public ReplacerAdapter(Domain domain) {
-		this.domain = domain;
-	}
-
-	public ReplacerAdapter(final Map<String,String> domain) {
-		this(new Domain() {
-
-			public Map<String,String> getMap() {
-				return domain;
-			}
-
-			public Domain getParent() {
-				return null;
-			}
-			
-		});
-	}
-
-	public ReplacerAdapter target(Object target) {
-		assert target != null;
-		targets.add(target);
-		return this;
-	}
-
-	public ReplacerAdapter target(File base) {
-		this.base = base;
-		return this;
-	}
-
-	public String process(String line, Domain 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(base.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;
-	}
-
-	public String getProcessed(String key) {
-		return replace(key, null);
-	}
-
-	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) {
-				Domain source = domain;
-				String value = null;
-				if (key.indexOf(';') < 0) {
-					if (WILDCARD.matcher(key).find()) {
-						Glob ins = new Glob(key);
-						StringBuilder sb = new StringBuilder();
-						String del = "";
-						for (String k : getAllKeys()) {
-							if (ins.matcher(k).find()) {
-								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.getMap().get(key);
-						if (value != null)
-							return process(value, new Link(source, link, key));
-
-						source = source.getParent();
-					}
-				}
-				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("@"))
-					reporter.warning("No translation found for macro: " + key);
-			} else {
-				reporter.warning("Found empty macro key");
-			}
-		} else {
-			reporter.warning("Found null macro key");
-		}
-		return "${" + key + "}";
-	}
-
-	private List<String> getAllKeys() {
-		List<String> l = new ArrayList<String>();
-		Domain source = domain;
-		do {
-			l.addAll(source.getMap().keySet());
-			source = source.getParent();
-		} while (source != null);
-
-		Collections.sort(l);
-		return l;
-	}
-
-	/**
-	 * 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();
-
-			Domain parent = source.start.getParent();
-			if (parent != null)
-				return parent.getMap().get(varname);
-			return null;
-		}
-
-		Domain rover = domain;
-		while (rover != null) {
-			String result = doCommand(rover, args[0], args);
-			if (result != null)
-				return result;
-
-			rover = rover.getParent();
-		}
-
-		for (Object target : targets) {
-			String result = doCommand(target, 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) {
-					reporter.error("%s, for cmd: %s, arguments; %s", e.getCause().getMessage(), method, Arrays.toString(args));
-				} else {
-					reporter.warning("Exception in replace: " + e.getCause());
-					e.getCause().printStackTrace();
-				}
-			}
-			catch (Exception e) {
-				reporter.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++) {
-			set.addAll(ExtList.from(args[i].trim()));
-		}
-		ExtList<String> rsult = new ExtList<String>();
-		rsult.addAll(set);
-		return rsult.join(",");
-	}
-
-	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);
-
-		ExtList<String> list = ExtList.from(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 list.join();
-	}
-
-	static String	_sortHelp	= "${sort;<list>...}";
-
-	public String _sort(String args[]) {
-		verifyCommand(args, _sortHelp, null, 2, Integer.MAX_VALUE);
-
-		ExtList<String> result = new ExtList<String>();
-		for (int i = 1; i < args.length; i++) {
-			result.addAll(ExtList.from(args[i]));
-		}
-		Collections.sort(result);
-		return result.join();
-	}
-
-	static String	_joinHelp	= "${join;<list>...}";
-
-	public String _join(String args[]) {
-
-		verifyCommand(args, _joinHelp, null, 1, Integer.MAX_VALUE);
-
-		ExtList<String> result = new ExtList<String>();
-		for (int i = 1; i < args.length; i++) {
-			result.addAll(ExtList.from(args[i]));
-		}
-		return result.join();
-	}
-
-	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];
-		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 ExtList<String>();
-		for (int i = 1; i < args.length; i++) {
-			names.addAll(ExtList.from(args[i]));
-		}
-		for (String name : names) {
-			File f = new File(name);
-			if (f.exists() && f.lastModified() > time)
-				time = f.lastModified();
-		}
-		return "" + time;
-	}
-
-	public String _long2date(String args[]) {
-		try {
-			return new Date(Long.parseLong(args[1])).toString();
-		}
-		catch (Exception e) {
-			e.printStackTrace();
-		}
-		return "not a valid long";
-	}
-
-	public String _literal(String args[]) {
-		if (args.length != 2)
-			throw new RuntimeException("Need a value for the ${literal;<value>} macro");
-		return "${" + args[1] + "}";
-	}
-
-	public String _def(String args[]) {
-		if (args.length != 2)
-			throw new RuntimeException("Need a value for the ${def;<value>} macro");
-
-		String value = domain.getMap().get(args[1]);
-		if (value == null)
-			return "";
-
-		return value;
-	}
-
-	/**
-	 * replace ; <list> ; regex ; replace
-	 * 
-	 * @param args
-	 * @return
-	 */
-	public String _replace(String args[]) {
-		if (args.length != 4) {
-			reporter.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++) {
-			reporter.warning(process(args[i]));
-		}
-		return "";
-	}
-
-	public String _error(String args[]) {
-		for (int i = 1; i < args.length; i++) {
-			reporter.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 = ExtList.from(args[1]);
-
-		ExtList<String> names = new ExtList<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 {
-				reporter.warning("in toclassname, %s, is not a class path because it does not end in .class", args[1]);
-			}
-		}
-		return names.join(",");
-	}
-
-	/**
-	 * 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]);
-
-		ExtList<String> names = ExtList.from(args[1]);
-		ExtList<String> paths = new ExtList<String>(names.size());
-		for (String name : names) {
-			String path = name.replace('.', '/') + (cl ? ".class" : "");
-			paths.add(path);
-		}
-		return paths.join(",");
-	}
-
-	public String _dir(String args[]) {
-		if (args.length < 2) {
-			reporter.warning("Need at least one file name for ${dir;...}");
-			return null;
-		}
-		String del = "";
-		StringBuilder sb = new StringBuilder();
-		for (int i = 1; i < args.length; i++) {
-			File f = IO.getFile(base, 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) {
-			reporter.warning("Need at least one file name for ${basename;...}");
-			return null;
-		}
-		String del = "";
-		StringBuilder sb = new StringBuilder();
-		for (int i = 1; i < args.length; i++) {
-			File f = IO.getFile(base, 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) {
-			reporter.warning("Need at least one file name for ${isfile;...}");
-			return null;
-		}
-		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) {
-			reporter.warning("Need at least one file name for ${isdir;...}");
-			return null;
-		}
-		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();
-		TimeZone tz = TimeZone.getTimeZone("UTC");
-
-		if (args.length > 1) {
-			format = args[1];
-		}
-		if (args.length > 2) {
-			tz = TimeZone.getTimeZone(args[2]);
-		}
-		if (args.length > 3) {
-			now = Long.parseLong(args[3]);
-		}
-		if (args.length > 4) {
-			reporter.warning("Too many arguments for tstamp: " + Arrays.toString(args));
-		}
-
-		SimpleDateFormat sdf = new SimpleDateFormat(format);
-		sdf.setTimeZone(tz);
-
-		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 = IO.getFile(base, 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++) {
-			Glob filters = new Glob(args[i]);
-			filters.select(files);
-		}
-
-		ExtList<String> result = new ExtList<String>();
-		for (File file : files)
-			result.add(relative ? file.getName() : file.getAbsolutePath());
-
-		return result.join(",");
-	}
-
-	public String _currenttime(String args[]) {
-		return Long.toString(System.currentTimeMillis());
-	}
-
-	/**
-	 * 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, base);
-		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)) {
-			reporter.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 = IO.getFile(base, 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;
-		Domain	start;
-
-		public Link(Domain 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);
-		}
-
-		@Override
-		public String toString() {
-			StringBuilder sb = new StringBuilder("[");
-			append(sb);
-			sb.append("]");
-			return sb.toString();
-		}
-
-		private void append(StringBuilder sb) {
-			if (previous != null) {
-				previous.append(sb);
-				sb.append(",");
-			}
-			sb.append(key);
-		}
-	}
-
-	/**
-	 * 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 Map<String,String> getFlattenedProperties() {
-		// Some macros only work in a lower Domain, so we
-		// do not report unknown macros while flattening
-		flattening = true;
-		try {
-			Map<String,String> flattened = new HashMap<String,String>();
-			Map<String,String> source = domain.getMap();
-			for (String key : source.keySet()) {
-				if (!key.startsWith("_"))
-					if (key.startsWith("-"))
-						flattened.put(key, source.get(key));
-					else
-						flattened.put(key, process(source.get(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 = IO.getFile(base, args[2]);
-		return f.getAbsolutePath();
-	}
-
-	public String _path(String args[]) {
-		ExtList<String> list = new ExtList<String>();
-		for (int i = 1; i < args.length; i++) {
-			list.addAll(ExtList.from(args[i]));
-		}
-		return list.join(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);
-	}
-
-	/**
-	 * 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.");
-			}
-		}
-
-		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);
-	}
-
-	public void setReporter(Reporter reporter) {
-		this.reporter = reporter;
-	}
-
-	
-	public int _processors(String args[]) {
-		float multiplier = 1F;
-		if ( args.length > 1 )
-			multiplier = Float.parseFloat(args[1]);
-		
-		return (int) (Runtime.getRuntime().availableProcessors() * multiplier);
-	}
-	
-	public long _maxMemory(String args[]) {
-		return Runtime.getRuntime().maxMemory();
-	}
-	public long _freeMemory(String args[]) {
-		return Runtime.getRuntime().freeMemory();
-	}
-
-	public long _nanoTime(String args[]) {
-		return System.nanoTime();
-	}
-	
-}
diff --git a/bundleplugin/src/main/java/aQute/libg/sed/Sed.java b/bundleplugin/src/main/java/aQute/libg/sed/Sed.java
deleted file mode 100644
index 0542f65..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sed/Sed.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package aQute.libg.sed;
-
-import java.io.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.lib.io.*;
-
-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);
-			}
-        } finally {
-        	brdr.close();
-			pw.close();
-        }
-        
-		if (output == null) {
-			if (backup) {
-				File bak = new File(file.getAbsolutePath() + ".bak");
-				IO.rename(file, bak);
-			}
-			IO.rename(out, file);
-		}
-        
-		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
deleted file mode 100644
index b3d1f97..0000000
--- a/bundleplugin/src/main/java/aQute/libg/sed/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-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
deleted file mode 100644
index c3e8ee1..0000000
--- a/bundleplugin/src/main/java/aQute/libg/tarjan/Tarjan.java
+++ /dev/null
@@ -1,108 +0,0 @@
-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;
-		}
-
-		@Override
-		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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/tarjan/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/tuple/ComparablePair.java b/bundleplugin/src/main/java/aQute/libg/tuple/ComparablePair.java
deleted file mode 100644
index 36f0242..0000000
--- a/bundleplugin/src/main/java/aQute/libg/tuple/ComparablePair.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package aQute.libg.tuple;
-
-public class ComparablePair<A extends Comparable<A>, B> extends Pair<A,B> implements Comparable<Pair<A, ? >> {
-
-	private static final long	serialVersionUID	= 1L;
-
-	public ComparablePair(A first, B second) {
-		super(first, second);
-	}
-
-	public int compareTo(Pair<A, ? > o) {
-		return getFirst().compareTo(o.getFirst());
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/tuple/Pair.java b/bundleplugin/src/main/java/aQute/libg/tuple/Pair.java
deleted file mode 100644
index d4612ee..0000000
--- a/bundleplugin/src/main/java/aQute/libg/tuple/Pair.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package aQute.libg.tuple;
-
-import java.io.Serializable;
-
-public class Pair<A, B> implements Serializable, Cloneable {
-
-	private static final long	serialVersionUID	= 1L;
-
-	private final A				first;
-	private final B				second;
-
-	public Pair(A first, B second) {
-		assert first != null && second != null : "both parameters must be non-null";
-		this.first = first;
-		this.second = second;
-	}
-
-	public static <A, B> Pair<A,B> newInstance(A first, B second) {
-		return new Pair<A,B>(first, second);
-	}
-
-	public A getFirst() {
-		return first;
-	}
-
-	public B getSecond() {
-		return second;
-	}
-
-	@Override
-	public String toString() {
-		return "Pair [" + first + ", " + second + "]";
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((first == null) ? 0 : first.hashCode());
-		result = prime * result + ((second == null) ? 0 : second.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		@SuppressWarnings("unchecked")
-		Pair<A,B> other = (Pair<A,B>) obj;
-		if (first == null) {
-			if (other.first != null)
-				return false;
-		} else if (!first.equals(other.first))
-			return false;
-		if (second == null) {
-			if (other.second != null)
-				return false;
-		} else if (!second.equals(other.second))
-			return false;
-		return true;
-	}
-
-	@Override
-	public Pair<A,B> clone() {
-		return new Pair<A,B>(first, second);
-	}
-}
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/libg/tuple/packageinfo b/bundleplugin/src/main/java/aQute/libg/tuple/packageinfo
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/tuple/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
diff --git a/bundleplugin/src/main/java/aQute/libg/xslt/Transform.java b/bundleplugin/src/main/java/aQute/libg/xslt/Transform.java
deleted file mode 100644
index a505c4b..0000000
--- a/bundleplugin/src/main/java/aQute/libg/xslt/Transform.java
+++ /dev/null
@@ -1,43 +0,0 @@
-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<URI,Templates>	cache				= new ConcurrentHashMap<URI,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.toURI());
-		if (templates == null) {
-			InputStream xsltIn = xslt.openStream();
-			try {
-				templates = transformerFactory.newTemplates(new StreamSource(xsltIn));
-
-				cache.put(xslt.toURI(), 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
deleted file mode 100644
index 7c8de03..0000000
--- a/bundleplugin/src/main/java/aQute/libg/xslt/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0
diff --git a/bundleplugin/src/main/java/aQute/service/reporter/Messages.java b/bundleplugin/src/main/java/aQute/service/reporter/Messages.java
deleted file mode 100644
index e4b589e..0000000
--- a/bundleplugin/src/main/java/aQute/service/reporter/Messages.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package aQute.service.reporter;
-
-
-
-public interface Messages {
-	static public interface ERROR extends Reporter.SetLocation {}
-
-	static public interface WARNING extends Reporter.SetLocation {}
-
-	ERROR NoSuchFile_(Object r);
-
-	ERROR Unexpected_Error_(String context, Exception e);
-
-}
diff --git a/bundleplugin/src/main/java/aQute/service/reporter/Report.java b/bundleplugin/src/main/java/aQute/service/reporter/Report.java
deleted file mode 100644
index a637c8e..0000000
--- a/bundleplugin/src/main/java/aQute/service/reporter/Report.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package aQute.service.reporter;
-
-import java.util.*;
-
-/**
- * A base interface to represent the state of a work in progress.
- */
-public interface Report {
-	/**
-	 * Defines a record for the location of an error/warning
-	 */
-	class Location {
-		public String	message;
-		public int		line;
-		public String	file;
-		public String	header;
-		public String	context;
-		public String	reference;
-		public String	methodName;
-	}
-
-
-	/**
-	 * Return the warnings. This list must not be changed and may be immutable.
-	 * 
-	 * @return the warnings
-	 */
-	List<String> getWarnings();
-
-	/**
-	 * Return the errors. This list must not be changed and may be immutable.
-	 * 
-	 * @return the errors
-	 */
-	List<String> getErrors();
-
-	/**
-	 * Return the errors for the given error or warning. Can return null.
-	 * 
-	 * @param msg
-	 *            The message
-	 * @return null or the location of the message
-	 */
-	Location getLocation(String msg);
-
-	/**
-	 * Check if this report has any errors.
-	 * 
-	 * @return true if errors is empty
-	 */
-	
-	boolean isOk();
-}
diff --git a/bundleplugin/src/main/java/aQute/service/reporter/Reporter.java b/bundleplugin/src/main/java/aQute/service/reporter/Reporter.java
deleted file mode 100755
index 521ec5e..0000000
--- a/bundleplugin/src/main/java/aQute/service/reporter/Reporter.java
+++ /dev/null
@@ -1,130 +0,0 @@
-package aQute.service.reporter;
-
-/**
- * A base interface to model a work in progress. Though exceptions work well for
- * major, well, exceptions, they are lousy for reporting errors/warnings in a
- * task. Logging also sucks because it is global, hard to relate to a single
- * piece of work. This small (uncoupled) interface is intended to fill this gap.
- * The idea is that different tasks can perform parts and the progress can be
- * integrated. A reporter is not mandated to track locations. Locations should
- * be seen as best effort.
- */
-public interface Reporter extends Report {
-	/**
-	 * Fluid interface to set location data
-	 */
-	interface SetLocation {
-		/**
-		 * Set the file location
-		 */
-		SetLocation file(String file);
-
-		/**
-		 * Set the header/section location. This is normally the header in a
-		 * manifest or properties file.
-		 */
-		SetLocation header(String header);
-
-		/**
-		 * Set the context in the header.
-		 * 
-		 * @param context
-		 * @return
-		 */
-		SetLocation context(String context);
-
-		/**
-		 * Set the method where the error is reported.
-		 * 
-		 * @param context
-		 * @return
-		 */
-		SetLocation method(String methodName);
-
-		/**
-		 * Set the line number. Line 0 is the top line.
-		 */
-		SetLocation line(int n);
-
-		/**
-		 * Set a reference for the error (url or so)
-		 */
-
-		SetLocation reference(String reference);
-	}
-
-	/**
-	 * Create an error. Implementations must ensure that the given args are not
-	 * prevented from garbage collecting. The args must have a proper toString
-	 * method.
-	 * 
-	 * @param format
-	 *            The format of the error
-	 * @param args
-	 *            The arguments of the error
-	 * @return a SetLocation to set the location
-	 */
-	SetLocation error(String format, Object... args);
-
-	/**
-	 * Create a warning. Implementations must ensure that the given args are not
-	 * prevented from garbage collecting. The args must have a proper toString
-	 * method.
-	 * 
-	 * @param format
-	 *            The format of the error
-	 * @param args
-	 *            The arguments of the error
-	 * @return a SetLocation to set the location
-	 */
-	SetLocation warning(String format, Object... args);
-
-	/**
-	 * Create a warning. Implementations must ensure that the given args are not
-	 * prevented from garbage collecting. The args must have a proper toString
-	 * method.
-	 * 
-	 * @param format
-	 *            The format of the error
-	 * @param args
-	 *            The arguments of the error
-	 */
-	void trace(String format, Object... args);
-
-	/**
-	 * Create a warning. Implementations must ensure that the given args are not
-	 * prevented from garbage collecting. The args must have a proper toString
-	 * method.
-	 * 
-	 * @param progress
-	 *            A value between 0 and 1 indicating the progress. 0 is starting
-	 *            and >=1 is done.
-	 * @param format
-	 *            The format of the error
-	 * @param args
-	 *            The arguments of the error
-	 * @return a SetLocation to set the location
-	 */
-	void progress(float progress, String format, Object... args);
-
-	/**
-	 * Dedicated message for an exception.
-	 * 
-	 * @param t
-	 *            The exception
-	 * @param s
-	 *            The format of the message
-	 * @param args
-	 *            The arguments
-	 */
-	public SetLocation exception(Throwable t, String format, Object... args);
-
-	/**
-	 * The provider of the reporter wants pedantic reporting, meaning every
-	 * possible warning should be reported.
-	 * 
-	 * @return if this is a pedantic reporter.
-	 */
-	boolean isPedantic();
-
-}
diff --git a/bundleplugin/src/main/java/aQute/service/reporter/packageinfo b/bundleplugin/src/main/java/aQute/service/reporter/packageinfo
deleted file mode 100644
index 9ad81f6..0000000
--- a/bundleplugin/src/main/java/aQute/service/reporter/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 1.0.0
diff --git a/bundleplugin/src/main/resources/aQute/bnd/help/changed.txt b/bundleplugin/src/main/resources/aQute/bnd/help/changed.txt
deleted file mode 100644
index 14d0bd2..0000000
--- a/bundleplugin/src/main/resources/aQute/bnd/help/changed.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-0.0.325
-  - No longer flattening properties starting with - because for version policy, the 
-    context macro ${@} is not valid. I think this is true for more things. So they are now
-    unexpanded.
-  - toclasspath can now take a suffix parameter, possibly empty
-  - Include-Resource can now take optional parameters:
-      flatten:= (true|false). Default is false. Create recursive directories in the output or not.
-      recursive:= (true|false) Default is true. Will descend any directories or not
-      
diff --git a/bundleplugin/src/main/resources/aQute/bnd/help/syntax.properties b/bundleplugin/src/main/resources/aQute/bnd/help/syntax.properties
deleted file mode 100644
index 14ec642..0000000
--- a/bundleplugin/src/main/resources/aQute/bnd/help/syntax.properties
+++ /dev/null
@@ -1,342 +0,0 @@
-Add=Holders of DmtPermission with the Add action present can create new nodes in the DMT, that is they are authorized to execute the createInteriorNode() and createLeafNode() methods of the DmtSession.
-Delete=Holders of DmtPermission with the Delete action present can delete nodes from the DMT, that is they are authorized to execute the deleteNode() method of the DmtSession.
-Exec=Holders of DmtPermission with the Exec action present can execute nodes in the DMT, that is they are authorized to call the execute() method of the DmtSession.
-Get=Holders of DmtPermission with the Get action present can query DMT node value or properties, that is they are authorized to execute the isLeafNode(), getNodeAcl(), getEffectiveNodeAcl(), getMetaNode(), getNodeValue(), getChildNodeNames(), getNodeTitle(), getNodeVersion(), getNodeTimeStamp(), getNodeSize() and getNodeType() methods of the DmtSession.
-Replace=Holders of DmtPermission with the Replace action present can update DMT node value or properties, that is they are authorized to execute the setNodeAcl(), setNodeTitle(), setNodeValue(), setNodeType() and renameNode() methods of the DmtSession.
-get=The action string get.
-register=The action string register.
-export=The action string export.
-exportonly=The action string exportonly.
-import=The action string import.
-System Bundle=Location identifier of the OSGi system bundle , which is defined to be "System Bundle".
-system.bundle=Alias for the symbolic name of the OSGi system bundle .
-Bundle-Category=Manifest header identifying the bundle's category.
-Bundle-ClassPath=Manifest header identifying a list of directories and embedded JAR files, which are bundle resources used to extend the bundle's classpath.
-Bundle-Copyright=Manifest header identifying the bundle's copyright information.
-Bundle-Description=Manifest header containing a brief description of the bundle's functionality.
-Bundle-Name=Manifest header identifying the bundle's name.
-Bundle-NativeCode=Manifest header identifying a number of hardware environments and the native language code libraries that the bundle is carrying for each of these environments.
-Export-Package=Manifest header identifying the packages that the bundle offers to the Framework for export.
-Export-Service=Manifest header identifying the fully qualified class names of the services that the bundle may register (used for informational purposes only).
-Import-Package=Manifest header identifying the packages on which the bundle depends.
-DynamicImport-Package=Manifest header identifying the packages that the bundle may dynamically import during execution.
-Import-Service=Manifest header identifying the fully qualified class names of the services that the bundle requires (used for informational purposes only).
-Bundle-Vendor=Manifest header identifying the bundle's vendor.
-Bundle-Version=Manifest header identifying the bundle's version.
-Bundle-DocURL=Manifest header identifying the bundle's documentation URL, from which further information about the bundle may be obtained.
-Bundle-ContactAddress=Manifest header identifying the contact address where problems with the bundle may be reported; for example, an email address.
-Bundle-Activator=Manifest header attribute identifying the bundle's activator class.
-Bundle-UpdateLocation=Manifest header identifying the location from which a new bundle version is obtained during a bundle update operation.
-specification-version=Manifest header attribute identifying the version of a package specified in the Export-Package or Import-Package manifest header.
-processor=Manifest header attribute identifying the processor required to run native bundle code specified in the Bundle-NativeCode manifest header).
-osname=Manifest header attribute identifying the operating system required to run native bundle code specified in the Bundle-NativeCode manifest header).
-osversion=Manifest header attribute identifying the operating system version required to run native bundle code specified in the Bundle-NativeCode manifest header).
-language=Manifest header attribute identifying the language in which the native bundle code is written specified in the Bundle-NativeCode manifest header.
-Bundle-RequiredExecutionEnvironment=Manifest header identifying the required execution environment for the bundle.
-Bundle-SymbolicName=Manifest header identifying the bundle's symbolic name.
-singleton=Manifest header directive identifying whether a bundle is a singleton.
-fragment-attachment=Manifest header directive identifying if and when a fragment may attach to a host bundle.
-always=Manifest header directive value identifying a fragment attachment type of always.
-resolve-time=Manifest header directive value identifying a fragment attachment type of resolve-time.
-never=Manifest header directive value identifying a fragment attachment type of never.
-Bundle-Localization=Manifest header identifying the base name of the bundle's localization entries.
-OSGI-INF/l10n/bundle=Default value for the Bundle-Localization manifest header.
-Require-Bundle=Manifest header identifying the symbolic names of other bundles required by the bundle.
-bundle-version=Manifest header attribute identifying a range of versions for a bundle specified in the Require-Bundle or Fragment-Host manifest headers.
-Fragment-Host=Manifest header identifying the symbolic name of another bundle for which that the bundle is a fragment.
-selection-filter=Manifest header attribute is used for selection by filtering based upon system properties.
-Bundle-ManifestVersion=Manifest header identifying the bundle manifest version.
-version=Manifest header attribute identifying the version of a package specified in the Export-Package or Import-Package manifest header.
-bundle-symbolic-name=Manifest header attribute identifying the symbolic name of a bundle that exports a package specified in the Import-Package manifest header.
-resolution=Manifest header directive identifying the resolution type in the Import-Package or Require-Bundle manifest header.
-mandatory=Manifest header directive value identifying a mandatory resolution type.
-optional=Manifest header directive value identifying an optional resolution type.
-uses=Manifest header directive identifying a list of packages that an exported package uses.
-include=Manifest header directive identifying a list of classes to include in the exported package.
-exclude=Manifest header directive identifying a list of classes to exclude in the exported package..
-mandatory=Manifest header directive identifying names of matching attributes which must be specified by matching Import-Package statements in the Export-Package manifest header.
-visibility=Manifest header directive identifying the visibility of a required bundle in the Require-Bundle manifest header.
-private=Manifest header directive value identifying a private visibility type.
-reexport=Manifest header directive value identifying a reexport visibility type.
-extension=Manifest header directive identifying the type of the extension fragment.
-framework=Manifest header directive value identifying the type of extension fragment.
-bootclasspath=Manifest header directive value identifying the type of extension fragment.
-Bundle-ActivationPolicy=Manifest header identifying the bundle's activation policy.
-lazy=Bundle activation policy declaring the bundle must be activated when the first class load is made from the bundle.
-org.osgi.framework.version=Framework environment property identifying the Framework version.
-org.osgi.framework.vendor=Framework environment property identifying the Framework implementation vendor.
-org.osgi.framework.language=Framework environment property identifying the Framework implementation language (see ISO 639 for possible values).
-org.osgi.framework.os.name=Framework environment property identifying the Framework host-computer's operating system.
-org.osgi.framework.os.version=Framework environment property identifying the Framework host-computer's operating system version number.
-org.osgi.framework.processor=Framework environment property identifying the Framework host-computer's processor name.
-org.osgi.framework.executionenvironment=Framework environment property identifying execution environments provided by the Framework.
-org.osgi.framework.bootdelegation=Framework environment property identifying packages for which the Framework must delegate class loading to the parent class loader of the bundle.
-org.osgi.framework.system.packages=Framework environment property identifying packages which the system bundle must export.
-org.osgi.framework.system.packages.extra=Framework environment property identifying extra packages which the system bundle must export from the current execution environment.
-org.osgi.supports.framework.extension=Framework environment property identifying whether the Framework supports framework extension bundles.
-org.osgi.supports.bootclasspath.extension=Framework environment property identifying whether the Framework supports bootclasspath extension bundles.
-org.osgi.supports.framework.fragment=Framework environment property identifying whether the Framework supports fragment bundles.
-org.osgi.supports.framework.requirebundle=Framework environment property identifying whether the Framework supports the Require-Bundle manifest header.
-org.osgi.framework.security=Specifies the type of security manager the framework must use.
-osgi=Specifies that a security manager that supports all security aspects of the OSGi core specification including postponed conditions must be installed.
-org.osgi.framework.storage=Specified the persistent storage area used by the framework.
-org.osgi.framework.storage.clean=Specifies if and when the persistent storage area for the framework should be cleaned.
-onFirstInit=Specifies that the framework storage area must be cleaned before the framework is initialized for the first time.
-org.osgi.framework.library.extensions=Specifies a comma separated list of additional library file extensions that must be used when a bundle's class loader is searching for native libraries.
-org.osgi.framework.command.execpermission=Specifies an optional OS specific command to set file permissions on extracted native code.
-org.osgi.framework.trust.repositories=Specifies the trust repositories used by the framework.
-org.osgi.framework.windowsystem=Specifies the current windowing system.
-org.osgi.framework.startlevel.beginning=Specifies the beginning start level of the framework.
-org.osgi.framework.bundle.parent=Specifies the parent class loader type for all bundle class loaders.
-boot=Specifies to use of the boot class loader as the parent class loader for all bundle class loaders.
-app=Specifies to use the application class loader as the parent class loader for all bundle class loaders.
-ext=Specifies to use the extension class loader as the parent class loader for all bundle class loaders.
-framework=Specifies to use the framework class loader as the parent class loader for all bundle class loaders.
-objectClass=Service property identifying all of the class names under which a service was registered in the Framework.
-service.id=Service property identifying a service's registration number.
-service.pid=Service property identifying a service's persistent identifier.
-service.ranking=Service property identifying a service's ranking number.
-service.vendor=Service property identifying a service's vendor.
-service.description=Service property identifying a service's description.
-provide=The action string provide.
-require=The action string require.
-host=The action string host.
-fragment=The action string fragment.
-class=The action string class.
-execute=The action string execute.
-extensionLifecycle=The action string extensionLifecycle.
-lifecycle=The action string lifecycle.
-listener=The action string listener.
-metadata=The action string metadata.
-resolve=The action string resolve.
-resource=The action string resource.
-startlevel=The action string startlevel.
-context=The action string context.
-service.pid=The property key for the identifier of the application being scheduled.
-schedule.id=The property key for the schedule identifier.
-org.osgi.triggeringevent=The key for the startup argument used to pass the event object that triggered the schedule to launch the application instance.
-org/osgi/application/timer=The topic name for the virtual timer topic.
-year=The name of the year attribute of a virtual timer event.
-month=The name of the month attribute of a virtual timer event.
-day_of_month=The name of the day of month attribute of a virtual timer event.
-day_of_week=The name of the day of week attribute of a virtual timer event.
-hour_of_day=The name of the hour of day attribute of a virtual timer event.
-minute=The name of the minute attribute of a virtual timer event.
-service.pid=The property key for the unique identifier (PID) of the application instance.
-application.descriptor=The property key for the pid of the corresponding application descriptor.
-application.state=The property key for the state of this application instance.
-application.supports.exitvalue=The property key for the supports exit value property of this application instance.
-RUNNING=The application instance is running.
-STOPPING=The application instance is being stopped.
-application.name=The property key for the localized name of the application.
-application.icon=The property key for the localized icon of the application.
-service.pid=The property key for the unique identifier (PID) of the application.
-application.version=The property key for the version of the application.
-service.vendor=The property key for the name of the application vendor.
-application.visible=The property key for the visibility property of the application.
-application.launchable=The property key for the launchable property of the application.
-application.locked=The property key for the locked property of the application.
-application.description=The property key for the localized description of the application.
-application.documentation=The property key for the localized documentation of the application.
-application.copyright=The property key for the localized copyright notice of the application.
-application.license=The property key for the localized license of the application.
-application.container=The property key for the application container of the application.
-application.location=The property key for the location of the application.
-lifecycle=Allows the lifecycle management of the target applications.
-schedule=Allows scheduling of the target applications.
-lock=Allows setting/unsetting the locking state of the target applications.
-bundle.version=The version property defining the bundle on whose behalf a module context event has been issued.
-extender.bundle=The extender bundle property defining the extender bundle processing the module context for which an event has been issued.
-extender.bundle.id=The extender bundle id property defining the id of the extender bundle processing the module context for which an event has been issued.
-extender.bundle.symbolicName=The extender bundle symbolic name property defining the symbolic name of the extender bundle processing the module context for which an event has been issued.
-org/osgi/service/blueprint=Topic prefix for all events issued by the Blueprint Service
-org/osgi/service/blueprint/context/CREATING=Topic for Blueprint Service CREATING events
-org/osgi/service/blueprint/context/CREATED=Topic for Blueprint Service CREATED events
-org/osgi/service/blueprint/context/DESTROYING=Topic for Blueprint Service DESTROYING events
-org/osgi/service/blueprint/context/DESTROYED=Topic for Blueprint Service DESTROYED events
-org/osgi/service/blueprint/context/WAITING=Topic for Blueprint Service WAITING events
-org/osgi/service/blueprint/context/FAILURE=Topic for Blueprint Service FAILURE events
-singleton=
-prototype=
-bundle=
-cm.target=A service property to limit the Managed Service or Managed Service Factory configuration dictionaries a Configuration Plugin service receives.
-service.cmRanking=A service property to specify the order in which plugins are invoked.
-configure=The action string configure.
-service.factoryPid=Service property naming the Factory PID in the configuration dictionary.
-service.bundleLocation=Service property naming the location of the bundle that is associated with a a Configuration object.
-osgi.converter.classes=This property is a string, or array of strings, and defines the classes or interfaces that this converter recognizes.
-osgi.command.scope=The scope of commands provided by this service.
-osgi.command.function=A String, array, or list of method names that may be called for this command provider.
-Service-Component=Manifest header specifying the XML documents within a bundle that contain the bundle's Service Component descriptions.
-component.name=A component property for a component configuration that contains the name of the component as specified in the name attribute of the component element.
-component.id=A component property that contains the generated id for a component configuration.
-component.factory=A service registration property for a Component Factory that contains the value of the factory attribute.
-.target=The suffix for reference target properties.
-allow=This string is used to indicate that a row in the Conditional Permission Table should return an access decision of "allow" if the conditions are all satisfied and at least one of the permissions is implied.
-deny=This string is used to indicate that a row in the Conditional Permission Table should return an access decision of "deny" if the conditions are all satisfied and at least one of the permissions is implied.
-deploymentpackage.name=The name of the Deployment Package.
-deploymentpackage.readablename=The human readable name of the DP localized to the default locale.
-deploymentpackage.currentversion=The currently installed version of the Deployment Package.
-deploymentpackage.nextversion=The version of DP after the successful completion of the install operation (used in INSTALL event only).
-install=Constant String to the "install" action.
-list=Constant String to the "list" action.
-uninstall=Constant String to the "uninstall" action.
-uninstall_forced=Constant String to the "uninstall_forced" action.
-cancel=Constant String to the "cancel" action.
-metadata=Constant String to the "metadata" action.
-privatearea=Constant String to the "privatearea" action.
--1=Return value from DriverSelector.select, if no Driver service should be attached to the Device service.
-DRIVER_ID=Property (named "DRIVER_ID") identifying a driver.
-DEVICE_CATEGORY=Property (named "DEVICE_CATEGORY") containing a human readable description of the device categories implemented by a device.
-DEVICE_SERIAL=Property (named "DEVICE_SERIAL") specifying a device's serial number.
-DEVICE_DESCRIPTION=Property (named "DEVICE_DESCRIPTION") containing a human readable string describing the actual hardware device.
-service.interface=Mandatory ServiceRegistration property which contains a collection of full qualified interface names offered by the advertised service endpoint.
-service.interface.version=Optional ServiceRegistration property which contains a collection of interface names with their associated version attributes separated by SEPARATOR e.g.
-osgi.remote.endpoint.interface=Optional ServiceRegistration property which contains a collection of interface names with their associated (non-Java) endpoint interface names separated by SEPARATOR e.g.: 'my.company.foo|MyWebService my.company.zoo|MyWebService'. This (non-Java) endpoint interface name is usually a communication protocol specific interface, for instance a web service interface name.
-service.properties=Optional ServiceRegistration property which contains a map of properties of the published service.
-osgi.remote.endpoint.location=Optional property of the published service identifying its location.
-osgi.remote.endpoint.id=Optional property of the published service uniquely identifying its endpoint.
-|=Separator constant for association of interface-specific values with the particular interface name.
-osgi.remote.discovery.product=Service Registration property for the name of the Discovery product.
-osgi.remote.discovery.product.version=Service Registration property for the version of the Discovery product.
-osgi.remote.discovery.vendor=Service Registration property for the Discovery product vendor name.
-osgi.remote.discovery.supported_protocols=Service Registration property that lists the discovery protocols used by this Discovery service.
-osgi.discovery.interest.interfaces=Optional ServiceRegistration property which contains service interfaces this tracker is interested in.
-osgi.discovery.interest.filters=Optional ServiceRegistration property which contains filters for services this tracker is interested in.
-osgi.remote.distribution.product=Service Registration property for the name of the Distribution Provider product.
-osgi.remote.distribution.product.version=Service Registration property for the version of the Distribution Provider product.
-osgi.remote.distribution.vendor=Service Registration property for the Distribution Provider product vendor name.
-osgi.remote.distribition.supported_intents=Service Registration property that lists the intents supported by this DistributionProvider.
-publish=The action string publish.
-subscribe=The action string subscribe.
-event.topics=Service registration property (named event.topics) specifying the Event topics of interest to a Event Handler service.
-event.filter=Service Registration property (named event.filter) specifying a filter to further select Event s of interest to a Event Handler service.
-bundle.signer=The Distinguished Names of the signers of the bundle relevant to the event.
-bundle.symbolicName=The Bundle Symbolic Name of the bundle relevant to the event.
-bundle.id=The Bundle id of the bundle relevant to the event.
-bundle=The Bundle object of the bundle relevant to the event.
-bundle.version=The version of the bundle relevant to the event.
-event=The forwarded event object.
-exception=An exception or error.
-exception.class=The name of the exception type.
-exception.message=The exception message.
-message=A human-readable message that is usually not localized.
-service=A service reference.
-service.id=A service's id.
-service.objectClass=A service's objectClass.
-service.pid=A service's persistent identity.
-timestamp=The time when the event occurred, as reported by System.currentTimeMillis().
-exception.class=This constant was released with an incorrectly spelled name.
-CompositeServiceFilter-Import=Manifest header (named "CompositeServiceFilter-Import") identifying the service filters that are used by a composite bundle to select services that will be registered into a child framework by its associated surrogate bundle.
-CompositeServiceFilter-Export=Manifest header (named "CompositeServiceFilter-Export") identifying the service filters that are used by a surrogate bundle to select services that will be registered into a parent framework by its associated composite bundle.
-org.osgi.service.http.authentication.remote.user=HttpServletRequest attribute specifying the name of the authenticated user.
-org.osgi.service.http.authentication.type=HttpServletRequest attribute specifying the scheme used in authentication.
-org.osgi.service.useradmin.authorization=HttpServletRequest attribute specifying the Authorization object obtained from the org.osgi.service.useradmin.UserAdmin service.
-io.scheme=Service property containing the scheme(s) for which this Connection Factory can create Connection objects.
--1=Argument for getAttributeDefinitions(int).
-OSGI-INF/metatype=Location of meta type documents.
-read=Holders of MonitorPermission with the read action present are allowed to read the value of the StatusVariables specified in the permission's target field.
-reset=Holders of MonitorPermission with the reset action present are allowed to reset the value of the StatusVariables specified in the permission's target field.
-publish=Holders of MonitorPermission with the publish action present are Monitorable services that are allowed to publish the StatusVariables specified in the permission's target field.
-startjob=Holders of MonitorPermission with the startjob action present are allowed to initiate monitoring jobs involving the StatusVariables specified in the permission's target field.
-switchevents=Holders of MonitorPermission with the switchevents action present are allowed to switch event sending on or off for the value of the StatusVariables specified in the permission's target field.
-license=
-description=
-documentation=
-copyright=
-source=
-symbolicname=
-presentationname=
-id=
-version=
-url=
-size=
-provisioning.spid=The key to the provisioning information that uniquely identifies the Service Platform.
-provisioning.reference=The key to the provisioning information that contains the location of the provision data provider.
-provisioning.agent.config=The key to the provisioning information that contains the initial configuration information of the initial Management Agent.
-provisioning.update.count=The key to the provisioning information that contains the update count of the info data.
-provisioning.start.bundle=The key to the provisioning information that contains the location of the bundle to start with AllPermission.
-provisioning.rootx509=The key to the provisioning information that contains the root X509 certificate used to establish trust with operator when using HTTPS.
-provisioning.rsh.secret=The key to the provisioning information that contains the shared secret used in conjunction with the RSH protocol.
-text/plain;charset=utf-8=MIME type to be used in the InitialProvisioning-Entries header or stored in the extra field of a ZipEntry object for String data.
-application/octet-stream=MIME type to be used in the InitialProvisioning-Entries header or stored stored in the extra field of a ZipEntry object for byte[] data.
-application/vnd.osgi.bundle=MIME type to be used in the InitialProvisioning-Entries header or stored stored in the extra field of a ZipEntry object for an installable bundle file.
-application/x-osgi-bundle=Alternative MIME type to be used in the InitialProvisioning-Entries header or stored stored in the extra field of a ZipEntry object for an installable bundle file.
-text/x-osgi-bundle-url=MIME type to be stored in the extra field of a ZipEntry for a String that represents a URL for a bundle.
-InitialProvisioning-Entries=Name of the header that specifies the (MIME) type information for the ZIP file entries.
-ui1=Unsigned 1 Byte int.
-ui2=Unsigned 2 Byte int.
-ui4=Unsigned 4 Byte int.
-i1=1 Byte int.
-i2=2 Byte int.
-i4=4 Byte int.
-int=Integer number.
-r4=4 Byte float.
-r8=8 Byte float.
-number=Same as r8.
-fixed.14.4=Same as r8 but no more than 14 digits to the left of the decimal point and no more than 4 to the right.
-float=Floating-point number.
-char=Unicode string.
-string=Unicode string.
-date=A calendar date.
-dateTime=A specific instant of time.
-dateTime.tz=A specific instant of time.
-time=An instant of time that recurs every day.
-time.tz=An instant of time that recurs every day.
-boolean=True or false.
-bin.base64=MIME-style Base64 encoded binary BLOB.
-bin.hex=Hexadecimal digits representing octets.
-uri=Universal Resource Identifier.
-uuid=Universally Unique ID.
-UPnP.service.type=Property key for the optional service type uri.
-UPnP.service.id=Property key for the optional service id.
-upnp.filter=Key for a service property having a value that is an object of type org.osgi.framework.Filter and that is used to limit received events.
-UPnP=Constant for the value of the service property DEVICE_CATEGORY used for all UPnP devices.
-UPnP.export=The UPnP.export service property is a hint that marks a device to be picked up and exported by the UPnP Service.
-UPnP.device.UDN=Property key for the Unique Device Name (UDN) property.
-UPnP.device.UDN=Property key for the Unique Device ID property.
-UPnP.device.type=Property key for the UPnP Device Type property.
-UPnP.device.manufacturer=Mandatory property key for the device manufacturer's property.
-UPnP.device.modelName=Mandatory property key for the device model name.
-UPnP.device.friendlyName=Mandatory property key for a short user friendly version of the device name.
-UPnP.device.manufacturerURL=Optional property key for a URL to the device manufacturers Web site.
-UPnP.device.modelDescription=Optional (but recommended) property key for a String object with a long description of the device for the end user.
-UPnP.device.modelNumber=Optional (but recommended) property key for a String class typed property holding the model number of the device.
-UPnP.device.modelURL=Optional property key for a String typed property holding a string representing the URL to the Web site for this model.
-UPnP.device.serialNumber=Optional (but recommended) property key for a String typed property holding the serial number of the device.
-UPnP.device.UPC=Optional property key for a String typed property holding the Universal Product Code (UPC) of the device.
-UPnP.presentationURL=Optional (but recommended) property key for a String typed property holding a string representing the URL to a device representation Web page.
-UPnP.device.parentUDN=The property key that must be set for all embedded devices.
-UPnP.device.childrenUDN=The property key that must be set for all devices containing other embedded devices.
-url.handler.protocol=Service property naming the protocols serviced by a URLStreamHandlerService.
-url.content.mimetype=Service property naming the MIME types serviced by a java.net.ContentHandler.
-admin=The permission name "admin".
-changeProperty=The action string "changeProperty".
-changeCredential=The action string "changeCredential".
-getCredential=The action string "getCredential".
-user.anyone=The name of the predefined role, user.anyone, that all users and groups belong to.
-produce=The action string for the produce action.
-consume=The action string for the consume action.
-wireadmin.pid=Wire property key (named wireadmin.pid) specifying the persistent identity (PID) of this Wire object.
-wireadmin.producer.composite=A service registration property for a Producer service that is composite.
-wireadmin.consumer.composite=A service registration property for a Consumer service that is composite.
-wireadmin.producer.scope=Service registration property key (named wireadmin.producer.scope) specifying a list of names that may be used to define the scope of this Wire object.
-wireadmin.consumer.scope=Service registration property key (named wireadmin.consumer.scope) specifying a list of names that may be used to define the scope of this Wire object.
-wireadmin.producer.pid=Wire property key (named wireadmin.producer.pid) specifying the service.pid of the associated Producer service.
-wireadmin.consumer.pid=Wire property key (named wireadmin.consumer.pid) specifying the service.pid of the associated Consumer service.
-wireadmin.filter=Wire property key (named wireadmin.filter) specifying a filter used to control the delivery rate of data between the Producer and the Consumer service.
-wirevalue.current=Wire object's filter attribute (named wirevalue.current) representing the current value.
-wirevalue.previous=Wire object's filter attribute (named wirevalue.previous) representing the previous value.
-wirevalue.delta.absolute=Wire object's filter attribute (named wirevalue.delta.absolute) representing the absolute delta.
-wirevalue.delta.relative=Wire object's filter attribute (named wirevalue.delta.relative) representing the relative delta.
-wirevalue.elapsed=Wire object's filter attribute (named wirevalue.elapsed) representing the elapsed time, in ms, between this filter evaluation and the last update of the Consumer service.
-wireadmin.producer.filters=Service Registration property (named wireadmin.producer.filters).
-wireadmin.consumer.flavors=Service Registration property (named wireadmin.consumer.flavors) specifying the list of data types understood by this Consumer service.
-wireadmin.producer.flavors=Service Registration property (named wireadmin.producer.flavors) specifying the list of data types available from this Producer service.
-wireadmin.events=Service Registration property (named wireadmin.events) specifying the WireAdminEvent type of interest to a Wire Admin Listener service.
-javax.xml.parsers.SAXParserFactory=Filename containing the SAX Parser Factory Class name.
-javax.xml.parsers.DocumentBuilderFactory=Filename containing the DOM Parser Factory Class name.
-/META-INF/services/javax.xml.parsers.SAXParserFactory=Fully qualified path name of SAX Parser Factory Class Name file
-/META-INF/services/javax.xml.parsers.DocumentBuilderFactory=Fully qualified path name of DOM Parser Factory Class Name file
-parser.validating=Service property specifying if factory is configured to support validating parsers.
-parser.namespaceAware=Service property specifying if factory is configured to support namespace aware parsers.
diff --git a/bundleplugin/src/main/resources/aQute/bnd/help/syntax.xml b/bundleplugin/src/main/resources/aQute/bnd/help/syntax.xml
deleted file mode 100644
index e81df31..0000000
--- a/bundleplugin/src/main/resources/aQute/bnd/help/syntax.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-
-Bundle-Name\\s*(:|=)\\s*
\ No newline at end of file
diff --git a/bundleplugin/src/main/resources/aQute/bnd/osgi/bnd.info b/bundleplugin/src/main/resources/aQute/bnd/osgi/bnd.info
deleted file mode 100644
index ee80a6b..0000000
--- a/bundleplugin/src/main/resources/aQute/bnd/osgi/bnd.info
+++ /dev/null
@@ -1,2 +0,0 @@
-version = ${Bundle-Version}
-lastmodified = ${now}
diff --git a/bundleplugin/src/main/resources/aQute/lib/spring/extract.xsl b/bundleplugin/src/main/resources/aQute/lib/spring/extract.xsl
deleted file mode 100644
index 11726b6..0000000
--- a/bundleplugin/src/main/resources/aQute/lib/spring/extract.xsl
+++ /dev/null
@@ -1,66 +0,0 @@
-<?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" 
-	xmlns:gemini-blueprint="http://www.eclipse.org/gemini/blueprint/schema/blueprint"
-	xmlns:blueprint="http://www.osgi.org/xmlns/blueprint/v1.0.0">
-	<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
-			|	//gemini-blueprint:*/@interface
-			|   //blueprint:*/@interface
-			|   //blueprint:*/@class
-			|	//util:list/@list-class
-			|	//util:set/@set-class
-			|	//util:map/@map-class
-			|	//webflow-config:*/@class
-		">
-			<xsl:value-of select="." />
-			<xsl:text>
-			</xsl:text>
-		</xsl:for-each>
-
-		<!-- This seems some magic to get extra imports? -->
-
-		<xsl:for-each select="//beans:bean[@class='org.springframework.osgi.service.exporter.support.OsgiServiceFactoryBean'
-				or @class='org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean']">
-			<xsl:for-each select="beans:property[@name='interfaces']">
-				<xsl:value-of select="@value" />
-				<xsl:text>
-				</xsl:text>
-			</xsl:for-each>
-		</xsl:for-each>
-
-	</xsl:template>
-
-
-</xsl:stylesheet>
-
diff --git a/bundleplugin/src/main/resources/aQute/lib/spring/hibernate.xsl b/bundleplugin/src/main/resources/aQute/lib/spring/hibernate.xsl
deleted file mode 100644
index 1f0a1c6..0000000
--- a/bundleplugin/src/main/resources/aQute/lib/spring/hibernate.xsl
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jms="http://www.springframework.org/schema/jms" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:osgi-compendium="http://www.springframework.org/schema/osgi-compendium" xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:tool="http://www.springframework.org/schema/tool" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:webflow-config="http://www.springframework.org/schema/webflow-config">
-	<xsl:output method="text" />
-
-	<xsl:template match="/">
-
-		<!-- Match all attributes that holds a class or a comma delimited 
-		     list of classes and print them -->
-
-		<xsl:for-each select="//provider|//class">
-			<xsl:value-of select="." />
-			<xsl:text>
-			</xsl:text>
-		</xsl:for-each>
-	</xsl:template>
-
-
-</xsl:stylesheet>
-
diff --git a/bundleplugin/src/main/resources/aQute/lib/spring/jpa.xsl b/bundleplugin/src/main/resources/aQute/lib/spring/jpa.xsl
deleted file mode 100644
index 43bba60..0000000
--- a/bundleplugin/src/main/resources/aQute/lib/spring/jpa.xsl
+++ /dev/null
@@ -1,38 +0,0 @@
-<?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/resources/aQute/libg/asn1/algorithms b/bundleplugin/src/main/resources/aQute/libg/asn1/algorithms
deleted file mode 100644
index 4fb6ab4..0000000
--- a/bundleplugin/src/main/resources/aQute/libg/asn1/algorithms
+++ /dev/null
@@ -1,22 +0,0 @@
----------------------------------------------------------------------------
-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
