Sync with latest bnd code

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1363322 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Project.java b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
index 99c904e..06a4f8e 100644
--- a/bundleplugin/src/main/java/aQute/bnd/build/Project.java
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
@@ -16,6 +16,7 @@
 import aQute.bnd.service.*;
 import aQute.bnd.service.RepositoryPlugin.Strategy;
 import aQute.bnd.service.action.*;
+import aQute.bnd.version.*;
 import aQute.lib.io.*;
 import aQute.libg.generics.*;
 import aQute.libg.reporter.*;
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/ProjectMessages.java b/bundleplugin/src/main/java/aQute/bnd/build/ProjectMessages.java
index d265703..57367f6 100644
--- a/bundleplugin/src/main/java/aQute/bnd/build/ProjectMessages.java
+++ b/bundleplugin/src/main/java/aQute/bnd/build/ProjectMessages.java
@@ -6,6 +6,7 @@
 import aQute.bnd.osgi.*;
 import aQute.bnd.service.*;
 import aQute.bnd.service.RepositoryPlugin.Strategy;
+import aQute.bnd.version.*;
 import aQute.service.reporter.*;
 
 public interface ProjectMessages extends Messages {
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/WorkspaceRepository.java b/bundleplugin/src/main/java/aQute/bnd/build/WorkspaceRepository.java
index 99a6325..451bd77 100644
--- a/bundleplugin/src/main/java/aQute/bnd/build/WorkspaceRepository.java
+++ b/bundleplugin/src/main/java/aQute/bnd/build/WorkspaceRepository.java
@@ -6,6 +6,7 @@
 
 import aQute.bnd.osgi.*;
 import aQute.bnd.service.*;
+import aQute.bnd.version.*;
 
 public class WorkspaceRepository implements RepositoryPlugin {
 	private final Workspace	workspace;
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/BndEditModel.java b/bundleplugin/src/main/java/aQute/bnd/build/model/BndEditModel.java
index c3b550d..35cd3c6 100644
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/BndEditModel.java
+++ b/bundleplugin/src/main/java/aQute/bnd/build/model/BndEditModel.java
@@ -12,6 +12,7 @@
 import aQute.bnd.header.*;
 import aQute.bnd.osgi.*;
 import aQute.bnd.properties.*;
+import aQute.bnd.version.*;
 import aQute.libg.tuple.*;
 
 /**
@@ -26,9 +27,9 @@
 	public static final String										LINE_SEPARATOR				= " \\\n\t";
 	public static final String										LIST_SEPARATOR				= ",\\\n\t";
 
-	protected static final String									ISO_8859_1					= "ISO-8859-1";												//$NON-NLS-1$
+	private static final String									ISO_8859_1					= "ISO-8859-1";												//$NON-NLS-1$
 
-	protected static String[]										KNOWN_PROPERTIES			= new String[] {
+	private static String[]										KNOWN_PROPERTIES			= new String[] {
 			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,
@@ -46,8 +47,8 @@
 																										+ Constants.BUNDLE_VERSION
 																										+ "}";
 
-	protected final Map<String,Converter< ? extends Object,String>>	converters					= new HashMap<String,Converter< ? extends Object,String>>();
-	protected final Map<String,Converter<String, ? extends Object>>	formatters					= new HashMap<String,Converter<String, ? extends Object>>();
+	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(
@@ -60,7 +61,7 @@
 	private final Map<String,String>								changesToSave				= new HashMap<String,String>();
 
 	// CONVERTERS
-	protected Converter<List<VersionedClause>,String>				buildPathConverter			= new ClauseListConverter<VersionedClause>(
+	private Converter<List<VersionedClause>,String>				buildPathConverter			= new ClauseListConverter<VersionedClause>(
 																										new Converter<VersionedClause,Pair<String,Attrs>>() {
 																											public VersionedClause convert(
 																													Pair<String,Attrs> input)
@@ -70,7 +71,7 @@
 																														input.getSecond());
 																											}
 																										});
-	protected Converter<List<VersionedClause>,String>				buildPackagesConverter		= new ClauseListConverter<VersionedClause>(
+	private Converter<List<VersionedClause>,String>				buildPackagesConverter		= new ClauseListConverter<VersionedClause>(
 																										new Converter<VersionedClause,Pair<String,Attrs>>() {
 																											public VersionedClause convert(
 																													Pair<String,Attrs> input)
@@ -80,10 +81,10 @@
 																														input.getSecond());
 																											}
 																										});
-	protected Converter<List<VersionedClause>,String>				clauseListConverter			= new ClauseListConverter<VersionedClause>(
+	private Converter<List<VersionedClause>,String>				clauseListConverter			= new ClauseListConverter<VersionedClause>(
 																										new VersionedClauseConverter());
-	protected Converter<String,String>								stringConverter				= new NoopConverter<String>();
-	protected Converter<Boolean,String>								includedSourcesConverter	= new Converter<Boolean,String>() {
+	private Converter<String,String>								stringConverter				= new NoopConverter<String>();
+	private Converter<Boolean,String>								includedSourcesConverter	= new Converter<Boolean,String>() {
 																									public Boolean convert(
 																											String string)
 																											throws IllegalArgumentException {
@@ -91,18 +92,10 @@
 																												.valueOf(string);
 																									}
 																								};
-	protected Converter<VersionPolicy,String>						versionPolicyConverter		= new Converter<VersionPolicy,String>() {
-																									public VersionPolicy convert(
-																											String string)
-																											throws IllegalArgumentException {
-																										return VersionPolicy
-																												.parse(string);
-																									}
-																								};
-	protected Converter<List<String>,String>						listConverter				= SimpleListConverter
+	private Converter<List<String>,String>						listConverter				= SimpleListConverter
 																										.create();
-	protected Converter<List<HeaderClause>,String>					headerClauseListConverter	= new HeaderClauseListConverter();
-	protected ClauseListConverter<ExportedPackage>					exportPackageConverter		= new ClauseListConverter<ExportedPackage>(
+	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) {
@@ -111,7 +104,7 @@
 																														input.getSecond());
 																											}
 																										});
-	protected Converter<List<ServiceComponent>,String>				serviceComponentConverter	= new ClauseListConverter<ServiceComponent>(
+	private Converter<List<ServiceComponent>,String>				serviceComponentConverter	= new ClauseListConverter<ServiceComponent>(
 																										new Converter<ServiceComponent,Pair<String,Attrs>>() {
 																											public ServiceComponent convert(
 																													Pair<String,Attrs> input)
@@ -121,7 +114,7 @@
 																														input.getSecond());
 																											}
 																										});
-	protected Converter<List<ImportPattern>,String>					importPatternConverter		= new ClauseListConverter<ImportPattern>(
+	private Converter<List<ImportPattern>,String>					importPatternConverter		= new ClauseListConverter<ImportPattern>(
 																										new Converter<ImportPattern,Pair<String,Attrs>>() {
 																											public ImportPattern convert(
 																													Pair<String,Attrs> input)
@@ -132,38 +125,38 @@
 																											}
 																										});
 
-	protected Converter<Map<String,String>,String>					propertiesConverter			= new PropertiesConverter();
+	private Converter<Map<String,String>,String>					propertiesConverter			= new PropertiesConverter();
 	
-	protected Converter<List<Requirement>,String>					requirementListConverter	= new RequirementListConverter();
-	protected Converter<EE,String>									eeConverter					= new EEConverter();
+	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
-	protected Converter<String,Object>								defaultFormatter			= new DefaultFormatter();
-	protected Converter<String,String>								newlineEscapeFormatter		= new NewlineEscapedStringFormatter();
-	protected Converter<String,Boolean>								defaultFalseBoolFormatter	= new DefaultBooleanFormatter(
+	private Converter<String,Object>								defaultFormatter			= new DefaultFormatter();
+	private Converter<String,String>								newlineEscapeFormatter		= new NewlineEscapedStringFormatter();
+	private Converter<String,Boolean>								defaultFalseBoolFormatter	= new DefaultBooleanFormatter(
 																										false);
-	protected Converter<String,Collection< ? >>						stringListFormatter			= new CollectionFormatter<Object>(
+	private Converter<String,Collection< ? >>						stringListFormatter			= new CollectionFormatter<Object>(
 																										LIST_SEPARATOR,
 																										(String) null);
-	protected Converter<String,Collection< ? extends HeaderClause>>	headerClauseListFormatter	= new CollectionFormatter<HeaderClause>(
+	private Converter<String,Collection< ? extends HeaderClause>>	headerClauseListFormatter	= new CollectionFormatter<HeaderClause>(
 																										LIST_SEPARATOR,
 																										new HeaderClauseFormatter(),
 																										null);
-	protected Converter<String,Map<String,String>>					propertiesFormatter			= new MapFormatter(
+	private Converter<String,Map<String,String>>					propertiesFormatter			= new MapFormatter(
 																										LIST_SEPARATOR,
 																										new PropertiesEntryFormatter(),
 																										null);
 	
-	protected Converter<String,Collection< ? extends Requirement>>	requirementListFormatter	= new CollectionFormatter<Requirement>(
+	private Converter<String,Collection< ? extends Requirement>>	requirementListFormatter	= new CollectionFormatter<Requirement>(
 																										LIST_SEPARATOR,
 																										new RequirementFormatter(),
 																										null);
 
-	protected Converter<String,EE>									eeFormatter					= new EEFormatter();
-	Converter<String,Collection< ? extends String>>					runReposFormatter			= new CollectionFormatter<String>(
+	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);
 
@@ -267,7 +260,7 @@
 		}
 	}
 
-	protected static IRegion findEntry(IDocument document, String name) throws Exception {
+	private static IRegion findEntry(IDocument document, String name) throws Exception {
 		PropertiesLineReader reader = new PropertiesLineReader(document);
 		LineType type = reader.next();
 		while (type != LineType.eof) {
@@ -281,7 +274,7 @@
 		return null;
 	}
 
-	protected static void updateDocument(IDocument document, String name, String value) {
+	private static void updateDocument(IDocument document, String name, String value) {
 		String newEntry;
 		if (value != null) {
 			StringBuilder buffer = new StringBuilder();
@@ -642,7 +635,7 @@
     }
 
 
-	protected <R> R doGetObject(String name, Converter< ? extends R, ? super String> converter) {
+	private <R> R doGetObject(String name, Converter< ? extends R, ? super String> converter) {
 		R result;
 		if (objectProperties.containsKey(name)) {
 			R temp = (R) objectProperties.get(name);
@@ -659,7 +652,7 @@
 		return result;
 	}
 
-	protected <T> void doSetObject(String name, T oldValue, T newValue, Converter<String, ? super T> formatter) {
+	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);
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/LowerVersionMatchType.java b/bundleplugin/src/main/java/aQute/bnd/build/model/LowerVersionMatchType.java
deleted file mode 100644
index 679d874..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/LowerVersionMatchType.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package aQute.bnd.build.model;
-
-public enum LowerVersionMatchType {
-	Exact("${@}"), Micro("${version;===;${@}}"), Minor("${version;==;${@}}"), Major("${version;=;${@}}");
-
-	private final String	representation;
-
-	private LowerVersionMatchType(String representation) {
-		this.representation = representation;
-	}
-
-	public String getRepresentation() {
-		return representation;
-	}
-
-	public static LowerVersionMatchType parse(String string) throws IllegalArgumentException {
-		for (LowerVersionMatchType type : LowerVersionMatchType.class.getEnumConstants()) {
-			if (type.getRepresentation().equals(string)) {
-				return type;
-			}
-		}
-		throw new IllegalArgumentException("Failed to parse version match type.");
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/UpperVersionMatchType.java b/bundleplugin/src/main/java/aQute/bnd/build/model/UpperVersionMatchType.java
deleted file mode 100644
index 89a4597..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/UpperVersionMatchType.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package aQute.bnd.build.model;
-
-public enum UpperVersionMatchType {
-	Exact("${@}"), NextMicro("${version;==+;${@}}"), NextMinor("${version;=+;${@}}"), NextMajor("${version;+;${@}}");
-
-	private final String	representation;
-
-	private UpperVersionMatchType(String representation) {
-		this.representation = representation;
-	}
-
-	public String getRepresentation() {
-		return representation;
-	}
-
-	public static UpperVersionMatchType parse(String string) throws IllegalArgumentException {
-		for (UpperVersionMatchType type : UpperVersionMatchType.class.getEnumConstants()) {
-			if (type.getRepresentation().equals(string)) {
-				return type;
-			}
-		}
-		throw new IllegalArgumentException("Failed to parse version match type.");
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/VersionPolicy.java b/bundleplugin/src/main/java/aQute/bnd/build/model/VersionPolicy.java
deleted file mode 100644
index af1b96f..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/VersionPolicy.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package aQute.bnd.build.model;
-
-public class VersionPolicy {
-	private final LowerVersionMatchType	lowerMatch;
-	private final UpperVersionMatchType	upperMatch;
-	private final boolean				upperInclusive;
-
-	public VersionPolicy(LowerVersionMatchType lowerMatch, UpperVersionMatchType upperMatch, boolean upperInclusive) {
-		assert lowerMatch != null;
-		this.lowerMatch = lowerMatch;
-		this.upperMatch = upperMatch;
-		this.upperInclusive = upperInclusive;
-	}
-
-	static VersionPolicy parse(String string) throws IllegalArgumentException {
-		String lowerSegment;
-		String upperSegment;
-		boolean upperInclusive;
-
-		if (string.charAt(0) == '[') {
-			int commaIndex = string.indexOf(',');
-			if (commaIndex < 0)
-				throw new IllegalArgumentException("Failed to parse version policy.");
-			lowerSegment = string.substring(1, commaIndex);
-
-			char lastChar = string.charAt(string.length() - 1);
-			if (lastChar == ')')
-				upperInclusive = false;
-			else if (lastChar == ']')
-				upperInclusive = true;
-			else
-				throw new IllegalArgumentException("Failed to parse version policy.");
-
-			upperSegment = string.substring(commaIndex + 1, string.length() - 1);
-		} else {
-			lowerSegment = string;
-			upperSegment = null;
-			upperInclusive = true;
-		}
-
-		LowerVersionMatchType lower = LowerVersionMatchType.parse(lowerSegment);
-		UpperVersionMatchType upper = upperSegment != null ? UpperVersionMatchType.parse(upperSegment) : null;
-
-		return new VersionPolicy(lower, upper, upperInclusive);
-	}
-
-	public LowerVersionMatchType getLowerMatch() {
-		return lowerMatch;
-	}
-
-	public UpperVersionMatchType getUpperMatch() {
-		return upperMatch;
-	}
-
-	public boolean isUpperInclusive() {
-		return upperInclusive;
-	}
-
-	@Override
-	public String toString() {
-		StringBuilder buffer = new StringBuilder();
-
-		if (upperMatch != null) {
-			buffer.append('[');
-			buffer.append(lowerMatch.getRepresentation());
-			buffer.append(',');
-			buffer.append(upperMatch.getRepresentation());
-			buffer.append(upperInclusive ? ']' : ')');
-		} else {
-			buffer.append(lowerMatch.getRepresentation());
-		}
-
-		return buffer.toString();
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/packageinfo b/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/packageinfo
deleted file mode 100644
index 55af8e5..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/build/model/conversions/packageinfo
+++ /dev/null
@@ -1 +0,0 @@
-version 2
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java b/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java
index 989fdc9..a452c9f 100644
--- a/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java
+++ b/bundleplugin/src/main/java/aQute/bnd/component/AnnotationReader.java
@@ -9,6 +9,7 @@
 import aQute.bnd.osgi.*;
 import aQute.bnd.osgi.Clazz.MethodDef;
 import aQute.bnd.osgi.Descriptors.TypeRef;
+import aQute.bnd.version.*;
 import aQute.lib.collections.*;
 
 /**
@@ -26,7 +27,7 @@
 public class AnnotationReader extends ClassDataCollector {
 	final static TypeRef[]		EMPTY					= new TypeRef[0];
 	final static Pattern		PROPERTY_PATTERN		= Pattern
-																.compile("\\s*([^=]+(\\s*:\\s*(Boolean|Byte|Char|Short|Integer|Long|Float|Double|String))?)\\s*=(.*)");
+																.compile("\\s*([^=\\s:]+)\\s*(?::\\s*(Boolean|Byte|Char|Short|Integer|Long|Float|Double|String)\\s*)?=(.*)");
 
 	public static final Version	V1_1					= new Version("1.1.0");																												// "1.1.0"
 	public static final Version	V1_2					= new Version("1.2.0");																												// "1.1.0"
@@ -308,7 +309,11 @@
 
 				if (m.matches()) {
 					String key = m.group(1);
-					String value = m.group(4);
+					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);
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/ComponentDef.java b/bundleplugin/src/main/java/aQute/bnd/component/ComponentDef.java
index 98f7d36..1054896 100644
--- a/bundleplugin/src/main/java/aQute/bnd/component/ComponentDef.java
+++ b/bundleplugin/src/main/java/aQute/bnd/component/ComponentDef.java
@@ -7,6 +7,7 @@
 
 import aQute.bnd.osgi.*;
 import aQute.bnd.osgi.Descriptors.TypeRef;
+import aQute.bnd.version.*;
 import aQute.lib.collections.*;
 import aQute.lib.tag.*;
 
@@ -183,6 +184,9 @@
 			return v;
 
 		try {
+			if ( type.equals("Char"))
+				type = "Character";
+			
 			Class< ? > c = Class.forName("java.lang." + type);
 			if (c == String.class)
 				return v;
diff --git a/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java b/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java
index 6c64fe0..8830084 100644
--- a/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java
+++ b/bundleplugin/src/main/java/aQute/bnd/component/ReferenceDef.java
@@ -3,6 +3,7 @@
 import org.osgi.service.component.annotations.*;
 
 import aQute.bnd.osgi.*;
+import aQute.bnd.version.*;
 import aQute.lib.tag.*;
 
 /**
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/Baseline.java b/bundleplugin/src/main/java/aQute/bnd/differ/Baseline.java
index b5eabb5..fe79c7d 100644
--- a/bundleplugin/src/main/java/aQute/bnd/differ/Baseline.java
+++ b/bundleplugin/src/main/java/aQute/bnd/differ/Baseline.java
@@ -8,6 +8,7 @@
 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.*;
 
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/JavaElement.java b/bundleplugin/src/main/java/aQute/bnd/differ/JavaElement.java
index 0be044b..99ccdd2 100644
--- a/bundleplugin/src/main/java/aQute/bnd/differ/JavaElement.java
+++ b/bundleplugin/src/main/java/aQute/bnd/differ/JavaElement.java
@@ -17,9 +17,9 @@
 import aQute.bnd.osgi.Clazz.MethodDef;
 import aQute.bnd.osgi.Descriptors.PackageRef;
 import aQute.bnd.osgi.Descriptors.TypeRef;
-import aQute.bnd.osgi.Version;
 import aQute.bnd.service.diff.*;
 import aQute.bnd.service.diff.Type;
+import aQute.bnd.version.Version;
 import aQute.lib.collections.*;
 import aQute.libg.generics.*;
 
diff --git a/bundleplugin/src/main/java/aQute/bnd/differ/RepositoryElement.java b/bundleplugin/src/main/java/aQute/bnd/differ/RepositoryElement.java
index 5577e0e..0145149 100644
--- a/bundleplugin/src/main/java/aQute/bnd/differ/RepositoryElement.java
+++ b/bundleplugin/src/main/java/aQute/bnd/differ/RepositoryElement.java
@@ -5,6 +5,7 @@
 import aQute.bnd.osgi.*;
 import aQute.bnd.service.*;
 import aQute.bnd.service.diff.*;
+import aQute.bnd.version.*;
 
 public class RepositoryElement {
 
diff --git a/bundleplugin/src/main/java/aQute/bnd/filerepo/FileRepo.java b/bundleplugin/src/main/java/aQute/bnd/filerepo/FileRepo.java
index c0113ac..4f5a436 100644
--- a/bundleplugin/src/main/java/aQute/bnd/filerepo/FileRepo.java
+++ b/bundleplugin/src/main/java/aQute/bnd/filerepo/FileRepo.java
@@ -5,6 +5,7 @@
 import java.util.regex.*;
 
 import aQute.bnd.osgi.*;
+import aQute.bnd.version.*;
 
 public class FileRepo {
 	File	root;
diff --git a/bundleplugin/src/main/java/aQute/bnd/header/Attrs.java b/bundleplugin/src/main/java/aQute/bnd/header/Attrs.java
index 8daaee7..0124ff1 100644
--- a/bundleplugin/src/main/java/aQute/bnd/header/Attrs.java
+++ b/bundleplugin/src/main/java/aQute/bnd/header/Attrs.java
@@ -4,6 +4,7 @@
 import java.util.regex.*;
 
 import aQute.bnd.osgi.*;
+import aQute.bnd.version.*;
 import aQute.lib.collections.*;
 
 public class Attrs implements Map<String,String> {
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java b/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java
index d081bb9..5143bd8 100644
--- a/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java
+++ b/bundleplugin/src/main/java/aQute/bnd/make/component/ComponentAnnotationReader.java
@@ -256,7 +256,7 @@
 		return Modifier.isPublic(method.getAccess()) || Modifier.isProtected(method.getAccess());
 	}
 
-	static Pattern	PROPERTY_PATTERN	= Pattern.compile("\\s*([^=\\s])+\\s*=(.+)");
+	static Pattern	PROPERTY_PATTERN	= Pattern.compile("\\s*([^=\\s]+)\\s*=(.+)");
 
 	private void doProperties(aQute.bnd.osgi.Annotation annotation) {
 		Object[] properties = annotation.get(Component.PROPERTIES);
diff --git a/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java b/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java
index 89c36be..06946ab 100644
--- a/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java
+++ b/bundleplugin/src/main/java/aQute/bnd/make/component/ServiceComponent.java
@@ -12,6 +12,7 @@
 import aQute.bnd.osgi.Clazz.QUERY;
 import aQute.bnd.osgi.Descriptors.TypeRef;
 import aQute.bnd.service.*;
+import aQute.bnd.version.*;
 
 /**
  * This class is an analyzer plugin. It looks at the properties and tries to
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/MavenRepository.java b/bundleplugin/src/main/java/aQute/bnd/maven/MavenRepository.java
index 2f55a07..7a6ff20 100644
--- a/bundleplugin/src/main/java/aQute/bnd/maven/MavenRepository.java
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/MavenRepository.java
@@ -6,6 +6,7 @@
 
 import aQute.bnd.osgi.*;
 import aQute.bnd.service.*;
+import aQute.bnd.version.*;
 import aQute.service.reporter.*;
 
 public class MavenRepository implements RepositoryPlugin, Plugin, BsnToMavenPath {
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java b/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java
index 66954e0..33d9d44 100644
--- a/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/PomFromManifest.java
@@ -8,6 +8,7 @@
 
 import aQute.bnd.header.*;
 import aQute.bnd.osgi.*;
+import aQute.bnd.version.*;
 import aQute.lib.io.*;
 import aQute.lib.tag.*;
 
diff --git a/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenRemoteRepository.java b/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenRemoteRepository.java
index 0cce3b3..93f169b 100644
--- a/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenRemoteRepository.java
+++ b/bundleplugin/src/main/java/aQute/bnd/maven/support/MavenRemoteRepository.java
@@ -6,6 +6,7 @@
 
 import aQute.bnd.osgi.*;
 import aQute.bnd.service.*;
+import aQute.bnd.version.*;
 import aQute.lib.io.*;
 import aQute.service.reporter.*;
 
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
index 09c494f..d4e68ce 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Analyzer.java
@@ -35,6 +35,7 @@
 import aQute.bnd.osgi.Descriptors.PackageRef;
 import aQute.bnd.osgi.Descriptors.TypeRef;
 import aQute.bnd.service.*;
+import aQute.bnd.version.Version;
 import aQute.lib.base64.*;
 import aQute.lib.collections.*;
 import aQute.lib.filter.*;
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Builder.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Builder.java
index a5bb7f6..d6fa2ba 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Builder.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Builder.java
@@ -117,6 +117,8 @@
 		dot.updateModified(lastModified(), "Last Modified Processor");
 		dot.setName(getBsn());
 
+		doDigests(dot);
+		
 		sign(dot);
 		doSaveManifest(dot);
 
@@ -138,7 +140,7 @@
 			return;
 		trace("digests %s", ps);
 		String[] digests = ps.keySet().toArray(new String[ps.size()]);
-		dot.calcChecksums(digests);
+		dot.setDigestAlgorithms(digests);
 	}
 
 	/**
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Domain.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Domain.java
index 828f1cf..bf7a31b 100644
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Domain.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Domain.java
@@ -7,6 +7,7 @@
 import java.util.jar.*;
 
 import aQute.bnd.header.*;
+import aQute.bnd.version.*;
 import aQute.lib.converter.*;
 import aQute.service.reporter.*;
 
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java
index b864297..11c0dab 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Jar.java
@@ -34,6 +34,7 @@
 	boolean									nomanifest;
 	Compression								compression	= Compression.DEFLATE;
 	boolean									closed;
+	String[]								algorithms;
 
 	public Jar(String name) {
 		this.name = name;
@@ -241,6 +242,40 @@
 
 	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) {
@@ -278,6 +313,7 @@
 			return;
 
 		JarEntry ze = new JarEntry("META-INF/MANIFEST.MF");
+
 		jout.putNextEntry(ze);
 		writeManifest(jout);
 		jout.closeEntry();
@@ -810,4 +846,8 @@
 			din.close();
 		}
 	}
+
+	public void setDigestAlgorithms(String[] algorithms) {
+		this.algorithms = algorithms;
+	}
 }
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java b/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
index f8474f4..4ac92d0 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/Macro.java
@@ -7,6 +7,7 @@
 import java.util.*;
 import java.util.regex.*;
 
+import aQute.bnd.version.*;
 import aQute.lib.collections.*;
 import aQute.lib.io.*;
 
@@ -230,7 +231,7 @@
 				if (e.getCause() instanceof IllegalArgumentException) {
 					domain.error("%s, for cmd: %s, arguments; %s", e.getMessage(), method, Arrays.toString(args));
 				} else {
-					domain.warning("Exception in replace: " + e.getCause());
+					domain.warning("Exception in replace: %s", e.getCause());
 					e.getCause().printStackTrace();
 				}
 			}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/TagResource.java b/bundleplugin/src/main/java/aQute/bnd/osgi/TagResource.java
deleted file mode 100644
index 183f1cd..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/TagResource.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package aQute.bnd.osgi;
-
-import java.io.*;
-
-import aQute.lib.tag.*;
-
-public class TagResource extends WriteResource {
-	final Tag	tag;
-
-	public TagResource(Tag tag) {
-		this.tag = tag;
-	}
-
-	public void write(OutputStream out) throws UnsupportedEncodingException {
-		OutputStreamWriter ow = new OutputStreamWriter(out, "UTF-8");
-		PrintWriter pw = new PrintWriter(ow);
-		pw.println("<?xml version='1.1'?>");
-		try {
-			tag.print(0, pw);
-		}
-		finally {
-			pw.flush();
-		}
-	}
-
-	public long lastModified() {
-		return 0;
-	}
-
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/Filters.java b/bundleplugin/src/main/java/aQute/bnd/osgi/resource/Filters.java
index 3194146..b8c7836 100644
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/resource/Filters.java
+++ b/bundleplugin/src/main/java/aQute/bnd/osgi/resource/Filters.java
@@ -3,6 +3,7 @@
 import org.osgi.framework.namespace.*;
 
 import aQute.bnd.osgi.*;
+import aQute.bnd.version.*;
 import aQute.libg.filters.*;
 
 public class Filters {
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/PropertiesReader.java b/bundleplugin/src/main/java/aQute/bnd/properties/PropertiesReader.java
deleted file mode 100644
index 10d7f4a..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/properties/PropertiesReader.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package aQute.bnd.properties;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.lib.io.*;
-
-public class PropertiesReader {
-	static Pattern	PROPERTY	= Pattern.compile("(\\s*#.*$)|(([^\\s]+)\\s*[:=]?\\s*([^#])(#.*)$)|\\s+([^#]*)(#.*)$)",
-										Pattern.MULTILINE);
-
-	public static Properties read(Properties p, File f) throws Exception {
-		return read(p, IO.reader(f));
-	}
-
-	public static Properties read(Properties p, InputStream in, String charset) throws IOException {
-		return read(p, IO.reader(in, charset));
-	}
-
-	public static Properties read(Properties p, InputStream in) throws IOException {
-		return read(p, IO.reader(in));
-	}
-
-	public static Properties read(Properties p, URL in) throws IOException {
-		return read(p, IO.reader(in.openStream()));
-	}
-
-	private static Properties read(Properties p, BufferedReader reader) throws IOException {
-		if (p != null)
-			p = new Properties();
-
-		String line = reader.readLine();
-		String key = null;
-		StringBuilder value = new StringBuilder();
-
-		while (line != null) {
-			Matcher m = PROPERTY.matcher(line);
-			if (m.matches()) {
-
-				if (m.group(1) != null)
-					continue; // comment line
-
-				if (m.group(2) != null) {
-					// header
-					if (key != null) {
-						cleanup(value);
-						p.put(key.toString(), value.toString());
-						key = null;
-						value.delete(0, value.length());
-					}
-					key = m.group(3);
-					value.append(m.group(4));
-				} else {
-					value.append(m.group(6));
-				}
-			} else {
-				System.out.println("Assume empty: " + line);
-			}
-			line = reader.readLine();
-		}
-		if (key != null) {
-			cleanup(value);
-			p.put(key.toString(), value.toString());
-		}
-		return p;
-	}
-
-	private static void cleanup(StringBuilder value) {
-		for (int i = 0; i < value.length(); i++) {
-			if (value.charAt(i) == '\\') {
-				value.deleteCharAt(i);
-				if (i < value.length()) {
-					char c = value.charAt(i);
-					switch (c) {
-						case 't' :
-							value.setCharAt(i, '\t');
-							break;
-						case 'r' :
-							value.setCharAt(i, '\r');
-							break;
-						case 'n' :
-							value.setCharAt(i, '\n');
-							break;
-						case 'f' :
-							value.setCharAt(i, '\f');
-							break;
-						case 'b' :
-							value.setCharAt(i, '\b');
-							break;
-
-						case 'u' :
-							if (i + 5 >= value.length())
-								throw new IllegalArgumentException("Invalid unicode escape " + value.substring(i));
-
-							String n = value.substring(i + 1, i + 5);
-							try {
-								int code = Integer.valueOf(n, 16);
-								value.delete(i + 1, i + 5);
-								value.setCharAt(i, (char) code);
-							}
-							catch (Exception e) {
-								throw new IllegalArgumentException("Invalid unicode escape " + value.substring(i));
-							}
-							break;
-						default :
-							throw new IllegalArgumentException("Invalid  escape " + value);
-					}
-				}
-
-			}
-		}
-	}
-}
diff --git a/bundleplugin/src/main/java/aQute/bnd/properties/packageinfo b/bundleplugin/src/main/java/aQute/bnd/properties/packageinfo
index a4f1546..7a6a5c0 100644
--- a/bundleplugin/src/main/java/aQute/bnd/properties/packageinfo
+++ b/bundleplugin/src/main/java/aQute/bnd/properties/packageinfo
@@ -1 +1 @@
-version 1.0
\ No newline at end of file
+version 2.0
\ No newline at end of file
diff --git a/bundleplugin/src/main/java/aQute/bnd/repo/eclipse/EclipseRepo.java b/bundleplugin/src/main/java/aQute/bnd/repo/eclipse/EclipseRepo.java
index 1f3bfdc..e40d179 100644
--- a/bundleplugin/src/main/java/aQute/bnd/repo/eclipse/EclipseRepo.java
+++ b/bundleplugin/src/main/java/aQute/bnd/repo/eclipse/EclipseRepo.java
@@ -8,6 +8,7 @@
 import aQute.bnd.header.*;
 import aQute.bnd.osgi.*;
 import aQute.bnd.service.*;
+import aQute.bnd.version.*;
 import aQute.lib.io.*;
 import aQute.libg.generics.*;
 import aQute.service.reporter.*;
diff --git a/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java b/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java
index 769238c..772803d 100644
--- a/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java
+++ b/bundleplugin/src/main/java/aQute/bnd/service/RepositoryPlugin.java
@@ -4,6 +4,7 @@
 import java.util.*;
 
 import aQute.bnd.osgi.*;
+import aQute.bnd.version.*;
 
 public interface RepositoryPlugin {
 	public enum Strategy {
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/Version.java b/bundleplugin/src/main/java/aQute/bnd/version/Version.java
similarity index 98%
rename from bundleplugin/src/main/java/aQute/bnd/osgi/Version.java
rename to bundleplugin/src/main/java/aQute/bnd/version/Version.java
index 951ad25..359a66d 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/Version.java
+++ b/bundleplugin/src/main/java/aQute/bnd/version/Version.java
@@ -1,4 +1,4 @@
-package aQute.bnd.osgi;
+package aQute.bnd.version;
 
 import java.util.regex.*;
 
diff --git a/bundleplugin/src/main/java/aQute/bnd/osgi/VersionRange.java b/bundleplugin/src/main/java/aQute/bnd/version/VersionRange.java
similarity index 98%
rename from bundleplugin/src/main/java/aQute/bnd/osgi/VersionRange.java
rename to bundleplugin/src/main/java/aQute/bnd/version/VersionRange.java
index 8ff69a3..0761616 100755
--- a/bundleplugin/src/main/java/aQute/bnd/osgi/VersionRange.java
+++ b/bundleplugin/src/main/java/aQute/bnd/version/VersionRange.java
@@ -1,4 +1,4 @@
-package aQute.bnd.osgi;
+package aQute.bnd.version;
 
 import java.util.*;
 import java.util.regex.*;
diff --git a/bundleplugin/src/main/java/aQute/bnd/version/packageinfo b/bundleplugin/src/main/java/aQute/bnd/version/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/version/packageinfo
@@ -0,0 +1 @@
+version 1.0