diff --git a/bundleplugin/src/main/java/aQute/bnd/obr/OBRFragment.java b/bundleplugin/src/main/java/aQute/bnd/obr/OBRFragment.java
deleted file mode 100644
index 1af3518..0000000
--- a/bundleplugin/src/main/java/aQute/bnd/obr/OBRFragment.java
+++ /dev/null
@@ -1,300 +0,0 @@
-package aQute.bnd.obr;
-
-import java.io.*;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.jar.*;
-import java.util.regex.*;
-
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
-import org.osgi.framework.namespace.*;
-import org.osgi.namespace.service.*;
-import org.osgi.resource.*;
-import org.osgi.service.repository.*;
-
-import aQute.bnd.header.*;
-import aQute.bnd.osgi.*;
-import aQute.bnd.osgi.resource.*;
-import aQute.bnd.version.*;
-import aQute.libg.cryptography.*;
-import aQute.libg.map.*;
-import aQute.service.reporter.*;
-
-public class OBRFragment {
-
-	// The mime-type of an OSGi bundle
-	static final String	MIME_TYPE_OSGI_BUNDLE	= "application/vnd.osgi.bundle";
-static Pattern EE_PATTERN = Pattern.compile("[^.]-([\\d]+(?:\\.[\\d]+(?:\\.[\\d]+(?:\\.)?)?)?)");
-
-	@SuppressWarnings("deprecation")
-	public static Reporter parse(Jar jar, ResourceBuilder resource) throws Exception {
-		Manifest m = jar.getManifest();
-		if (m == null)
-			return null;
-
-		Domain d = Domain.domain(m);
-		d.setTranslation(jar);
-		Entry<String,Attrs> bundleSymbolicName = d.getBundleSymbolicName();
-
-		if (bundleSymbolicName == null)
-			return null;
-
-		boolean singleton = "true".equals(bundleSymbolicName.getValue().get(Constants.SINGLETON_DIRECTIVE + ":"));
-		boolean isFragment = d.get(Constants.FRAGMENT_HOST) != null;
-		Version version = d.getBundleVersion() == null ? Version.emptyVersion : new Version(d.getBundleVersion());
-		
-		CapReqBuilder identity = new CapReqBuilder(IdentityNamespace.IDENTITY_NAMESPACE);
-		identity.addAttribute(IdentityNamespace.IDENTITY_NAMESPACE, bundleSymbolicName.getKey());
-		identity.addAttribute(IdentityNamespace.CAPABILITY_COPYRIGHT_ATTRIBUTE, d.translate(Constants.BUNDLE_COPYRIGHT));
-		identity.addAttribute(IdentityNamespace.CAPABILITY_DESCRIPTION_ATTRIBUTE,
-				d.translate(Constants.BUNDLE_DESCRIPTION));
-		identity.addAttribute(IdentityNamespace.CAPABILITY_DOCUMENTATION_ATTRIBUTE,
-				d.translate(Constants.BUNDLE_DOCURL));
-		identity.addAttribute(IdentityNamespace.CAPABILITY_LICENSE_ATTRIBUTE, d.translate("Bundle-License"));
-		if (singleton)
-			identity.addAttribute(IdentityNamespace.CAPABILITY_SINGLETON_DIRECTIVE, "true");
-		identity.addAttribute(IdentityNamespace.CAPABILITY_TYPE_ATTRIBUTE,
-				isFragment ? IdentityNamespace.TYPE_FRAGMENT
-						: IdentityNamespace.TYPE_BUNDLE);
-		identity.addAttribute(IdentityNamespace.CAPABILITY_VERSION_ATTRIBUTE, new Version(d.getBundleVersion()));
-
-		resource.addCapability(identity);
-
-		
-		if ( isFragment ) {
-			
-			//
-			// Fragment-Host
-			//
-
-			Entry<String,Attrs> fragmentHost = d.getFragmentHost();
-			CapReqBuilder fragment = new CapReqBuilder(HostNamespace.HOST_NAMESPACE);
-			String v = fragmentHost.getValue().get("version");
-			if ( v == null)
-				v = "0";
-			Version fragmentVersion = new Version(v);
-			String filter = filter(PackageNamespace.PACKAGE_NAMESPACE, fragmentHost.getKey(), fragmentHost.getValue());
-			fragment.addDirective(HostNamespace.REQUIREMENT_FILTER_DIRECTIVE, filter.toString());
-			resource.addRequirement(fragment);
-		} else {
-			
-			//
-			// Bundle-SymbolicName
-			//
-			
-			CapReqBuilder bundle = new CapReqBuilder(BundleNamespace.BUNDLE_NAMESPACE);
-			CapReqBuilder host = new CapReqBuilder(HostNamespace.HOST_NAMESPACE);
-			
-			bundle.addAttribute("version", version);
-			host.addAttribute("version", version);
-			
-			for (Entry<String,String> e : bundleSymbolicName.getValue().entrySet()) {
-				String key = e.getKey();
-				if (key.endsWith(":")) {
-					String directive = key.substring(0, key.length() - 1);
-					if (Constants.FRAGMENT_ATTACHMENT_DIRECTIVE.equalsIgnoreCase(directive)) {
-						if (Constants.FRAGMENT_ATTACHMENT_NEVER.equalsIgnoreCase(e.getValue()))
-							host = null;
-						
-					} else if (!Constants.SINGLETON_DIRECTIVE.equalsIgnoreCase(directive)) {
-						bundle.addDirective(directive, e.getValue());
-					}
-					if ( host != null )
-						host.addDirective(directive, e.getValue());
-					bundle.addDirective(directive, e.getValue());					
-				} else {
-					if ( host != null )
-						host.addAttribute(key, e.getValue());
-					bundle.addAttribute(key, e.getValue());
-				}
-			}
-			if ( host != null)
-				resource.addCapability(host);
-			resource.addCapability(bundle);
-		}		
-		
-		//
-		// Export-Package
-		//
-		
-		Parameters exports = d.getExportPackage();		
-		for (Entry<String,Attrs> entry : exports.entrySet()) {
-			CapReqBuilder exported = new CapReqBuilder(PackageNamespace.PACKAGE_NAMESPACE);
-
-			String pkgName = Processor.removeDuplicateMarker(entry.getKey());
-			exported.addAttribute(PackageNamespace.PACKAGE_NAMESPACE, pkgName);
-
-			String versionStr = entry.getValue().get(Constants.VERSION_ATTRIBUTE);
-			Version v = Version.parseVersion(entry.getValue().get("version"));
-			
-			exported.addAttribute(PackageNamespace.CAPABILITY_VERSION_ATTRIBUTE, version);
-
-			for (Entry<String,String> attribEntry : entry.getValue().entrySet()) {
-				String key = attribEntry.getKey();
-				if (key.endsWith(":")) {
-					String directive = key.substring(0, key.length()-1);
-					exported.addDirective(directive, attribEntry.getValue());
-				} else {
-					if ( key.equals("specification-version") || key.equals("version"))
-						exported.addAttribute("version",  Version.parseVersion(attribEntry.getValue()));
-					else
-						exported.addAttribute(key, attribEntry.getValue());
-				}
-			}
-
-			exported.addAttribute(PackageNamespace.CAPABILITY_BUNDLE_SYMBOLICNAME_ATTRIBUTE, bundleSymbolicName.getKey());
-			exported.addAttribute(PackageNamespace.CAPABILITY_BUNDLE_VERSION_ATTRIBUTE, version);
-
-			resource.addCapability(exported);
-		}
-
-		//
-		// Import-Package
-		//
-		
-		Parameters imports = d.getImportPackage();		
-		for (Entry<String,Attrs> entry : imports.entrySet()) {
-			CapReqBuilder imported = new CapReqBuilder(PackageNamespace.PACKAGE_NAMESPACE);
-			String name = Processor.removeDuplicateMarker(entry.getKey());
-			String filter = filter(PackageNamespace.PACKAGE_NAMESPACE, Processor.removeDuplicateMarker(entry.getKey()), entry.getValue());
-			imported.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter);			
-			resource.addRequirement(imported);
-		}
-
-		//
-		// Require-Bundle
-		//
-		
-		Parameters requires = d.getRequireBundle();
-		for (Entry<String,Attrs> entry : requires.entrySet()) {
-			CapReqBuilder req = new CapReqBuilder(BundleNamespace.BUNDLE_NAMESPACE);
-			String bsn = Processor.removeDuplicateMarker(entry.getKey());
-			String filter = filter(BundleNamespace.BUNDLE_NAMESPACE, bsn, entry.getValue());
-			req.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter);			
-			resource.addRequirement(req);
-		}
-
-		//
-		// Bundle-RequiredExecutionEnvironment
-		//
-		
-		Parameters brees = d.getBundleRequiredExecutionEnvironment();
-		Formatter formatter = new Formatter();
-			formatter.format("(|");
-		
-		for ( Entry<String,Attrs> bree : brees.entrySet()	) {
-			String name = Processor.removeDuplicateMarker(bree.getKey());
-			Matcher matcher = EE_PATTERN.matcher(name);
-			if ( matcher.matches()) {
-				name = matcher.group(1);
-				Version v = Version.parseVersion(matcher.group(2));
-				formatter.format("%s", filter(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE, name, MAP.$("version", v.toString())));
-			}
-		}
-		formatter.format(")");
-		
-		CapReqBuilder breeReq = new CapReqBuilder(ExecutionEnvironmentNamespace.EXECUTION_ENVIRONMENT_NAMESPACE);
-		breeReq.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, formatter.toString());
-
-		//
-		// Export-Service (deprecated)
-		//
-		
-		for (Entry<String,Attrs> export : d.getParameters(Constants.EXPORT_SERVICE).entrySet()) {
-			CapReqBuilder	exportedService = new CapReqBuilder(ServiceNamespace.SERVICE_NAMESPACE);
-			String service = Processor.removeDuplicateMarker(export.getKey());
-			exportedService.addAttribute(ServiceNamespace.SERVICE_NAMESPACE, service);
-			exportedService.addAttribute(ServiceNamespace.CAPABILITY_OBJECTCLASS_ATTRIBUTE, export.getValue().get("objectclass"));
-			resource.addCapability(exportedService);
-		}
-		
-		//
-		// Import-Service (deprecated)
-		//
-		
-		for (Entry<String,Attrs> imported : d.getParameters(Constants.IMPORT_SERVICE).entrySet()) {
-			CapReqBuilder	importedService = new CapReqBuilder(ServiceNamespace.SERVICE_NAMESPACE);
-			String service = Processor.removeDuplicateMarker(imported.getKey());
-			importedService.addDirective(Namespace.REQUIREMENT_FILTER_DIRECTIVE, filter(ServiceNamespace.SERVICE_NAMESPACE, service, imported.getValue()));
-			resource.addRequirement(importedService);
-		}
-		
-		//
-		// Provide-Capability
-		//
-		
-		for ( Entry<String,Attrs> rc : d.getProvideCapability().entrySet()) {
-			resource.addCapability( toCapability(rc.getKey(), rc.getValue()));
-		}
-		
-		//
-		// Require-Capability
-		//
-
-		for ( Entry<String,Attrs> rc : d.getRequireCapability().entrySet()) {
-			resource.addCapability( toRequirement(rc.getKey(), rc.getValue()));
-		}
-		
-		
-		return null;
-	}
-
-	private static Capability toRequirement(String key, Attrs value) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	private static Capability toCapability(String key, Attrs value) {
-		// TODO Auto-generated method stub
-		return null;
-	}
-
-	public static Reporter parse(File file, ResourceBuilder resource, String base) throws Exception {
-		Jar jar = new Jar(file);
-		try {
-			Reporter reporter = parse(jar, resource);
-			if (!reporter.isOk())
-				return reporter;
-
-			CapReqBuilder content = new CapReqBuilder(ContentNamespace.CONTENT_NAMESPACE);
-			String sha = SHA1.digest(file).asHex();
-			content.addAttribute(ContentNamespace.CONTENT_NAMESPACE, sha);
-			content.addAttribute(ContentNamespace.CAPABILITY_SIZE_ATTRIBUTE, (long) file.length());
-			content.addAttribute(ContentNamespace.CAPABILITY_MIME_ATTRIBUTE, MIME_TYPE_OSGI_BUNDLE);
-
-			if (base != null) {
-				String path = file.getAbsolutePath();
-				if (base.startsWith(path)) {
-					content.addAttribute(ContentNamespace.CAPABILITY_URL_ATTRIBUTE, path.substring(base.length())
-							.replace(File.separatorChar, '/'));
-				} else {
-					reporter.error("Base path %s is not parent of file path: %s", base, file.getAbsolutePath());
-				}
-			}
-
-			resource.addCapability(content);
-			return reporter;
-		}
-		finally {
-			jar.close();
-		}
-	}
-	
-	// TODO finish
-	private static String filter(String ns, String primary, Map<String,String> value) {
-		Formatter f = new Formatter();
-		f.format("(&(%s=%s)", ns, primary);
-		for ( String key : value.keySet()) {
-			if ( key.equals("version") || key.equals("bundle-version")) {
-				VersionRange vr = new VersionRange(value.get(key));
-			} else {
-				f.format("(%s=%s)", key, value.get(key));
-			}
-		}
-		
-		f.format(")");
-		return null;
-	}
-
-}
