Pull in complete OSGi R4.3 API. (FELIX-2950)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1103907 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index 338d0e4..7aa4bcf 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -20,6 +20,7 @@
 
 import java.io.File;
 import java.io.InputStream;
+import java.util.Collection;
 import java.util.Dictionary;
 
 import org.apache.felix.framework.ext.FelixBundleContext;
@@ -177,6 +178,18 @@
         return m_felix.getBundle(id);
     }
 
+    public Bundle getBundle(String location)
+    {
+        checkValidity();
+
+        // CONCURRENCY NOTE: This is a check-then-act situation,
+        // but we ignore it since the time window is small and
+        // the result is the same as if the calling thread had
+        // won the race condition.
+
+        return m_felix.getBundle(location);
+    }
+
     public Bundle[] getBundles()
     {
         checkValidity();
@@ -293,14 +306,14 @@
         m_felix.removeFrameworkListener(m_bundle, l);
     }
 
-    public ServiceRegistration registerService(
-        String clazz, Object svcObj, Dictionary dict)
+    public ServiceRegistration<?> registerService(
+        String clazz, Object svcObj, Dictionary<String, ? > dict)
     {
         return registerService(new String[] { clazz }, svcObj, dict);
     }
 
-    public ServiceRegistration registerService(
-        String[] clazzes, Object svcObj, Dictionary dict)
+    public ServiceRegistration<?> registerService(
+        String[] clazzes, Object svcObj, Dictionary<String, ? > dict)
     {
         checkValidity();
 
@@ -325,7 +338,13 @@
         return m_felix.registerService(m_bundle, clazzes, svcObj, dict);
     }
 
-    public ServiceReference getServiceReference(String clazz)
+    public <S> ServiceRegistration<S> registerService(
+        Class<S> clazz, S svcObj, Dictionary<String, ? > dict)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public ServiceReference<?> getServiceReference(String clazz)
     {
         checkValidity();
 
@@ -346,6 +365,11 @@
         return null;
     }
 
+    public <S> ServiceReference<S> getServiceReference(Class<S> clazz)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
     private ServiceReference getBestServiceReference(ServiceReference[] refs)
     {
         if (refs == null)
@@ -372,7 +396,8 @@
         return bestRef;
     }
 
-    public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException
+    public ServiceReference<?>[] getAllServiceReferences(String clazz, String filter)
+        throws InvalidSyntaxException
     {
         checkValidity();
 
@@ -385,7 +410,7 @@
 
     }
 
-    public ServiceReference[] getServiceReferences(String clazz, String filter)
+    public ServiceReference<?>[] getServiceReferences(String clazz, String filter)
         throws InvalidSyntaxException
     {
         checkValidity();
@@ -399,7 +424,14 @@
 
     }
 
-    public Object getService(ServiceReference ref)
+    public <S> Collection<ServiceReference<S>> getServiceReferences(
+        Class<S> clazz, String filter)
+        throws InvalidSyntaxException
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public <S> S getService(ServiceReference<S> ref)
     {
         checkValidity();
 
@@ -423,7 +455,7 @@
         return m_felix.getService(m_bundle, ref);
     }
 
-    public boolean ungetService(ServiceReference ref)
+    public boolean ungetService(ServiceReference<?> ref)
     {
         checkValidity();
 
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
index 458fa9f..6609b42 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleImpl.java
@@ -18,6 +18,7 @@
  */
 package org.apache.felix.framework;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
@@ -998,6 +999,21 @@
         getFramework().uninstallBundle(this);
     }
 
+    public <A> A adapt(Class<A> type)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public File getDataFile(String filename)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    public int compareTo(Bundle t)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
     public String toString()
     {
         String sym = getCurrentRevision().getSymbolicName();
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index d3f2f4f..397b0ed 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -3172,11 +3172,11 @@
 
     }
 
-    Object getService(Bundle bundle, ServiceReference ref)
+    <S> S getService(Bundle bundle, ServiceReference<S> ref)
     {
         try
         {
-            return m_registry.getService(bundle, ref);
+            return (S) m_registry.getService(bundle, ref);
         }
         catch (ServiceException ex)
         {
diff --git a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
index 4b2fdb1..a64ba1f 100644
--- a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
@@ -57,16 +57,21 @@
         return CapabilitySet.matches((ServiceReferenceImpl) sr, m_filter);
     }
 
-    public boolean match(Dictionary dctnr)
+    public boolean match(Dictionary<String, ? > dctnr)
     {
         return CapabilitySet.matches(new DictionaryCapability(dctnr, false), m_filter);
     }
 
-    public boolean matchCase(Dictionary dctnr)
+    public boolean matchCase(Dictionary<String, ? > dctnr)
     {
         return CapabilitySet.matches(new DictionaryCapability(dctnr, true), m_filter);
     }
 
+    public boolean matches(Map<String, ?> map)
+    {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
     public boolean equals(Object o)
     {
         return toString().equals(o.toString());
diff --git a/framework/src/main/java/org/osgi/framework/AdaptPermission.java b/framework/src/main/java/org/osgi/framework/AdaptPermission.java
new file mode 100644
index 0000000..f95c1fe
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/AdaptPermission.java
@@ -0,0 +1,635 @@
+/*
+ * Copyright (c) OSGi Alliance (2010, 2011). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.AccessController;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A bundle's authority to adapt an object to a type.
+ * 
+ * <p>
+ * {@code AdaptPermission} has one action: {@code adapt}.
+ * 
+ * @ThreadSafe
+ * @version $Id: bc4c5d392d2534a7744f6fc00f4665502f82033c $
+ */
+public class AdaptPermission extends BasicPermission {
+
+	private static final long						serialVersionUID	= 1L;
+
+	/**
+	 * The action string {@code initiate}.
+	 */
+	public final static String						ADAPT				= "adapt";
+
+	private final static int						ACTION_ADAPT		= 0x00000001;
+	private final static int						ACTION_ALL			= ACTION_ADAPT;
+	final static int								ACTION_NONE			= 0;
+
+	/**
+	 * The actions mask.
+	 */
+	transient int									action_mask;
+
+	/**
+	 * The actions in canonical form.
+	 * 
+	 * @serial
+	 */
+	private volatile String							actions				= null;
+
+	/**
+	 * The bundle used by this AdaptPermission.
+	 */
+	transient final Bundle							bundle;
+
+	/**
+	 * This holds a Filter matching object used to evaluate the filter in
+	 * implies.
+	 */
+	transient Filter								filter;
+
+	/**
+	 * This map holds the properties of the permission, used to match a filter
+	 * in implies. This is not initialized until necessary, and then cached in
+	 * this object.
+	 */
+	private transient volatile Map<String, Object>	properties;
+
+	/**
+	 * Creates a new granted {@code AdaptPermission} object.
+	 * 
+	 * This constructor must only be used to create a permission that is going
+	 * to be checked.
+	 * <p>
+	 * Examples:
+	 * 
+	 * <pre>
+	 * (adaptClass=com.acme.*)
+	 * (&amp;(signer=\*,o=ACME,c=US)(adaptClass=com.acme.*))
+	 * (signer=\*,o=ACME,c=US)
+	 * </pre>
+	 * 
+	 * <p>
+	 * When a signer key is used within the filter expression the signer value
+	 * must escape the special filter chars ('*', '(', ')').
+	 * <p>
+	 * The name is specified as a filter expression. The filter gives access to
+	 * the following attributes:
+	 * <ul>
+	 * <li>signer - A Distinguished Name chain used to sign the exporting
+	 * bundle. Wildcards in a DN are not matched according to the filter string
+	 * rules, but according to the rules defined for a DN chain.</li>
+	 * <li>location - The location of the exporting bundle.</li>
+	 * <li>id - The bundle ID of the exporting bundle.</li>
+	 * <li>name - The symbolic name of the exporting bundle.</li>
+	 * <li>adaptClass - The name of the type to which an object can be adapted.</li>
+	 * </ul>
+	 * Filter attribute names are processed in a case sensitive manner.
+	 * 
+	 * @param filter A filter expression. Filter attribute names are processed
+	 *        in a case sensitive manner. A special value of {@code "*"} can be
+	 *        used to match all adaptations.
+	 * @param actions {@code adapt}.
+	 * @throws IllegalArgumentException If the filter has an invalid syntax.
+	 */
+	public AdaptPermission(String filter, String actions) {
+		this(parseFilter(filter), parseActions(actions));
+	}
+
+	/**
+	 * Creates a new requested {@code AdaptPermission} object to be used by the
+	 * code that must perform {@code checkPermission}. {@code AdaptPermission}
+	 * objects created with this constructor cannot be added to an
+	 * {@code AdaptPermission} permission collection.
+	 * 
+	 * @param adaptClass The name of the type to which an object can be adapted.
+	 * @param adaptableBundle The bundle associated with the object being
+	 *        adapted.
+	 * @param actions {@code adapt}.
+	 */
+	public AdaptPermission(String adaptClass, Bundle adaptableBundle,
+			String actions) {
+		super(adaptClass);
+		setTransients(null, parseActions(actions));
+		this.bundle = adaptableBundle;
+		if (adaptClass == null) {
+			throw new NullPointerException("adaptClass must not be null");
+		}
+		if (adaptableBundle == null) {
+			throw new NullPointerException("adaptableBundle must not be null");
+		}
+	}
+
+	/**
+	 * Package private constructor used by AdaptPermissionCollection.
+	 * 
+	 * @param filter name filter
+	 * @param mask action mask
+	 */
+	AdaptPermission(Filter filter, int mask) {
+		super((filter == null) ? "*" : filter.toString());
+		setTransients(filter, mask);
+		this.bundle = null;
+	}
+
+	/**
+	 * Called by constructors and when deserialized.
+	 * 
+	 * @param filter Permission's filter or {@code null} for wildcard.
+	 * @param mask action mask
+	 */
+	private void setTransients(Filter filter, int mask) {
+		this.filter = filter;
+		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+		this.action_mask = mask;
+	}
+
+	/**
+	 * Parse action string into action mask.
+	 * 
+	 * @param actions Action string.
+	 * @return action mask.
+	 */
+	private static int parseActions(String actions) {
+		boolean seencomma = false;
+
+		int mask = ACTION_NONE;
+
+		if (actions == null) {
+			return mask;
+		}
+
+		char[] a = actions.toCharArray();
+
+		int i = a.length - 1;
+		if (i < 0)
+			return mask;
+
+		while (i != -1) {
+			char c;
+
+			// skip whitespace
+			while ((i != -1)
+					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
+							|| c == '\f' || c == '\t'))
+				i--;
+
+			// check for the known strings
+			int matchlen;
+
+			if (i >= 4 && (a[i - 4] == 'a' || a[i - 4] == 'A')
+					&& (a[i - 3] == 'd' || a[i - 3] == 'D')
+					&& (a[i - 2] == 'a' || a[i - 2] == 'A')
+					&& (a[i - 1] == 'p' || a[i - 1] == 'P')
+					&& (a[i] == 't' || a[i] == 'T')) {
+				matchlen = 5;
+				mask |= ACTION_ADAPT;
+
+			}
+			else {
+				// parse error
+				throw new IllegalArgumentException("invalid actions: "
+						+ actions);
+			}
+
+			// make sure we didn't just match the tail of a word
+			// like "ackbarfadapt". Also, skip to the comma.
+			seencomma = false;
+			while (i >= matchlen && !seencomma) {
+				switch (a[i - matchlen]) {
+					case ',' :
+						seencomma = true;
+						/* FALLTHROUGH */
+					case ' ' :
+					case '\r' :
+					case '\n' :
+					case '\f' :
+					case '\t' :
+						break;
+					default :
+						throw new IllegalArgumentException(
+								"invalid permission: " + actions);
+				}
+				i--;
+			}
+
+			// point i at the location of the comma minus one (or -1).
+			i -= matchlen;
+		}
+
+		if (seencomma) {
+			throw new IllegalArgumentException("invalid actions: " + actions);
+		}
+
+		return mask;
+	}
+
+	/**
+	 * Parse filter string into a Filter object.
+	 * 
+	 * @param filterString The filter string to parse.
+	 * @return a Filter for this bundle.
+	 * @throws IllegalArgumentException If the filter syntax is invalid.
+	 */
+	private static Filter parseFilter(String filterString) {
+		filterString = filterString.trim();
+		if (filterString.equals("*")) {
+			return null;
+		}
+		try {
+			return FrameworkUtil.createFilter(filterString);
+		}
+		catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException(
+					"invalid filter");
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Determines if the specified permission is implied by this object.
+	 * 
+	 * <p>
+	 * This method checks that the filter of the target is implied by the adapt
+	 * class name of this object. The list of {@code AdaptPermission} actions
+	 * must either match or allow for the list of the target object to imply the
+	 * target {@code AdaptPermission} action.
+	 * <p>
+	 * 
+	 * @param p The requested permission.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	public boolean implies(Permission p) {
+		if (!(p instanceof AdaptPermission)) {
+			return false;
+		}
+		AdaptPermission requested = (AdaptPermission) p;
+		if (bundle != null) {
+			return false;
+		}
+		// if requested permission has a filter, then it is an invalid argument
+		if (requested.filter != null) {
+			return false;
+		}
+		return implies0(requested, ACTION_NONE);
+	}
+
+	/**
+	 * Internal implies method. Used by the implies and the permission
+	 * collection implies methods.
+	 * 
+	 * @param requested The requested AdaptPermission which has already be
+	 *        validated as a proper argument. The requested AdaptPermission must
+	 *        not have a filter expression.
+	 * @param effective The effective actions with which to start.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	boolean implies0(AdaptPermission requested, int effective) {
+		/* check actions first - much faster */
+		effective |= action_mask;
+		final int desired = requested.action_mask;
+		if ((effective & desired) != desired) {
+			return false;
+		}
+		/* Get filter */
+		Filter f = filter;
+		if (f == null) {
+			// it's "*"
+			return true;
+		}
+		return f.matches(requested.getProperties());
+	}
+
+	/**
+	 * Returns the canonical string representation of the
+	 * {@code AdaptPermission} actions.
+	 * 
+	 * <p>
+	 * Always returns present {@code AdaptPermission} actions in the following
+	 * order: {@code adapt}.
+	 * 
+	 * @return Canonical string representation of the {@code AdaptPermission}
+	 *         actions.
+	 */
+	public String getActions() {
+		String result = actions;
+		if (result == null) {
+			actions = result = ADAPT;
+		}
+		return result;
+	}
+
+	/**
+	 * Returns a new {@code PermissionCollection} object suitable for storing
+	 * {@code AdaptPermission} objects.
+	 * 
+	 * @return A new {@code PermissionCollection} object.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return new AdaptPermissionCollection();
+	}
+
+	/**
+	 * Determines the equality of two {@code AdaptPermission} objects.
+	 * 
+	 * This method checks that specified permission has the same name and
+	 * {@code AdaptPermission} actions as this {@code AdaptPermission} object.
+	 * 
+	 * @param obj The object to test for equality with this
+	 *        {@code AdaptPermission} object.
+	 * @return {@code true} if {@code obj} is a {@code AdaptPermission}, and has
+	 *         the same name and actions as this {@code AdaptPermission} object;
+	 *         {@code false} otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+
+		if (!(obj instanceof AdaptPermission)) {
+			return false;
+		}
+
+		AdaptPermission cp = (AdaptPermission) obj;
+
+		return (action_mask == cp.action_mask)
+				&& getName().equals(cp.getName())
+				&& ((bundle == cp.bundle) || ((bundle != null) && bundle
+						.equals(cp.bundle)));
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return A hash code value for this object.
+	 */
+	public int hashCode() {
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		if (bundle != null) {
+			h = 31 * h + bundle.hashCode();
+		}
+		return h;
+	}
+
+	/**
+	 * WriteObject is called to save the state of this permission object to a
+	 * stream. The actions are serialized, and the superclass takes care of the
+	 * name.
+	 */
+	private synchronized void writeObject(java.io.ObjectOutputStream s)
+			throws IOException {
+		if (bundle != null) {
+			throw new NotSerializableException("cannot serialize");
+		}
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		s.defaultWriteObject();
+	}
+
+	/**
+	 * readObject is called to restore the state of this permission from a
+	 * stream.
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s)
+			throws IOException, ClassNotFoundException {
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		setTransients(parseFilter(getName()), parseActions(actions));
+	}
+
+	/**
+	 * Called by {@code <@link AdaptPermission#implies(Permission)>}. This
+	 * method is only called on a requested permission which cannot have a
+	 * filter set.
+	 * 
+	 * @return a map of properties for this permission.
+	 */
+	private Map<String, Object> getProperties() {
+		Map<String, Object> result = properties;
+		if (result != null) {
+			return result;
+		}
+		final Map<String, Object> map = new HashMap<String, Object>(5);
+		map.put("adaptClass", getName());
+		if (bundle != null) {
+			AccessController.doPrivileged(new PrivilegedAction<Object>() {
+				public Object run() {
+					map.put("id", new Long(bundle.getBundleId()));
+					map.put("location", bundle.getLocation());
+					String name = bundle.getSymbolicName();
+					if (name != null) {
+						map.put("name", name);
+					}
+					SignerProperty signer = new SignerProperty(bundle);
+					if (signer.isBundleSigned()) {
+						map.put("signer", signer);
+					}
+					return null;
+				}
+			});
+		}
+		return properties = map;
+	}
+}
+
+/**
+ * Stores a set of {@code AdaptPermission} permissions.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+
+final class AdaptPermissionCollection extends PermissionCollection {
+	static final long						serialVersionUID	= -3350758995234427603L;
+	/**
+	 * Collection of permissions.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private Map<String, AdaptPermission>	permissions;
+
+	/**
+	 * Boolean saying if "*" is in the collection.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private boolean							all_allowed;
+
+	/**
+	 * Create an empty AdaptPermissions object.
+	 */
+	public AdaptPermissionCollection() {
+		permissions = new HashMap<String, AdaptPermission>();
+		all_allowed = false;
+	}
+
+	/**
+	 * Adds a permission to this permission collection.
+	 * 
+	 * @param permission The {@code AdaptPermission} object to add.
+	 * @throws IllegalArgumentException If the specified permission is not a
+	 *         {@code AdaptPermission} instance or was constructed with a Bundle
+	 *         object.
+	 * @throws SecurityException If this {@code AdaptPermissionCollection}
+	 *         object has been marked read-only.
+	 */
+	public void add(final Permission permission) {
+		if (!(permission instanceof AdaptPermission)) {
+			throw new IllegalArgumentException("invalid permission: "
+					+ permission);
+		}
+		if (isReadOnly()) {
+			throw new SecurityException("attempt to add a Permission to a "
+					+ "readonly PermissionCollection");
+		}
+
+		final AdaptPermission ap = (AdaptPermission) permission;
+		if (ap.bundle != null) {
+			throw new IllegalArgumentException("cannot add to collection: "
+					+ ap);
+		}
+
+		final String name = ap.getName();
+		synchronized (this) {
+			Map<String, AdaptPermission> pc = permissions;
+			final AdaptPermission existing = pc.get(name);
+			if (existing != null) {
+				final int oldMask = existing.action_mask;
+				final int newMask = ap.action_mask;
+				if (oldMask != newMask) {
+					pc.put(name, new AdaptPermission(existing.filter, oldMask
+							| newMask));
+
+				}
+			}
+			else {
+				pc.put(name, ap);
+			}
+
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Determines if the specified permissions implies the permissions expressed
+	 * in {@code permission}.
+	 * 
+	 * @param permission The Permission object to compare with this
+	 *        {@code AdaptPermission} object.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
+	 */
+	public boolean implies(final Permission permission) {
+		if (!(permission instanceof AdaptPermission)) {
+			return false;
+		}
+		final AdaptPermission requested = (AdaptPermission) permission;
+		/* if requested permission has a filter, then it is an invalid argument */
+		if (requested.filter != null) {
+			return false;
+		}
+
+		int effective = AdaptPermission.ACTION_NONE;
+
+		Collection<AdaptPermission> perms;
+		synchronized (this) {
+			Map<String, AdaptPermission> pc = permissions;
+			/* short circuit if the "*" Permission was added */
+			if (all_allowed) {
+				AdaptPermission ap = pc.get("*");
+				if (ap != null) {
+					effective |= ap.action_mask;
+					final int desired = requested.action_mask;
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+			}
+			perms = pc.values();
+		}
+		/* iterate one by one over filteredPermissions */
+		for (AdaptPermission perm : perms) {
+			if (perm.implies0(requested, effective)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns an enumeration of all {@code AdaptPermission} objects in the
+	 * container.
+	 * 
+	 * @return Enumeration of all {@code AdaptPermission} objects.
+	 */
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		return Collections.enumeration(all);
+	}
+
+	/* serialization logic */
+	private static final ObjectStreamField[]	serialPersistentFields	= {
+			new ObjectStreamField("permissions", HashMap.class),
+			new ObjectStreamField("all_allowed", Boolean.TYPE)			};
+
+	private synchronized void writeObject(ObjectOutputStream out)
+			throws IOException {
+		ObjectOutputStream.PutField pfields = out.putFields();
+		pfields.put("permissions", permissions);
+		pfields.put("all_allowed", all_allowed);
+		out.writeFields();
+	}
+
+	private synchronized void readObject(java.io.ObjectInputStream in)
+			throws IOException, ClassNotFoundException {
+		ObjectInputStream.GetField gfields = in.readFields();
+		permissions = (HashMap<String, AdaptPermission>) gfields.get(
+				"permissions", null);
+		all_allowed = gfields.get("all_allowed", false);
+	}
+}
diff --git a/framework/src/main/java/org/osgi/framework/AdminPermission.java b/framework/src/main/java/org/osgi/framework/AdminPermission.java
index 1811791..fc7b1f4 100644
--- a/framework/src/main/java/org/osgi/framework/AdminPermission.java
+++ b/framework/src/main/java/org/osgi/framework/AdminPermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,13 +26,13 @@
 import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.PrivilegedAction;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
-import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -45,7 +45,7 @@
  *  class                Bundle.loadClass
  *  execute              Bundle.start
  *                       Bundle.stop
- *                       StartLevel.setBundleStartLevel
+ *                       BundleStartLevel.setStartLevel
  *  extensionLifecycle   BundleContext.installBundle for extension bundles
  *                       Bundle.update for extension bundles
  *                       Bundle.uninstall for extension bundles
@@ -56,23 +56,25 @@
  *                       BundleContext.removeBundleListener for SynchronousBundleListener
  *  metadata             Bundle.getHeaders
  *                       Bundle.getLocation
- *  resolve              PackageAdmin.refreshPackages
- *                       PackageAdmin.resolveBundles
+ *  resolve              FrameworkWiring.refreshBundles
+ *                       FrameworkWiring.resolveBundles
  *  resource             Bundle.getResource
  *                       Bundle.getResources
  *                       Bundle.getEntry
  *                       Bundle.getEntryPaths
  *                       Bundle.findEntries
  *                       Bundle resource/entry URL creation
- *  startlevel           StartLevel.setStartLevel
- *                       StartLevel.setInitialBundleStartLevel 
+ *  startlevel           FrameworkStartLevel.setStartLevel
+ *                       FrameworkStartLevel.setInitialBundleStartLevel 
  *  context              Bundle.getBundleContext
+ *  weave                WovenClass.setBytes
+ *                       WovenClass.getDynamicImports for modification
  * </pre>
  * 
  * <p>
  * The special action &quot;*&quot; will represent all actions. The
- * <code>resolve</code> action is implied by the <code>class</code>,
- * <code>execute</code> and <code>resource</code> actions.
+ * {@code resolve} action is implied by the {@code class}, {@code execute} and
+ * {@code resource} actions.
  * <p>
  * The name of this permission is a filter expression. The filter gives access
  * to the following attributes:
@@ -87,79 +89,86 @@
  * Filter attribute names are processed in a case sensitive manner.
  * 
  * @ThreadSafe
- * @version $Revision: 7743 $
+ * @version $Id: 43baf9a6d7ce5e6108507834e841e340fd91c513 $
  */
 
 public final class AdminPermission extends BasicPermission {
 	static final long						serialVersionUID			= 307051004521261705L;
 
 	/**
-	 * The action string <code>class</code>. The <code>class</code> action
-	 * implies the <code>resolve</code> action.
+	 * The action string {@code class}. The {@code class} action
+	 * implies the {@code resolve} action.
 	 * 
 	 * @since 1.3
 	 */
 	public final static String	CLASS						= "class";
 	/**
-	 * The action string <code>execute</code>. The <code>execute</code> action
-	 * implies the <code>resolve</code> action.
+	 * The action string {@code execute}. The {@code execute} action
+	 * implies the {@code resolve} action.
 	 * 
 	 * @since 1.3
 	 */
 	public final static String	EXECUTE						= "execute";
 	/**
-	 * The action string <code>extensionLifecycle</code>.
+	 * The action string {@code extensionLifecycle}.
 	 * 
 	 * @since 1.3
 	 */
 	public final static String	EXTENSIONLIFECYCLE			= "extensionLifecycle";
 	/**
-	 * The action string <code>lifecycle</code>.
+	 * The action string {@code lifecycle}.
 	 * 
 	 * @since 1.3
 	 */
 	public final static String	LIFECYCLE					= "lifecycle";
 	/**
-	 * The action string <code>listener</code>.
+	 * The action string {@code listener}.
 	 * 
 	 * @since 1.3
 	 */
 	public final static String	LISTENER					= "listener";
 	/**
-	 * The action string <code>metadata</code>.
+	 * The action string {@code metadata}.
 	 * 
 	 * @since 1.3
 	 */
 	public final static String	METADATA					= "metadata";
 	/**
-	 * The action string <code>resolve</code>. The <code>resolve</code> action
-	 * is implied by the <code>class</code>, <code>execute</code> and
-	 * <code>resource</code> actions.
+	 * The action string {@code resolve}. The {@code resolve} action
+	 * is implied by the {@code class}, {@code execute} and
+	 * {@code resource} actions.
 	 * 
 	 * @since 1.3
 	 */
 	public final static String	RESOLVE						= "resolve";
 	/**
-	 * The action string <code>resource</code>. The <code>resource</code> action
-	 * implies the <code>resolve</code> action.
+	 * The action string {@code resource}. The {@code resource} action
+	 * implies the {@code resolve} action.
 	 * 
 	 * @since 1.3
 	 */
 	public final static String	RESOURCE					= "resource";
 	/**
-	 * The action string <code>startlevel</code>.
+	 * The action string {@code startlevel}.
 	 * 
 	 * @since 1.3
 	 */
 	public final static String	STARTLEVEL					= "startlevel";
 
 	/**
-	 * The action string <code>context</code>.
+	 * The action string {@code context}.
 	 * 
 	 * @since 1.4
 	 */
 	public final static String	CONTEXT						= "context";
 
+	/**
+	 * The action string {@code weave}.
+	 * 
+	 * @since 1.6
+	 */
+	public final static String						WEAVE						= "weave";
+
 	private final static int	ACTION_CLASS				= 0x00000001;
 	private final static int	ACTION_EXECUTE				= 0x00000002;
 	private final static int	ACTION_LIFECYCLE			= 0x00000004;
@@ -170,6 +179,7 @@
 	private final static int	ACTION_STARTLEVEL			= 0x00000100;
 	private final static int	ACTION_EXTENSIONLIFECYCLE	= 0x00000200;
 	private final static int	ACTION_CONTEXT				= 0x00000400;
+	private final static int						ACTION_WEAVE				= 0x00000800;
 	private final static int	ACTION_ALL					= ACTION_CLASS
 																	| ACTION_EXECUTE
 																	| ACTION_LIFECYCLE
@@ -179,7 +189,8 @@
 																	| ACTION_RESOURCE
 																	| ACTION_STARTLEVEL
 																	| ACTION_EXTENSIONLIFECYCLE
-																	| ACTION_CONTEXT;
+																						| ACTION_CONTEXT
+																						| ACTION_WEAVE;
 	final static int						ACTION_NONE					= 0;
 
 	/**
@@ -203,23 +214,23 @@
 	/**
 	 * The bundle governed by this AdminPermission - only used if filter == null
 	 */
-	transient final Bundle					bundle; 
+	transient final Bundle					bundle;
 
 	/**
-	 * This dictionary holds the properties of the permission, used to match a
-	 * filter in implies. This is not initialized until necessary, and then
-	 * cached in this object.
+	 * This map holds the properties of the permission, used to match a filter
+	 * in implies. This is not initialized until necessary, and then cached in
+	 * this object.
 	 */
-	private transient volatile Dictionary	properties;
+	private transient volatile Map<String, Object>	properties;
 
 	/**
 	 * ThreadLocal used to determine if we have recursively called
 	 * getProperties.
 	 */
-	private static final ThreadLocal		recurse						= new ThreadLocal();
+	private static final ThreadLocal<Bundle>	recurse						= new ThreadLocal<Bundle>();
 
 	/**
-	 * Creates a new <code>AdminPermission</code> object that matches all
+	 * Creates a new {@code AdminPermission} object that matches all
 	 * bundles and has all actions. Equivalent to AdminPermission("*","*");
 	 */
 	public AdminPermission() {
@@ -247,14 +258,13 @@
 	 * Null arguments are equivalent to "*".
 	 * 
 	 * @param filter A filter expression that can use signer, location, id, and
-	 *        name keys. A value of &quot;*&quot; or <code>null</code> matches
-	 *        all bundle. Filter attribute names are processed in a case
-	 *        sensitive manner.
-	 * @param actions <code>class</code>, <code>execute</code>,
-	 *        <code>extensionLifecycle</code>, <code>lifecycle</code>,
-	 *        <code>listener</code>, <code>metadata</code>, <code>resolve</code>
-	 *        , <code>resource</code>, <code>startlevel</code> or
-	 *        <code>context</code>. A value of "*" or <code>null</code>
+	 *        name keys. A value of &quot;*&quot; or {@code null} matches all
+	 *        bundle. Filter attribute names are processed in a case sensitive
+	 *        manner.
+	 * @param actions {@code class}, {@code execute}, {@code extensionLifecycle}
+	 *        , {@code lifecycle}, {@code listener}, {@code metadata},
+	 *        {@code resolve} , {@code resource}, {@code startlevel},
+	 *        {@code context} or {@code weave}. A value of "*" or {@code null}
 	 *        indicates all actions.
 	 * @throws IllegalArgumentException If the filter has an invalid syntax.
 	 */
@@ -265,17 +275,16 @@
 	}
 
 	/**
-	 * Creates a new requested <code>AdminPermission</code> object to be used by
-	 * the code that must perform <code>checkPermission</code>.
-	 * <code>AdminPermission</code> objects created with this constructor cannot
-	 * be added to an <code>AdminPermission</code> permission collection.
+	 * Creates a new requested {@code AdminPermission} object to be used by the
+	 * code that must perform {@code checkPermission}. {@code AdminPermission}
+	 * objects created with this constructor cannot be added to an
+	 * {@code AdminPermission} permission collection.
 	 * 
 	 * @param bundle A bundle.
-	 * @param actions <code>class</code>, <code>execute</code>,
-	 *        <code>extensionLifecycle</code>, <code>lifecycle</code>,
-	 *        <code>listener</code>, <code>metadata</code>, <code>resolve</code>
-	 *        , <code>resource</code>, <code>startlevel</code>,
-	 *        <code>context</code>. A value of "*" or <code>null</code>
+	 * @param actions {@code class}, {@code execute}, {@code extensionLifecycle}
+	 *        , {@code lifecycle}, {@code listener}, {@code metadata},
+	 *        {@code resolve} , {@code resource}, {@code startlevel},
+	 *        {@code context}, {@code weave}. A value of "*" or {@code null}
 	 *        indicates all actions.
 	 * @since 1.3
 	 */
@@ -304,7 +313,7 @@
 	/**
 	 * Package private constructor used by AdminPermissionCollection.
 	 * 
-	 * @param filter name filter or <code>null</code> for wildcard.
+	 * @param filter name filter or {@code null} for wildcard.
 	 * @param mask action mask
 	 */
 	AdminPermission(Filter filter, int mask) {
@@ -316,7 +325,7 @@
 	/**
 	 * Called by constructors and when deserialized.
 	 * 
-	 * @param filter Permission's filter or <code>null</code> for wildcard.
+	 * @param filter Permission's filter or {@code null} for wildcard.
 	 * @param mask action mask
 	 */
 	private void setTransients(Filter filter, int mask) {
@@ -341,11 +350,7 @@
 		boolean seencomma = false;
 	
 		int mask = ACTION_NONE;
-	
-		if (actions == null) {
-			return mask;
-		}
-	
+
 		char[] a = actions.toCharArray();
 	
 		int i = a.length - 1;
@@ -507,19 +512,29 @@
 	
 												}
 												else
-													if (i >= 0 &&
-	
-													(a[i] == '*')) {
-														matchlen = 1;
-														mask |= ACTION_ALL;
-	
+													if (i >= 4
+															&& (a[i - 4] == 'w' || a[i - 4] == 'W')
+															&& (a[i - 3] == 'e' || a[i - 3] == 'E')
+															&& (a[i - 2] == 'a' || a[i - 2] == 'A')
+															&& (a[i - 1] == 'v' || a[i - 1] == 'V')
+															&& (a[i] == 'e' || a[i] == 'E')) {
+														matchlen = 5;
+														mask |= ACTION_WEAVE;
+
 													}
-													else {
-														// parse error
-														throw new IllegalArgumentException(
-																"invalid permission: "
-																		+ actions); 
-													}
+													else
+														if (i >= 0
+																&& (a[i] == '*')) {
+															matchlen = 1;
+															mask |= ACTION_ALL;
+
+														}
+														else {
+															// parse error
+															throw new IllegalArgumentException(
+																	"invalid permission: "
+																			+ actions);
+														}
 	
 			// make sure we didn't just match the tail of a word
 			// like "ackbarfstartlevel". Also, skip to the comma.
@@ -559,7 +574,7 @@
 	 * 
 	 * @param filterString The filter string to parse.
 	 * @return a Filter for this bundle. If the specified filterString is
-	 *         <code>null</code> or equals "*", then <code>null</code> is
+	 *         {@code null} or equals "*", then {@code null} is
 	 *         returned to indicate a wildcard.
 	 * @throws IllegalArgumentException If the filter syntax is invalid.
 	 */
@@ -589,7 +604,7 @@
 	 * constructed with a bundle.
 	 * 
 	 * <p>
-	 * This method returns <code>true</code> if the specified permission is an
+	 * This method returns {@code true} if the specified permission is an
 	 * AdminPermission AND
 	 * <ul>
 	 * <li>this object's filter matches the specified permission's bundle ID,
@@ -601,13 +616,13 @@
 	 * actions.
 	 * <p>
 	 * Special case: if the specified permission was constructed with "*"
-	 * filter, then this method returns <code>true</code> if this object's
+	 * filter, then this method returns {@code true} if this object's
 	 * filter is "*" and this object's actions include all of the specified
 	 * permission's actions
 	 * 
 	 * @param p The requested permission.
-	 * @return <code>true</code> if the specified permission is implied by this
-	 *         object; <code>false</code> otherwise.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
 	 */
 	public boolean implies(Permission p) {
 		if (!(p instanceof AdminPermission)) {
@@ -632,8 +647,8 @@
 	 *        validated as a proper argument. The requested AdminPermission must
 	 *        not have a filter expression.
 	 * @param effective The effective actions with which to start.
-	 * @return <code>true</code> if the specified permission is implied by this
-	 *         object; <code>false</code> otherwise.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
 	 */
 	boolean implies0(AdminPermission requested, int effective) {
 		/* check actions first - much faster */
@@ -653,7 +668,8 @@
 		if (requested.bundle == null) {
 			return false;
 		}
-		Dictionary requestedProperties = requested.getProperties();
+		Map<String, Object> requestedProperties = requested
+				.getProperties();
 		if (requestedProperties == null) {
 			/*
 			 * If the requested properties are null, then we have detected a
@@ -663,22 +679,21 @@
 			 */
 			return true;
 		}
-		return f.matchCase(requestedProperties);
+		return f.matches(requestedProperties);
 	}
 
 	/**
 	 * Returns the canonical string representation of the
-	 * <code>AdminPermission</code> actions.
+	 * {@code AdminPermission} actions.
 	 * 
 	 * <p>
-	 * Always returns present <code>AdminPermission</code> actions in the
-	 * following order: <code>class</code>, <code>execute</code>,
-	 * <code>extensionLifecycle</code>, <code>lifecycle</code>,
-	 * <code>listener</code>, <code>metadata</code>, <code>resolve</code>,
-	 * <code>resource</code>, <code>startlevel</code>, <code>context</code>.
+	 * Always returns present {@code AdminPermission} actions in the following
+	 * order: {@code class}, {@code execute}, {@code extensionLifecycle},
+	 * {@code lifecycle}, {@code listener}, {@code metadata}, {@code resolve},
+	 * {@code resource}, {@code startlevel}, {@code context}, {@code weave}.
 	 * 
-	 * @return Canonical string representation of the
-	 *         <code>AdminPermission</code> actions.
+	 * @return Canonical string representation of the {@code AdminPermission}
+	 *         actions.
 	 */
 	public String getActions() {
 		String result = actions;
@@ -735,6 +750,11 @@
 				sb.append(CONTEXT);
 				sb.append(',');
 			}
+
+			if ((mask & ACTION_WEAVE) == ACTION_WEAVE) {
+				sb.append(WEAVE);
+				sb.append(',');
+			}
 	
 			// remove trailing comma
 			if (sb.length() > 0) {
@@ -747,21 +767,21 @@
 	}
 
 	/**
-	 * Returns a new <code>PermissionCollection</code> object suitable for
-	 * storing <code>AdminPermission</code>s.
+	 * Returns a new {@code PermissionCollection} object suitable for
+	 * storing {@code AdminPermission}s.
 	 * 
-	 * @return A new <code>PermissionCollection</code> object.
+	 * @return A new {@code PermissionCollection} object.
 	 */
 	public PermissionCollection newPermissionCollection() {
 		return new AdminPermissionCollection();
 	}
 
 	/**
-	 * Determines the equality of two <code>AdminPermission</code> objects.
+	 * Determines the equality of two {@code AdminPermission} objects.
 	 * 
 	 * @param obj The object being compared for equality with this object.
-	 * @return <code>true</code> if <code>obj</code> is equivalent to this
-	 *         <code>AdminPermission</code>; <code>false</code> otherwise.
+	 * @return {@code true} if {@code obj} is equivalent to this
+	 *         {@code AdminPermission}; {@code false} otherwise.
 	 */
 	public boolean equals(Object obj) {
 		if (obj == this) {
@@ -824,18 +844,18 @@
 	}
 
 	/**
-	 * Called by <code>implies0</code> on an AdminPermission which was
-	 * constructed with a Bundle. This method loads a dictionary with the
-	 * filter-matchable properties of this bundle. The dictionary is cached so
-	 * this lookup only happens once.
+	 * Called by {@code implies0} on an AdminPermission which was constructed
+	 * with a Bundle. This method loads a map with the filter-matchable
+	 * properties of this bundle. The map is cached so this lookup only happens
+	 * once.
 	 * 
 	 * This method should only be called on an AdminPermission which was
 	 * constructed with a bundle
 	 * 
-	 * @return a dictionary of properties for this bundle
+	 * @return a map of properties for this bundle
 	 */
-	private Dictionary getProperties() {
-		Dictionary result = properties;
+	private Map<String, Object> getProperties() {
+		Map<String, Object> result = properties;
 		if (result != null) {
 			return result;
 		}
@@ -850,23 +870,24 @@
 		}
 		recurse.set(bundle);
 		try {
-			final Dictionary dict = new Hashtable(4);
-			AccessController.doPrivileged(new PrivilegedAction() {
+			final Map<String, Object> map = new HashMap<String, Object>(
+					4);
+			AccessController.doPrivileged(new PrivilegedAction<Object>() {
 				public Object run() {
-					dict.put("id", new Long(bundle.getBundleId()));
-					dict.put("location", bundle.getLocation());
+					map.put("id", new Long(bundle.getBundleId()));
+					map.put("location", bundle.getLocation());
 					String name = bundle.getSymbolicName();
 					if (name != null) {
-						dict.put("name", name);
+						map.put("name", name);
 					}
 					SignerProperty signer = new SignerProperty(bundle);
 					if (signer.isBundleSigned()) {
-						dict.put("signer", signer);
+						map.put("signer", signer);
 					}
 					return null;
 				}
 			});
-			return properties = dict;
+			return properties = map;
 		}
 		finally {
 			recurse.set(null);
@@ -875,7 +896,7 @@
 }
 
 /**
- * Stores a collection of <code>AdminPermission</code>s.
+ * Stores a collection of {@code AdminPermission}s.
  */
 final class AdminPermissionCollection extends PermissionCollection {
 	private static final long	serialVersionUID	= 3906372644575328048L;
@@ -884,7 +905,7 @@
 	 * 
 	 * @GuardedBy this
 	 */
-	private transient Map		permissions;
+	private transient Map<String, AdminPermission>	permissions;
 
 	/**
 	 * Boolean saying if "*" is in the collection.
@@ -899,17 +920,17 @@
 	 * 
 	 */
 	public AdminPermissionCollection() {
-		permissions = new HashMap();
+		permissions = new HashMap<String, AdminPermission>();
 	}
 
 	/**
 	 * Adds a permission to this permission collection.
 	 * 
-	 * @param permission The <code>AdminPermission</code> object to add.
+	 * @param permission The {@code AdminPermission} object to add.
 	 * @throws IllegalArgumentException If the specified permission is not an
-	 *         <code>AdminPermission</code> instance or was constructed with a
+	 *         {@code AdminPermission} instance or was constructed with a
 	 *         Bundle object.
-	 * @throws SecurityException If this <code>AdminPermissionCollection</code>
+	 * @throws SecurityException If this {@code AdminPermissionCollection}
 	 *         object has been marked read-only.
 	 */
 	public void add(Permission permission) {
@@ -928,8 +949,8 @@
 		}
 		final String name = ap.getName();
 		synchronized (this) {
-			Map pc = permissions;
-			AdminPermission existing = (AdminPermission) pc.get(name);
+			Map<String, AdminPermission> pc = permissions;
+			AdminPermission existing = pc.get(name);
 			if (existing != null) {
 				int oldMask = existing.action_mask;
 				int newMask = ap.action_mask;
@@ -952,13 +973,13 @@
 
 	/**
 	 * Determines if the specified permissions implies the permissions expressed
-	 * in <code>permission</code>.
+	 * in {@code permission}.
 	 * 
 	 * @param permission The Permission object to compare with the
-	 *        <code>AdminPermission</code> objects in this collection.
-	 * @return <code>true</code> if <code>permission</code> is implied by an
-	 *         <code>AdminPermission</code> in this collection,
-	 *         <code>false</code> otherwise.
+	 *        {@code AdminPermission} objects in this collection.
+	 * @return {@code true} if {@code permission} is implied by an
+	 *         {@code AdminPermission} in this collection,
+	 *         {@code false} otherwise.
 	 */
 	public boolean implies(Permission permission) {
 		if (!(permission instanceof AdminPermission)) {
@@ -971,12 +992,12 @@
 			return false;
 		}
 		int effective = AdminPermission.ACTION_NONE;
-		Collection perms;
+		Collection<AdminPermission> perms;
 		synchronized (this) {
-			Map pc = permissions;
+			Map<String, AdminPermission> pc = permissions;
 			// short circuit if the "*" Permission was added
 			if (all_allowed) {
-				AdminPermission ap = (AdminPermission) pc.get("*");
+				AdminPermission ap = pc.get("*");
 				if (ap != null) {
 					effective |= ap.action_mask;
 					final int desired = requested.action_mask;
@@ -989,8 +1010,8 @@
 		}
 
 		// just iterate one by one
-		for (Iterator iter = perms.iterator(); iter.hasNext();) {
-			if (((AdminPermission) iter.next()).implies0(requested, effective)) {
+		for (AdminPermission perm : perms) {
+			if (perm.implies0(requested, effective)) {
 				return true;
 			}
 		}
@@ -998,13 +1019,14 @@
 	}
 
 	/**
-	 * Returns an enumeration of all <code>AdminPermission</code> objects in the
+	 * Returns an enumeration of all {@code AdminPermission} objects in the
 	 * container.
 	 * 
-	 * @return Enumeration of all <code>AdminPermission</code> objects.
+	 * @return Enumeration of all {@code AdminPermission} objects.
 	 */
-	public synchronized Enumeration elements() {
-		return Collections.enumeration(permissions.values());
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		return Collections.enumeration(all);
 	}
 	
 	/* serialization logic */
@@ -1014,19 +1036,21 @@
     
     private synchronized void writeObject(ObjectOutputStream out)
 			throws IOException {
-		Hashtable hashtable = new Hashtable(permissions);
+		Hashtable<String, AdminPermission> hashtable = new Hashtable<String, AdminPermission>(
+				permissions);
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", hashtable);
 		pfields.put("all_allowed", all_allowed);
 		out.writeFields();
 	}
     
-    private synchronized void readObject(java.io.ObjectInputStream in)
+	private synchronized void readObject(java.io.ObjectInputStream in)
 			throws IOException,
 			ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		Hashtable hashtable = (Hashtable) gfields.get("permissions", null);
-		permissions = new HashMap(hashtable);
+		Hashtable<String, AdminPermission> hashtable = (Hashtable<String, AdminPermission>) gfields
+				.get("permissions", null);
+		permissions = new HashMap<String, AdminPermission>(hashtable);
 		all_allowed = gfields.get("all_allowed", false);
 	}
 }
diff --git a/framework/src/main/java/org/osgi/framework/AllServiceListener.java b/framework/src/main/java/org/osgi/framework/AllServiceListener.java
index 688f51e..9874a4b 100644
--- a/framework/src/main/java/org/osgi/framework/AllServiceListener.java
+++ b/framework/src/main/java/org/osgi/framework/AllServiceListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,35 +17,35 @@
 package org.osgi.framework;
 
 /**
- * A <code>ServiceEvent</code> listener that does not filter based upon
- * package wiring. <code>AllServiceListener</code> is a listener interface
+ * A {@code ServiceEvent} listener that does not filter based upon
+ * package wiring. {@code AllServiceListener} is a listener interface
  * that may be implemented by a bundle developer. When a
- * <code>ServiceEvent</code> is fired, it is synchronously delivered to an
- * <code>AllServiceListener</code>. The Framework may deliver
- * <code>ServiceEvent</code> objects to an <code>AllServiceListener</code>
+ * {@code ServiceEvent} is fired, it is synchronously delivered to an
+ * {@code AllServiceListener}. The Framework may deliver
+ * {@code ServiceEvent} objects to an {@code AllServiceListener}
  * out of order and may concurrently call and/or reenter an
- * <code>AllServiceListener</code>.
+ * {@code AllServiceListener}.
  * <p>
- * An <code>AllServiceListener</code> object is registered with the Framework
- * using the <code>BundleContext.addServiceListener</code> method.
- * <code>AllServiceListener</code> objects are called with a
- * <code>ServiceEvent</code> object when a service is registered, modified, or
+ * An {@code AllServiceListener} object is registered with the Framework
+ * using the {@code BundleContext.addServiceListener} method.
+ * {@code AllServiceListener} objects are called with a
+ * {@code ServiceEvent} object when a service is registered, modified, or
  * is in the process of unregistering.
  * 
  * <p>
- * <code>ServiceEvent</code> object delivery to
- * <code>AllServiceListener</code> objects is filtered by the filter specified
+ * {@code ServiceEvent} object delivery to
+ * {@code AllServiceListener} objects is filtered by the filter specified
  * when the listener was registered. If the Java Runtime Environment supports
- * permissions, then additional filtering is done. <code>ServiceEvent</code>
+ * permissions, then additional filtering is done. {@code ServiceEvent}
  * objects are only delivered to the listener if the bundle which defines the
- * listener object's class has the appropriate <code>ServicePermission</code>
+ * listener object's class has the appropriate {@code ServicePermission}
  * to get the service using at least one of the named classes under which the
  * service was registered.
  * 
  * <p>
- * Unlike normal <code>ServiceListener</code> objects,
- * <code>AllServiceListener</code> objects receive all
- * <code>ServiceEvent</code> objects regardless of whether the package source
+ * Unlike normal {@code ServiceListener} objects,
+ * {@code AllServiceListener} objects receive all
+ * {@code ServiceEvent} objects regardless of whether the package source
  * of the listening bundle is equal to the package source of the bundle that
  * registered the service. This means that the listener may not be able to cast
  * the service object to any of its corresponding service interfaces if the
@@ -55,7 +55,7 @@
  * @see ServicePermission
  * @ThreadSafe
  * @since 1.3
- * @version $Revision: 5673 $
+ * @version $Id: 35cee8a49e89b7b222aa3f85e1af0b4a4b550ce6 $
  */
 
 public interface AllServiceListener extends ServiceListener {
diff --git a/framework/src/main/java/org/osgi/framework/Bundle.java b/framework/src/main/java/org/osgi/framework/Bundle.java
index 692bc5e..8f4002c 100644
--- a/framework/src/main/java/org/osgi/framework/Bundle.java
+++ b/framework/src/main/java/org/osgi/framework/Bundle.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,23 +16,28 @@
 
 package org.osgi.framework;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
+import java.security.cert.X509Certificate;
 import java.util.Dictionary;
 import java.util.Enumeration;
+import java.util.List;
 import java.util.Map;
 
+import org.osgi.framework.wiring.FrameworkWiring;
+
 /**
  * An installed bundle in the Framework.
  * 
  * <p>
- * A <code>Bundle</code> object is the access point to define the lifecycle of
- * an installed bundle. Each bundle installed in the OSGi environment must have
- * an associated <code>Bundle</code> object.
+ * A {@code Bundle} object is the access point to define the lifecycle of an
+ * installed bundle. Each bundle installed in the OSGi environment must have an
+ * associated {@code Bundle} object.
  * 
  * <p>
- * A bundle must have a unique identity, a <code>long</code>, chosen by the
+ * A bundle must have a unique identity, a {@code long}, chosen by the
  * Framework. This identity must not change during the lifecycle of a bundle,
  * even when the bundle is updated. Uninstalling and then reinstalling the
  * bundle must create a new unique identity.
@@ -53,54 +58,59 @@
  * the valid states.
  * 
  * <p>
- * A bundle should only execute code when its state is one of
- * <code>STARTING</code>,<code>ACTIVE</code>, or <code>STOPPING</code>.
- * An <code>UNINSTALLED</code> bundle can not be set to another state; it is a
- * zombie and can only be reached because references are kept somewhere.
+ * A bundle should only have active threads of execution when its state is one
+ * of {@code STARTING},{@code ACTIVE}, or {@code STOPPING}. An {@code
+ * UNINSTALLED} bundle can not be set to another state; it is a zombie and can
+ * only be reached because references are kept somewhere.
  * 
  * <p>
- * The Framework is the only entity that is allowed to create
- * <code>Bundle</code> objects, and these objects are only valid within the
- * Framework that created them.
+ * The Framework is the only entity that is allowed to create {@code Bundle}
+ * objects, and these objects are only valid within the Framework that created
+ * them.
+ * 
+ * <p>
+ * Bundles have a natural ordering such that if two {@code Bundle}s have the
+ * same {@link #getBundleId() bundle id} they are equal. A {@code Bundle} is
+ * less than another {@code Bundle} if it has a lower {@link #getBundleId()
+ * bundle id} and is greater if it has a higher bundle id.
  * 
  * @ThreadSafe
- * @version $Revision: 6906 $
+ * @noimplement
+ * @version $Id: 239108e8d54ff493587b9cdfe1688bdefc5a714c $
  */
-public interface Bundle {
+public interface Bundle extends Comparable<Bundle> {
 	/**
 	 * The bundle is uninstalled and may not be used.
 	 * 
 	 * <p>
-	 * The <code>UNINSTALLED</code> state is only visible after a bundle is
+	 * The {@code UNINSTALLED} state is only visible after a bundle is
 	 * uninstalled; the bundle is in an unusable state but references to the
-	 * <code>Bundle</code> object may still be available and used for
-	 * introspection.
+	 * {@code Bundle} object may still be available and used for introspection.
 	 * <p>
-	 * The value of <code>UNINSTALLED</code> is 0x00000001.
+	 * The value of {@code UNINSTALLED} is 0x00000001.
 	 */
-	public static final int	UNINSTALLED				= 0x00000001;
+	int	UNINSTALLED				= 0x00000001;
 
 	/**
 	 * The bundle is installed but not yet resolved.
 	 * 
 	 * <p>
-	 * A bundle is in the <code>INSTALLED</code> state when it has been
-	 * installed in the Framework but is not or cannot be resolved.
+	 * A bundle is in the {@code INSTALLED} state when it has been installed in
+	 * the Framework but is not or cannot be resolved.
 	 * <p>
 	 * This state is visible if the bundle's code dependencies are not resolved.
-	 * The Framework may attempt to resolve an <code>INSTALLED</code> bundle's
-	 * code dependencies and move the bundle to the <code>RESOLVED</code>
-	 * state.
+	 * The Framework may attempt to resolve an {@code INSTALLED} bundle's code
+	 * dependencies and move the bundle to the {@code RESOLVED} state.
 	 * <p>
-	 * The value of <code>INSTALLED</code> is 0x00000002.
+	 * The value of {@code INSTALLED} is 0x00000002.
 	 */
-	public static final int	INSTALLED				= 0x00000002;
+	int	INSTALLED				= 0x00000002;
 
 	/**
 	 * The bundle is resolved and is able to be started.
 	 * 
 	 * <p>
-	 * A bundle is in the <code>RESOLVED</code> state when the Framework has
+	 * A bundle is in the {@code RESOLVED} state when the Framework has
 	 * successfully resolved the bundle's code dependencies. These dependencies
 	 * include:
 	 * <ul>
@@ -116,57 +126,56 @@
 	 * </ul>
 	 * <p>
 	 * Note that the bundle is not active yet. A bundle must be put in the
-	 * <code>RESOLVED</code> state before it can be started. The Framework may
+	 * {@code RESOLVED} state before it can be started. The Framework may
 	 * attempt to resolve a bundle at any time.
 	 * <p>
-	 * The value of <code>RESOLVED</code> is 0x00000004.
+	 * The value of {@code RESOLVED} is 0x00000004.
 	 */
-	public static final int	RESOLVED				= 0x00000004;
+	int	RESOLVED				= 0x00000004;
 
 	/**
 	 * The bundle is in the process of starting.
 	 * 
 	 * <p>
-	 * A bundle is in the <code>STARTING</code> state when its
-	 * {@link #start(int) start} method is active. A bundle must be in this
-	 * state when the bundle's {@link BundleActivator#start} is called. If the
-	 * <code>BundleActivator.start</code> method completes without exception,
-	 * then the bundle has successfully started and must move to the
-	 * <code>ACTIVE</code> state.
+	 * A bundle is in the {@code STARTING} state when its {@link #start(int)
+	 * start} method is active. A bundle must be in this state when the bundle's
+	 * {@link BundleActivator#start} is called. If the {@code
+	 * BundleActivator.start} method completes without exception, then the
+	 * bundle has successfully started and must move to the {@code ACTIVE}
+	 * state.
 	 * <p>
-	 * If the bundle has a
-	 * {@link Constants#ACTIVATION_LAZY lazy activation policy}, then the
-	 * bundle may remain in this state for some time until the activation is
-	 * triggered.
+	 * If the bundle has a {@link Constants#ACTIVATION_LAZY lazy activation
+	 * policy}, then the bundle may remain in this state for some time until the
+	 * activation is triggered.
 	 * <p>
-	 * The value of <code>STARTING</code> is 0x00000008.
+	 * The value of {@code STARTING} is 0x00000008.
 	 */
-	public static final int	STARTING				= 0x00000008;
+	int	STARTING				= 0x00000008;
 
 	/**
 	 * The bundle is in the process of stopping.
 	 * 
 	 * <p>
-	 * A bundle is in the <code>STOPPING</code> state when its
-	 * {@link #stop(int) stop} method is active. A bundle must be in this state
-	 * when the bundle's {@link BundleActivator#stop} method is called. When the
-	 * <code>BundleActivator.stop</code> method completes the bundle is
-	 * stopped and must move to the <code>RESOLVED</code> state.
+	 * A bundle is in the {@code STOPPING} state when its {@link #stop(int)
+	 * stop} method is active. A bundle must be in this state when the bundle's
+	 * {@link BundleActivator#stop} method is called. When the {@code
+	 * BundleActivator.stop} method completes the bundle is stopped and must
+	 * move to the {@code RESOLVED} state.
 	 * <p>
-	 * The value of <code>STOPPING</code> is 0x00000010.
+	 * The value of {@code STOPPING} is 0x00000010.
 	 */
-	public static final int	STOPPING				= 0x00000010;
+	int	STOPPING				= 0x00000010;
 
 	/**
 	 * The bundle is now running.
 	 * 
 	 * <p>
-	 * A bundle is in the <code>ACTIVE</code> state when it has been
-	 * successfully started and activated.
+	 * A bundle is in the {@code ACTIVE} state when it has been successfully
+	 * started and activated.
 	 * <p>
-	 * The value of <code>ACTIVE</code> is 0x00000020.
+	 * The value of {@code ACTIVE} is 0x00000020.
 	 */
-	public static final int	ACTIVE					= 0x00000020;
+	int	ACTIVE					= 0x00000020;
 
 	/**
 	 * The bundle start operation is transient and the persistent autostart
@@ -181,12 +190,12 @@
 	 * @since 1.4
 	 * @see #start(int)
 	 */
-	public static final int	START_TRANSIENT			= 0x00000001;
+	int	START_TRANSIENT			= 0x00000001;
 
 	/**
 	 * The bundle start operation must activate the bundle according to the
-	 * bundle's declared
-	 * {@link Constants#BUNDLE_ACTIVATIONPOLICY activation policy}.
+	 * bundle's declared {@link Constants#BUNDLE_ACTIVATIONPOLICY activation
+	 * policy}.
 	 * 
 	 * <p>
 	 * This bit may be set when calling {@link #start(int)} to notify the
@@ -197,7 +206,7 @@
 	 * @see Constants#BUNDLE_ACTIVATIONPOLICY
 	 * @see #start(int)
 	 */
-	public static final int	START_ACTIVATION_POLICY	= 0x00000002;
+	int	START_ACTIVATION_POLICY	= 0x00000002;
 
 	/**
 	 * The bundle stop is transient and the persistent autostart setting of the
@@ -212,7 +221,7 @@
 	 * @since 1.4
 	 * @see #stop(int)
 	 */
-	public static final int	STOP_TRANSIENT			= 0x00000001;
+	int	STOP_TRANSIENT			= 0x00000001;
 
 	/**
 	 * Request that all certificates used to sign the bundle be returned.
@@ -220,7 +229,7 @@
 	 * @since 1.5
 	 * @see #getSignerCertificates(int)
 	 */
-	public final static int	SIGNERS_ALL				= 1;
+	int	SIGNERS_ALL				= 1;
 
 	/**
 	 * Request that only certificates used to sign the bundle that are trusted
@@ -229,7 +238,7 @@
 	 * @since 1.5
 	 * @see #getSignerCertificates(int)
 	 */
-	public final static int	SIGNERS_TRUSTED			= 2;
+	int	SIGNERS_TRUSTED			= 2;
 
 	/**
 	 * Returns this bundle's current state.
@@ -237,24 +246,23 @@
 	 * <p>
 	 * A bundle can be in only one state at any time.
 	 * 
-	 * @return An element of <code>UNINSTALLED</code>,<code>INSTALLED</code>,
-	 *         <code>RESOLVED</code>,<code>STARTING</code>,
-	 *         <code>STOPPING</code>,<code>ACTIVE</code>.
+	 * @return An element of {@code UNINSTALLED},{@code INSTALLED},
+	 *         {@code RESOLVED}, {@code STARTING}, {@code STOPPING},
+	 *         {@code ACTIVE}.
 	 */
-	public int getState();
+	int getState();
 
 	/**
 	 * Starts this bundle.
 	 * 
 	 * <p>
-	 * If this bundle's state is <code>UNINSTALLED</code> then an
-	 * <code>IllegalStateException</code> is thrown.
+	 * If this bundle's state is {@code UNINSTALLED} then an
+	 * {@code IllegalStateException} is thrown.
 	 * <p>
-	 * If the Framework implements the optional Start Level service and the
-	 * current start level is less than this bundle's start level:
+	 * If the current start level is less than this bundle's start level:
 	 * <ul>
 	 * <li>If the {@link #START_TRANSIENT} option is set, then a
-	 * <code>BundleException</code> is thrown indicating this bundle cannot be
+	 * {@code BundleException} is thrown indicating this bundle cannot be
 	 * started due to the Framework's current start level.
 	 * 
 	 * <li>Otherwise, the Framework must set this bundle's persistent autostart
@@ -271,11 +279,11 @@
 	 * <li>If this bundle is in the process of being activated or deactivated
 	 * then this method must wait for activation or deactivation to complete
 	 * before continuing. If this does not occur in a reasonable time, a
-	 * <code>BundleException</code> is thrown to indicate this bundle was unable
-	 * to be started.
+	 * {@code BundleException} is thrown to indicate this bundle was unable to
+	 * be started.
 	 * 
-	 * <li>If this bundle's state is <code>ACTIVE</code> then this method
-	 * returns immediately.
+	 * <li>If this bundle's state is {@code ACTIVE} then this method returns
+	 * immediately.
 	 * 
 	 * <li>If the {@link #START_TRANSIENT} option is not set then set this
 	 * bundle's autostart setting to <em>Started with declared activation</em>
@@ -284,107 +292,111 @@
 	 * restarted and this bundle's autostart setting is not <em>Stopped</em>,
 	 * this bundle must be automatically started.
 	 * 
-	 * <li>If this bundle's state is not <code>RESOLVED</code>, an attempt is
-	 * made to resolve this bundle. If the Framework cannot resolve this bundle,
-	 * a <code>BundleException</code> is thrown.
+	 * <li>If this bundle's state is not {@code RESOLVED}, an attempt is made to
+	 * resolve this bundle. If the Framework cannot resolve this bundle, a
+	 * {@code BundleException} is thrown.
 	 * 
 	 * <li>If the {@link #START_ACTIVATION_POLICY} option is set and this
 	 * bundle's declared activation policy is {@link Constants#ACTIVATION_LAZY
 	 * lazy} then:
 	 * <ul>
-	 * <li>If this bundle's state is <code>STARTING</code> then this method
-	 * returns immediately.
-	 * <li>This bundle's state is set to <code>STARTING</code>.
+	 * <li>If this bundle's state is {@code STARTING} then this method returns
+	 * immediately.
+	 * <li>This bundle's state is set to {@code STARTING}.
 	 * <li>A bundle event of type {@link BundleEvent#LAZY_ACTIVATION} is fired.
 	 * <li>This method returns immediately and the remaining steps will be
 	 * followed when this bundle's activation is later triggered.
 	 * </ul>
 	 * <i></i>
-	 * <li>This bundle's state is set to <code>STARTING</code>.
+	 * <li>This bundle's state is set to {@code STARTING}.
 	 * 
 	 * <li>A bundle event of type {@link BundleEvent#STARTING} is fired.
 	 * 
 	 * <li>The {@link BundleActivator#start} method of this bundle's
-	 * <code>BundleActivator</code>, if one is specified, is called. If the
-	 * <code>BundleActivator</code> is invalid or throws an exception then:
+	 * {@code BundleActivator}, if one is specified, is called. If the
+	 * {@code BundleActivator} is invalid or throws an exception then:
 	 * <ul>
-	 * <li>This bundle's state is set to <code>STOPPING</code>.
+	 * <li>This bundle's state is set to {@code STOPPING}.
 	 * <li>A bundle event of type {@link BundleEvent#STOPPING} is fired.
 	 * <li>Any services registered by this bundle must be unregistered.
 	 * <li>Any services used by this bundle must be released.
 	 * <li>Any listeners registered by this bundle must be removed.
-	 * <li>This bundle's state is set to <code>RESOLVED</code>.
+	 * <li>This bundle's state is set to {@code RESOLVED}.
 	 * <li>A bundle event of type {@link BundleEvent#STOPPED} is fired.
-	 * <li>A <code>BundleException</code> is then thrown.
+	 * <li>A {@code BundleException} is then thrown.
 	 * </ul>
 	 * <i></i>
-	 * <li>If this bundle's state is <code>UNINSTALLED</code>, because this
-	 * bundle was uninstalled while the <code>BundleActivator.start</code>
-	 * method was running, a <code>BundleException</code> is thrown.
+	 * <li>If this bundle's state is {@code UNINSTALLED}, because this bundle
+	 * was uninstalled while the {@code BundleActivator.start} method was
+	 * running, a {@code BundleException} is thrown.
 	 * 
-	 * <li>This bundle's state is set to <code>ACTIVE</code>.
+	 * <li>This bundle's state is set to {@code ACTIVE}.
 	 * 
 	 * <li>A bundle event of type {@link BundleEvent#STARTED} is fired.
 	 * </ol>
 	 * 
 	 * <b>Preconditions </b>
 	 * <ul>
-	 * <li><code>getState()</code> in &#x007B; <code>INSTALLED</code>,
-	 * <code>RESOLVED</code> &#x007D; or &#x007B; <code>INSTALLED</code>,
-	 * <code>RESOLVED</code>, <code>STARTING</code> &#x007D; if this bundle has
-	 * a lazy activation policy.
+	 * <li>{@code getState()} in &#x007B; {@code INSTALLED}, {@code RESOLVED}
+	 * &#x007D; or &#x007B; {@code INSTALLED}, {@code RESOLVED},
+	 * {@code STARTING} &#x007D; if this bundle has a lazy activation policy.
 	 * </ul>
 	 * <b>Postconditions, no exceptions thrown </b>
 	 * <ul>
 	 * <li>Bundle autostart setting is modified unless the
 	 * {@link #START_TRANSIENT} option was set.
-	 * <li><code>getState()</code> in &#x007B; <code>ACTIVE</code> &#x007D;
-	 * unless the lazy activation policy was used.
-	 * <li><code>BundleActivator.start()</code> has been called and did not
-	 * throw an exception unless the lazy activation policy was used.
+	 * <li>{@code getState()} in &#x007B; {@code ACTIVE} &#x007D; unless the
+	 * lazy activation policy was used.
+	 * <li>{@code BundleActivator.start()} has been called and did not throw an
+	 * exception unless the lazy activation policy was used.
 	 * </ul>
 	 * <b>Postconditions, when an exception is thrown </b>
 	 * <ul>
 	 * <li>Depending on when the exception occurred, bundle autostart setting is
 	 * modified unless the {@link #START_TRANSIENT} option was set.
-	 * <li><code>getState()</code> not in &#x007B; <code>STARTING</code>,
-	 * <code>ACTIVE</code> &#x007D;.
+	 * <li>{@code getState()} not in &#x007B; {@code STARTING}, {@code ACTIVE}
+	 * &#x007D;.
 	 * </ul>
 	 * 
 	 * @param options The options for starting this bundle. See
 	 *        {@link #START_TRANSIENT} and {@link #START_ACTIVATION_POLICY}. The
 	 *        Framework must ignore unrecognized options.
-	 * @throws BundleException If this bundle could not be started. This could
-	 *         be because a code dependency could not be resolved or the
-	 *         specified <code>BundleActivator</code> could not be loaded or
-	 *         threw an exception or this bundle is a fragment.
+	 * @throws BundleException If this bundle could not be started.
+	 *         BundleException types thrown by this method include:
+	 *         {@link BundleException#START_TRANSIENT_ERROR},
+	 *         {@link BundleException#NATIVECODE_ERROR},
+	 *         {@link BundleException#RESOLVE_ERROR},
+	 *         {@link BundleException#STATECHANGE_ERROR}, and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
 	 * @throws IllegalStateException If this bundle has been uninstalled or this
 	 *         bundle tries to change its own state.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,EXECUTE]</code>, and the Java Runtime
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
 	 *         Environment supports permissions.
 	 * @since 1.4
 	 */
-	public void start(int options) throws BundleException;
+	void start(int options) throws BundleException;
 
 	/**
 	 * Starts this bundle with no options.
 	 * 
 	 * <p>
-	 * This method performs the same function as calling <code>start(0)</code>.
+	 * This method performs the same function as calling {@code start(0)}.
 	 * 
-	 * @throws BundleException If this bundle could not be started. This could
-	 *         be because a code dependency could not be resolved or the
-	 *         specified <code>BundleActivator</code> could not be loaded or
-	 *         threw an exception or this bundle is a fragment.
+	 * @throws BundleException If this bundle could not be started.
+	 *         BundleException types thrown by this method include:
+	 *         {@link BundleException#NATIVECODE_ERROR},
+	 *         {@link BundleException#RESOLVE_ERROR},
+	 *         {@link BundleException#STATECHANGE_ERROR}, and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
 	 * @throws IllegalStateException If this bundle has been uninstalled or this
 	 *         bundle tries to change its own state.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,EXECUTE]</code>, and the Java Runtime
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
 	 *         Environment supports permissions.
 	 * @see #start(int)
 	 */
-	public void start() throws BundleException;
+	void start() throws BundleException;
 
 	/**
 	 * Stops this bundle.
@@ -392,58 +404,58 @@
 	 * <p>
 	 * The following steps are required to stop a bundle:
 	 * <ol>
-	 * <li>If this bundle's state is <code>UNINSTALLED</code> then an
-	 * <code>IllegalStateException</code> is thrown.
+	 * <li>If this bundle's state is {@code UNINSTALLED} then an
+	 * {@code IllegalStateException} is thrown.
 	 * 
 	 * <li>If this bundle is in the process of being activated or deactivated
 	 * then this method must wait for activation or deactivation to complete
 	 * before continuing. If this does not occur in a reasonable time, a
-	 * <code>BundleException</code> is thrown to indicate this bundle was unable
-	 * to be stopped.
+	 * {@code BundleException} is thrown to indicate this bundle was unable to
+	 * be stopped.
 	 * <li>If the {@link #STOP_TRANSIENT} option is not set then then set this
 	 * bundle's persistent autostart setting to to <em>Stopped</em>. When the
 	 * Framework is restarted and this bundle's autostart setting is
 	 * <em>Stopped</em>, this bundle must not be automatically started.
 	 * 
-	 * <li>If this bundle's state is not <code>STARTING</code> or
-	 * <code>ACTIVE</code> then this method returns immediately.
+	 * <li>If this bundle's state is not {@code STARTING} or {@code ACTIVE} then
+	 * this method returns immediately.
 	 * 
-	 * <li>This bundle's state is set to <code>STOPPING</code>.
+	 * <li>This bundle's state is set to {@code STOPPING}.
 	 * 
 	 * <li>A bundle event of type {@link BundleEvent#STOPPING} is fired.
 	 * 
-	 * <li>If this bundle's state was <code>ACTIVE</code> prior to setting the
-	 * state to <code>STOPPING</code>, the {@link BundleActivator#stop} method
-	 * of this bundle's <code>BundleActivator</code>, if one is specified, is
-	 * called. If that method throws an exception, this method must continue to
-	 * stop this bundle and a <code>BundleException</code> must be thrown after
-	 * completion of the remaining steps.
+	 * <li>If this bundle's state was {@code ACTIVE} prior to setting the state
+	 * to {@code STOPPING}, the {@link BundleActivator#stop} method of this
+	 * bundle's {@code BundleActivator}, if one is specified, is called. If that
+	 * method throws an exception, this method must continue to stop this bundle
+	 * and a {@code BundleException} must be thrown after completion of the
+	 * remaining steps.
 	 * 
 	 * <li>Any services registered by this bundle must be unregistered.
 	 * <li>Any services used by this bundle must be released.
 	 * <li>Any listeners registered by this bundle must be removed.
 	 * 
-	 * <li>If this bundle's state is <code>UNINSTALLED</code>, because this
-	 * bundle was uninstalled while the <code>BundleActivator.stop</code> method
-	 * was running, a <code>BundleException</code> must be thrown.
+	 * <li>If this bundle's state is {@code UNINSTALLED}, because this bundle
+	 * was uninstalled while the {@code BundleActivator.stop} method was
+	 * running, a {@code BundleException} must be thrown.
 	 * 
-	 * <li>This bundle's state is set to <code>RESOLVED</code>.
+	 * <li>This bundle's state is set to {@code RESOLVED}.
 	 * 
 	 * <li>A bundle event of type {@link BundleEvent#STOPPED} is fired.
 	 * </ol>
 	 * 
 	 * <b>Preconditions </b>
 	 * <ul>
-	 * <li><code>getState()</code> in &#x007B; <code>ACTIVE</code> &#x007D;.
+	 * <li>{@code getState()} in &#x007B; {@code ACTIVE} &#x007D;.
 	 * </ul>
 	 * <b>Postconditions, no exceptions thrown </b>
 	 * <ul>
 	 * <li>Bundle autostart setting is modified unless the
 	 * {@link #STOP_TRANSIENT} option was set.
-	 * <li><code>getState()</code> not in &#x007B; <code>ACTIVE</code>,
-	 * <code>STOPPING</code> &#x007D;.
-	 * <li><code>BundleActivator.stop</code> has been called and did not throw
-	 * an exception.
+	 * <li>{@code getState()} not in &#x007B; {@code ACTIVE}, {@code STOPPING}
+	 * &#x007D;.
+	 * <li>{@code BundleActivator.stop} has been called and did not throw an
+	 * exception.
 	 * </ul>
 	 * <b>Postconditions, when an exception is thrown </b>
 	 * <ul>
@@ -451,143 +463,156 @@
 	 * {@link #STOP_TRANSIENT} option was set.
 	 * </ul>
 	 * 
-	 * @param options The options for stoping this bundle. See
+	 * @param options The options for stopping this bundle. See
 	 *        {@link #STOP_TRANSIENT}. The Framework must ignore unrecognized
 	 *        options.
-	 * @throws BundleException If this bundle's <code>BundleActivator</code>
-	 *         threw an exception or this bundle is a fragment.
+	 * @throws BundleException BundleException types thrown by this method
+	 *         include: {@link BundleException#STATECHANGE_ERROR} and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
 	 * @throws IllegalStateException If this bundle has been uninstalled or this
 	 *         bundle tries to change its own state.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,EXECUTE]</code>, and the Java Runtime
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
 	 *         Environment supports permissions.
 	 * @since 1.4
 	 */
-	public void stop(int options) throws BundleException;
+	void stop(int options) throws BundleException;
 
 	/**
 	 * Stops this bundle with no options.
 	 * 
 	 * <p>
-	 * This method performs the same function as calling <code>stop(0)</code>.
+	 * This method performs the same function as calling {@code stop(0)}.
 	 * 
-	 * @throws BundleException If this bundle's <code>BundleActivator</code>
-	 *         threw an exception or this bundle is a fragment.
+	 * @throws BundleException BundleException types thrown by this method
+	 *         include: {@link BundleException#STATECHANGE_ERROR} and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
 	 * @throws IllegalStateException If this bundle has been uninstalled or this
 	 *         bundle tries to change its own state.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,EXECUTE]</code>, and the Java Runtime
+	 *         {@code AdminPermission[this,EXECUTE]}, and the Java Runtime
 	 *         Environment supports permissions.
 	 * @see #start(int)
 	 */
-	public void stop() throws BundleException;
+	void stop() throws BundleException;
 
 	/**
-	 * Updates this bundle from an <code>InputStream</code>.
+	 * Updates this bundle from an {@code InputStream}.
 	 * 
 	 * <p>
-	 * If the specified <code>InputStream</code> is <code>null</code>, the
-	 * Framework must create the <code>InputStream</code> from which to read the
-	 * updated bundle by interpreting, in an implementation dependent manner,
-	 * this bundle's {@link Constants#BUNDLE_UPDATELOCATION
-	 * Bundle-UpdateLocation} Manifest header, if present, or this bundle's
-	 * original location.
+	 * If the specified {@code InputStream} is {@code null}, the Framework must
+	 * create the {@code InputStream} from which to read the updated bundle by
+	 * interpreting, in an implementation dependent manner, this bundle's
+	 * {@link Constants#BUNDLE_UPDATELOCATION Bundle-UpdateLocation} Manifest
+	 * header, if present, or this bundle's original location.
 	 * 
 	 * <p>
-	 * If this bundle's state is <code>ACTIVE</code>, it must be stopped before
-	 * the update and started after the update successfully completes.
+	 * If this bundle's state is {@code ACTIVE}, it must be stopped before the
+	 * update and started after the update successfully completes.
 	 * 
 	 * <p>
 	 * If this bundle has exported any packages that are imported by another
-	 * bundle, these packages must not be updated. Instead, the previous package
-	 * version must remain exported until the
-	 * <code>PackageAdmin.refreshPackages</code> method has been has been called
-	 * or the Framework is relaunched.
+	 * bundle, these packages must remain exported until the
+	 * {@link FrameworkWiring#refreshBundles(java.util.Collection, FrameworkListener...)
+	 * FrameworkWiring.refreshBundles} method has been has been called or the
+	 * Framework is relaunched.
 	 * 
 	 * <p>
 	 * The following steps are required to update a bundle:
 	 * <ol>
-	 * <li>If this bundle's state is <code>UNINSTALLED</code> then an
-	 * <code>IllegalStateException</code> is thrown.
+	 * <li>If this bundle's state is {@code UNINSTALLED} then an
+	 * {@code IllegalStateException} is thrown.
 	 * 
-	 * <li>If this bundle's state is <code>ACTIVE</code>, <code>STARTING</code>
-	 * or <code>STOPPING</code>, this bundle is stopped as described in the
-	 * <code>Bundle.stop</code> method. If <code>Bundle.stop</code> throws an
-	 * exception, the exception is rethrown terminating the update.
+	 * <li>If this bundle's state is {@code ACTIVE}, {@code STARTING} or
+	 * {@code STOPPING}, this bundle is stopped as described in the
+	 * {@code Bundle.stop} method. If {@code Bundle.stop} throws an exception,
+	 * the exception is rethrown terminating the update.
 	 * 
 	 * <li>The updated version of this bundle is read from the input stream and
 	 * installed. If the Framework is unable to install the updated version of
 	 * this bundle, the original version of this bundle must be restored and a
-	 * <code>BundleException</code> must be thrown after completion of the
-	 * remaining steps.
+	 * {@code BundleException} must be thrown after completion of the remaining
+	 * steps.
 	 * 
-	 * <li>This bundle's state is set to <code>INSTALLED</code>.
+	 * <li>This bundle's state is set to {@code INSTALLED}.
 	 * 
 	 * <li>If the updated version of this bundle was successfully installed, a
 	 * bundle event of type {@link BundleEvent#UPDATED} is fired.
 	 * 
-	 * <li>If this bundle's state was originally <code>ACTIVE</code>, the
-	 * updated bundle is started as described in the <code>Bundle.start</code>
-	 * method. If <code>Bundle.start</code> throws an exception, a Framework
-	 * event of type {@link FrameworkEvent#ERROR} is fired containing the
-	 * exception.
+	 * <li>If this bundle's state was originally {@code ACTIVE}, the updated
+	 * bundle is started as described in the {@code Bundle.start} method. If
+	 * {@code Bundle.start} throws an exception, a Framework event of type
+	 * {@link FrameworkEvent#ERROR} is fired containing the exception.
 	 * </ol>
 	 * 
 	 * <b>Preconditions </b>
 	 * <ul>
-	 * <li><code>getState()</code> not in &#x007B; <code>UNINSTALLED</code>
-	 * &#x007D;.
+	 * <li>{@code getState()} not in &#x007B; {@code UNINSTALLED} &#x007D;.
 	 * </ul>
 	 * <b>Postconditions, no exceptions thrown </b>
 	 * <ul>
-	 * <li><code>getState()</code> in &#x007B; <code>INSTALLED</code>,
-	 * <code>RESOLVED</code>, <code>ACTIVE</code> &#x007D;.
+	 * <li>{@code getState()} in &#x007B; {@code INSTALLED}, {@code RESOLVED},
+	 * {@code ACTIVE} &#x007D;.
 	 * <li>This bundle has been updated.
 	 * </ul>
 	 * <b>Postconditions, when an exception is thrown </b>
 	 * <ul>
-	 * <li><code>getState()</code> in &#x007B; <code>INSTALLED</code>,
-	 * <code>RESOLVED</code>, <code>ACTIVE</code> &#x007D;.
+	 * <li>{@code getState()} in &#x007B; {@code INSTALLED}, {@code RESOLVED},
+	 * {@code ACTIVE} &#x007D;.
 	 * <li>Original bundle is still used; no update occurred.
 	 * </ul>
 	 * 
-	 * @param input The <code>InputStream</code> from which to read the new
-	 *        bundle or <code>null</code> to indicate the Framework must create
-	 *        the input stream from this bundle's
-	 *        {@link Constants#BUNDLE_UPDATELOCATION Bundle-UpdateLocation}
-	 *        Manifest header, if present, or this bundle's original location.
-	 *        The input stream must always be closed when this method completes,
-	 *        even if an exception is thrown.
-	 * @throws BundleException If the input stream cannot be read or the update
-	 *         fails.
+	 * @param input The {@code InputStream} from which to read the new bundle or
+	 *        {@code null} to indicate the Framework must create the input
+	 *        stream from this bundle's {@link Constants#BUNDLE_UPDATELOCATION
+	 *        Bundle-UpdateLocation} Manifest header, if present, or this
+	 *        bundle's original location. The input stream must always be closed
+	 *        when this method completes, even if an exception is thrown.
+	 * @throws BundleException If this bundle could not be updated.
+	 *         BundleException types thrown by this method include:
+	 *         {@link BundleException#READ_ERROR},
+	 *         {@link BundleException#DUPLICATE_BUNDLE_ERROR},
+	 *         {@link BundleException#MANIFEST_ERROR},
+	 *         {@link BundleException#NATIVECODE_ERROR},
+	 *         {@link BundleException#RESOLVE_ERROR},
+	 *         {@link BundleException#STATECHANGE_ERROR}, and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
 	 * @throws IllegalStateException If this bundle has been uninstalled or this
 	 *         bundle tries to change its own state.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,LIFECYCLE]</code> for both the current
+	 *         {@code AdminPermission[this,LIFECYCLE]} for both the current
 	 *         bundle and the updated bundle, and the Java Runtime Environment
 	 *         supports permissions.
 	 * @see #stop()
 	 * @see #start()
 	 */
-	public void update(InputStream input) throws BundleException;
+	void update(InputStream input) throws BundleException;
 
 	/**
 	 * Updates this bundle.
 	 * 
 	 * <p>
 	 * This method performs the same function as calling
-	 * {@link #update(InputStream)} with a <code>null</code> InputStream.
+	 * {@link #update(InputStream)} with a {@code null} InputStream.
 	 * 
-	 * @throws BundleException If the update fails.
+	 * @throws BundleException If this bundle could not be updated.
+	 *         BundleException types thrown by this method include:
+	 *         {@link BundleException#READ_ERROR},
+	 *         {@link BundleException#DUPLICATE_BUNDLE_ERROR},
+	 *         {@link BundleException#MANIFEST_ERROR},
+	 *         {@link BundleException#NATIVECODE_ERROR},
+	 *         {@link BundleException#RESOLVE_ERROR},
+	 *         {@link BundleException#STATECHANGE_ERROR}, and
+	 *         {@link BundleException#ACTIVATOR_ERROR}.
 	 * @throws IllegalStateException If this bundle has been uninstalled or this
 	 *         bundle tries to change its own state.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,LIFECYCLE]</code> for both the current
+	 *         {@code AdminPermission[this,LIFECYCLE]} for both the current
 	 *         bundle and the updated bundle, and the Java Runtime Environment
 	 *         supports permissions.
 	 * @see #update(InputStream)
 	 */
-	public void update() throws BundleException;
+	void update() throws BundleException;
 
 	/**
 	 * Uninstalls this bundle.
@@ -595,28 +620,29 @@
 	 * <p>
 	 * This method causes the Framework to notify other bundles that this bundle
 	 * is being uninstalled, and then puts this bundle into the
-	 * <code>UNINSTALLED</code> state. The Framework must remove any resources
+	 * {@code UNINSTALLED} state. The Framework must remove any resources
 	 * related to this bundle that it is able to remove.
 	 * 
 	 * <p>
 	 * If this bundle has exported any packages, the Framework must continue to
 	 * make these packages available to their importing bundles until the
-	 * <code>PackageAdmin.refreshPackages</code> method has been called or the
-	 * Framework is relaunched.
+	 * {@link FrameworkWiring#refreshBundles(java.util.Collection, FrameworkListener...)
+	 * FrameworkWiring.refreshBundles} method has been called or the Framework
+	 * is relaunched.
 	 * 
 	 * <p>
 	 * The following steps are required to uninstall a bundle:
 	 * <ol>
-	 * <li>If this bundle's state is <code>UNINSTALLED</code> then an
-	 * <code>IllegalStateException</code> is thrown.
+	 * <li>If this bundle's state is {@code UNINSTALLED} then an
+	 * {@code IllegalStateException} is thrown.
 	 * 
-	 * <li>If this bundle's state is <code>ACTIVE</code>, <code>STARTING</code>
-	 * or <code>STOPPING</code>, this bundle is stopped as described in the
-	 * <code>Bundle.stop</code> method. If <code>Bundle.stop</code> throws an
-	 * exception, a Framework event of type {@link FrameworkEvent#ERROR} is
-	 * fired containing the exception.
+	 * <li>If this bundle's state is {@code ACTIVE}, {@code STARTING} or
+	 * {@code STOPPING}, this bundle is stopped as described in the
+	 * {@code Bundle.stop} method. If {@code Bundle.stop} throws an exception, a
+	 * Framework event of type {@link FrameworkEvent#ERROR} is fired containing
+	 * the exception.
 	 * 
-	 * <li>This bundle's state is set to <code>UNINSTALLED</code>.
+	 * <li>This bundle's state is set to {@code UNINSTALLED}.
 	 * 
 	 * <li>A bundle event of type {@link BundleEvent#UNINSTALLED} is fired.
 	 * 
@@ -626,33 +652,32 @@
 	 * 
 	 * <b>Preconditions </b>
 	 * <ul>
-	 * <li><code>getState()</code> not in &#x007B; <code>UNINSTALLED</code>
-	 * &#x007D;.
+	 * <li>{@code getState()} not in &#x007B; {@code UNINSTALLED} &#x007D;.
 	 * </ul>
 	 * <b>Postconditions, no exceptions thrown </b>
 	 * <ul>
-	 * <li><code>getState()</code> in &#x007B; <code>UNINSTALLED</code>
-	 * &#x007D;.
+	 * <li>{@code getState()} in &#x007B; {@code UNINSTALLED} &#x007D;.
 	 * <li>This bundle has been uninstalled.
 	 * </ul>
 	 * <b>Postconditions, when an exception is thrown </b>
 	 * <ul>
-	 * <li><code>getState()</code> not in &#x007B; <code>UNINSTALLED</code>
-	 * &#x007D;.
+	 * <li>{@code getState()} not in &#x007B; {@code UNINSTALLED} &#x007D;.
 	 * <li>This Bundle has not been uninstalled.
 	 * </ul>
 	 * 
 	 * @throws BundleException If the uninstall failed. This can occur if
 	 *         another thread is attempting to change this bundle's state and
-	 *         does not complete in a timely manner.
+	 *         does not complete in a timely manner. BundleException types
+	 *         thrown by this method include:
+	 *         {@link BundleException#STATECHANGE_ERROR}
 	 * @throws IllegalStateException If this bundle has been uninstalled or this
 	 *         bundle tries to change its own state.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,LIFECYCLE]</code>, and the Java
-	 *         Runtime Environment supports permissions.
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java Runtime
+	 *         Environment supports permissions.
 	 * @see #stop()
 	 */
-	public void uninstall() throws BundleException;
+	void uninstall() throws BundleException;
 
 	/**
 	 * Returns this bundle's Manifest headers and values. This method returns
@@ -661,7 +686,7 @@
 	 * 
 	 * <p>
 	 * Manifest header names are case-insensitive. The methods of the returned
-	 * <code>Dictionary</code> object must operate on header names in a
+	 * {@code Dictionary} object must operate on header names in a
 	 * case-insensitive manner.
 	 * 
 	 * If a Manifest header value starts with &quot;%&quot;, it must be
@@ -684,16 +709,16 @@
 	 * 
 	 * <p>
 	 * This method must continue to return Manifest header information while
-	 * this bundle is in the <code>UNINSTALLED</code> state.
+	 * this bundle is in the {@code UNINSTALLED} state.
 	 * 
-	 * @return A <code>Dictionary</code> object containing this bundle's
-	 *         Manifest headers and values.
-	 * @throws SecurityException If the caller does not have the
-	 *         appropriate <code>AdminPermission[this,METADATA]</code>, and
-	 *         the Java Runtime Environment supports permissions.
+	 * @return An unmodifiable {@code Dictionary} object containing this
+	 *         bundle's Manifest headers and values.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,METADATA]}, and the Java Runtime
+	 *         Environment supports permissions.
 	 * @see Constants#BUNDLE_LOCALIZATION
 	 */
-	public Dictionary/* <String,String> */getHeaders();
+	Dictionary<String, String> getHeaders();
 
 	/**
 	 * Returns this bundle's unique identifier. This bundle is assigned a unique
@@ -704,7 +729,7 @@
 	 * A bundle's unique identifier has the following attributes:
 	 * <ul>
 	 * <li>Is unique and persistent.
-	 * <li>Is a <code>long</code>.
+	 * <li>Is a {@code long}.
 	 * <li>Its value is not reused for another bundle, even after a bundle is
 	 * uninstalled.
 	 * <li>Does not change while a bundle remains installed.
@@ -713,151 +738,142 @@
 	 * 
 	 * <p>
 	 * This method must continue to return this bundle's unique identifier while
-	 * this bundle is in the <code>UNINSTALLED</code> state.
+	 * this bundle is in the {@code UNINSTALLED} state.
 	 * 
 	 * @return The unique identifier of this bundle.
 	 */
-	public long getBundleId();
+	long getBundleId();
 
 	/**
 	 * Returns this bundle's location identifier.
 	 * 
 	 * <p>
-	 * The location identifier is the location passed to
-	 * <code>BundleContext.installBundle</code> when a bundle is installed.
-	 * The location identifier does not change while this bundle remains
-	 * installed, even if this bundle is updated.
+	 * The location identifier is the location passed to {@code
+	 * BundleContext.installBundle} when a bundle is installed. The location
+	 * identifier does not change while this bundle remains installed, even if
+	 * this bundle is updated.
 	 * 
 	 * <p>
 	 * This method must continue to return this bundle's location identifier
-	 * while this bundle is in the <code>UNINSTALLED</code> state.
+	 * while this bundle is in the {@code UNINSTALLED} state.
 	 * 
 	 * @return The string representation of this bundle's location identifier.
-	 * @throws SecurityException If the caller does not have the
-	 *         appropriate <code>AdminPermission[this,METADATA]</code>, and
-	 *         the Java Runtime Environment supports permissions.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,METADATA]}, and the Java Runtime
+	 *         Environment supports permissions.
 	 */
-	public String getLocation();
+	String getLocation();
 
 	/**
-	 * Returns this bundle's <code>ServiceReference</code> list for all
-	 * services it has registered or <code>null</code> if this bundle has no
-	 * registered services.
+	 * Returns this bundle's {@code ServiceReference} list for all services it
+	 * has registered or {@code null} if this bundle has no registered services.
 	 * 
 	 * <p>
-	 * If the Java runtime supports permissions, a <code>ServiceReference</code>
+	 * If the Java runtime supports permissions, a {@code ServiceReference}
 	 * object to a service is included in the returned list only if the caller
-	 * has the <code>ServicePermission</code> to get the service using at
-	 * least one of the named classes the service was registered under.
+	 * has the {@code ServicePermission} to get the service using at least one
+	 * of the named classes the service was registered under.
 	 * 
 	 * <p>
 	 * The list is valid at the time of the call to this method, however, as the
 	 * Framework is a very dynamic environment, services can be modified or
 	 * unregistered at anytime.
 	 * 
-	 * @return An array of <code>ServiceReference</code> objects or
-	 *         <code>null</code>.
-	 * @throws IllegalStateException If this bundle has been
-	 *         uninstalled.
+	 * @return An array of {@code ServiceReference} objects or {@code null}.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @see ServiceRegistration
 	 * @see ServiceReference
 	 * @see ServicePermission
 	 */
-	public ServiceReference[] getRegisteredServices();
+	ServiceReference< ? >[] getRegisteredServices();
 
 	/**
-	 * Returns this bundle's <code>ServiceReference</code> list for all
-	 * services it is using or returns <code>null</code> if this bundle is not
-	 * using any services. A bundle is considered to be using a service if its
-	 * use count for that service is greater than zero.
+	 * Returns this bundle's {@code ServiceReference} list for all services it
+	 * is using or returns {@code null} if this bundle is not using any
+	 * services. A bundle is considered to be using a service if its use count
+	 * for that service is greater than zero.
 	 * 
 	 * <p>
-	 * If the Java Runtime Environment supports permissions, a
-	 * <code>ServiceReference</code> object to a service is included in the
-	 * returned list only if the caller has the <code>ServicePermission</code>
-	 * to get the service using at least one of the named classes the service
-	 * was registered under.
+	 * If the Java Runtime Environment supports permissions, a {@code
+	 * ServiceReference} object to a service is included in the returned list
+	 * only if the caller has the {@code ServicePermission} to get the service
+	 * using at least one of the named classes the service was registered under.
 	 * <p>
 	 * The list is valid at the time of the call to this method, however, as the
 	 * Framework is a very dynamic environment, services can be modified or
 	 * unregistered at anytime.
 	 * 
-	 * @return An array of <code>ServiceReference</code> objects or
-	 *         <code>null</code>.
-	 * @throws IllegalStateException If this bundle has been
-	 *         uninstalled.
+	 * @return An array of {@code ServiceReference} objects or {@code null}.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @see ServiceReference
 	 * @see ServicePermission
 	 */
-	public ServiceReference[] getServicesInUse();
+	ServiceReference< ? >[] getServicesInUse();
 
 	/**
 	 * Determines if this bundle has the specified permissions.
 	 * 
 	 * <p>
 	 * If the Java Runtime Environment does not support permissions, this method
-	 * always returns <code>true</code>.
+	 * always returns {@code true}.
 	 * <p>
-	 * <code>permission</code> is of type <code>Object</code> to avoid
-	 * referencing the <code>java.security.Permission</code> class directly.
-	 * This is to allow the Framework to be implemented in Java environments
-	 * which do not support permissions.
+	 * {@code permission} is of type {@code Object} to avoid referencing the
+	 * {@code java.security.Permission} class directly. This is to allow the
+	 * Framework to be implemented in Java environments which do not support
+	 * permissions.
 	 * 
 	 * <p>
 	 * If the Java Runtime Environment does support permissions, this bundle and
 	 * all its resources including embedded JAR files, belong to the same
-	 * <code>java.security.ProtectionDomain</code>; that is, they must share
-	 * the same set of permissions.
+	 * {@code java.security.ProtectionDomain}; that is, they must share the same
+	 * set of permissions.
 	 * 
 	 * @param permission The permission to verify.
-	 * @return <code>true</code> if this bundle has the specified permission
-	 *         or the permissions possessed by this bundle imply the specified
-	 *         permission; <code>false</code> if this bundle does not have the
-	 *         specified permission or <code>permission</code> is not an
-	 *         <code>instanceof</code> <code>java.security.Permission</code>.
-	 * @throws IllegalStateException If this bundle has been
-	 *         uninstalled.
+	 * @return {@code true} if this bundle has the specified permission or the
+	 *         permissions possessed by this bundle imply the specified
+	 *         permission; {@code false} if this bundle does not have the
+	 *         specified permission or {@code permission} is not an {@code
+	 *         instanceof} {@code java.security.Permission}.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 */
-	public boolean hasPermission(Object permission);
+	boolean hasPermission(Object permission);
 
 	/**
 	 * Find the specified resource from this bundle's class loader.
 	 * 
 	 * This bundle's class loader is called to search for the specified
-	 * resource. If this bundle's state is <code>INSTALLED</code>, this method
-	 * must attempt to resolve this bundle before attempting to get the
-	 * specified resource. If this bundle cannot be resolved, then only this
-	 * bundle must be searched for the specified resource. Imported packages
-	 * cannot be searched when this bundle has not been resolved. If this bundle
-	 * is a fragment bundle then <code>null</code> is returned.
+	 * resource. If this bundle's state is {@code INSTALLED}, this method must
+	 * attempt to resolve this bundle before attempting to get the specified
+	 * resource. If this bundle cannot be resolved, then only this bundle must
+	 * be searched for the specified resource. Imported packages cannot be
+	 * searched when this bundle has not been resolved. If this bundle is a
+	 * fragment bundle then {@code null} is returned.
 	 * <p>
 	 * Note: Jar and zip files are not required to include directory entries.
 	 * URLs to directory entries will not be returned if the bundle contents do
 	 * not contain directory entries.
 	 * 
-	 * @param name The name of the resource. See
-	 *        <code>ClassLoader.getResource</code> for a description of the
-	 *        format of a resource name.
-	 * @return A URL to the named resource, or <code>null</code> if the resource
+	 * @param name The name of the resource. See {@code ClassLoader.getResource}
+	 *        for a description of the format of a resource name.
+	 * @return A URL to the named resource, or {@code null} if the resource
 	 *         could not be found or if this bundle is a fragment bundle or if
-	 *         the caller does not have the appropriate
-	 *         <code>AdminPermission[this,RESOURCE]</code>, and the Java Runtime
-	 *         Environment supports permissions.
+	 *         the caller does not have the appropriate {@code
+	 *         AdminPermission[this,RESOURCE]}, and the Java Runtime Environment
+	 *         supports permissions.
 	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @see #getEntry
 	 * @see #findEntries
 	 * @since 1.1
 	 */
-	public URL getResource(String name);
+	URL getResource(String name);
 
 	/**
 	 * Returns this bundle's Manifest headers and values localized to the
 	 * specified locale.
 	 * 
 	 * <p>
-	 * This method performs the same function as
-	 * <code>Bundle.getHeaders()</code> except the manifest header values are
-	 * localized to the specified locale.
+	 * This method performs the same function as {@code Bundle.getHeaders()}
+	 * except the manifest header values are localized to the specified locale.
 	 * 
 	 * <p>
 	 * If a Manifest header value starts with &quot;%&quot;, it must be
@@ -875,128 +891,122 @@
 	 *   bn
 	 * </pre>
 	 * 
-	 * Where <code>bn</code> is this bundle's localization basename,
-	 * <code>Ls</code>, <code>Cs</code> and <code>Vs</code> are the
-	 * specified locale (language, country, variant) and <code>Ld</code>,
-	 * <code>Cd</code> and <code>Vd</code> are the default locale (language,
-	 * country, variant).
+	 * Where {@code bn} is this bundle's localization basename, {@code Ls},
+	 * {@code Cs} and {@code Vs} are the specified locale (language, country,
+	 * variant) and {@code Ld}, {@code Cd} and {@code Vd} are the default locale
+	 * (language, country, variant).
 	 * 
-	 * If <code>null</code> is specified as the locale string, the header
-	 * values must be localized using the default locale. If the empty string
-	 * (&quot;&quot;) is specified as the locale string, the header values must
-	 * not be localized and the raw (unlocalized) header values, including any
-	 * leading &quot;%&quot;, must be returned. If no localization is found for
-	 * a header value, the header value without the leading &quot;%&quot; is
-	 * returned.
+	 * If {@code null} is specified as the locale string, the header values must
+	 * be localized using the default locale. If the empty string (&quot;&quot;)
+	 * is specified as the locale string, the header values must not be
+	 * localized and the raw (unlocalized) header values, including any leading
+	 * &quot;%&quot;, must be returned. If no localization is found for a header
+	 * value, the header value without the leading &quot;%&quot; is returned.
 	 * 
 	 * <p>
 	 * This method must continue to return Manifest header information while
-	 * this bundle is in the <code>UNINSTALLED</code> state, however the
-	 * header values must only be available in the raw and default locale
-	 * values.
+	 * this bundle is in the {@code UNINSTALLED} state, however the header
+	 * values must only be available in the raw and default locale values.
 	 * 
 	 * @param locale The locale name into which the header values are to be
-	 *        localized. If the specified locale is <code>null</code> then the
-	 *        locale returned by <code>java.util.Locale.getDefault</code> is
-	 *        used. If the specified locale is the empty string, this method
-	 *        will return the raw (unlocalized) manifest headers including any
-	 *        leading &quot;%&quot;.
-	 * @return A <code>Dictionary</code> object containing this bundle's
-	 *         Manifest headers and values.
-	 * @throws SecurityException If the caller does not have the
-	 *         appropriate <code>AdminPermission[this,METADATA]</code>, and
-	 *         the Java Runtime Environment supports permissions.
+	 *        localized. If the specified locale is {@code null} then the locale
+	 *        returned by {@code java.util.Locale.getDefault} is used. If the
+	 *        specified locale is the empty string, this method will return the
+	 *        raw (unlocalized) manifest headers including any leading
+	 *        &quot;%&quot;.
+	 * @return An unmodifiable {@code Dictionary} object containing this
+	 *         bundle's Manifest headers and values.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,METADATA]}, and the Java Runtime
+	 *         Environment supports permissions.
 	 * @see #getHeaders()
 	 * @see Constants#BUNDLE_LOCALIZATION
 	 * @since 1.3
 	 */
-	public Dictionary/* <String,String> */getHeaders(String locale);
+	Dictionary<String, String> getHeaders(String locale);
 
 	/**
-	 * Returns the symbolic name of this bundle as specified by its
-	 * <code>Bundle-SymbolicName</code> manifest header. 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 naming
-	 * convention like that used for java packages.
+	 * Returns the symbolic name of this bundle as specified by its {@code
+	 * Bundle-SymbolicName} manifest header. The bundle symbolic name should be
+	 * based on the reverse domain name naming convention like that used for
+	 * java packages.
 	 * 
 	 * <p>
 	 * This method must continue to return this bundle's symbolic name while
-	 * this bundle is in the <code>UNINSTALLED</code> state.
+	 * this bundle is in the {@code UNINSTALLED} state.
 	 * 
-	 * @return The symbolic name of this bundle or <code>null</code> if this
-	 *         bundle does not have a symbolic name.
+	 * @return The symbolic name of this bundle or {@code null} if this bundle
+	 *         does not have a symbolic name.
 	 * @since 1.3
 	 */
-	public String getSymbolicName();
+	String getSymbolicName();
 
 	/**
 	 * Loads the specified class using this bundle's class loader.
 	 * 
 	 * <p>
-	 * If this bundle is a fragment bundle then this method must throw a
-	 * <code>ClassNotFoundException</code>.
+	 * If this bundle is a fragment bundle then this method must throw a {@code
+	 * ClassNotFoundException}.
 	 * 
 	 * <p>
-	 * If this bundle's state is <code>INSTALLED</code>, this method must
-	 * attempt to resolve this bundle before attempting to load the class.
+	 * If this bundle's state is {@code INSTALLED}, this method must attempt to
+	 * resolve this bundle before attempting to load the class.
 	 * 
 	 * <p>
 	 * If this bundle cannot be resolved, a Framework event of type
-	 * {@link FrameworkEvent#ERROR} is fired containing a
-	 * <code>BundleException</code> with details of the reason this bundle
-	 * could not be resolved. This method must then throw a
-	 * <code>ClassNotFoundException</code>.
+	 * {@link FrameworkEvent#ERROR} is fired containing a {@code
+	 * BundleException} with details of the reason this bundle could not be
+	 * resolved. This method must then throw a {@code ClassNotFoundException}.
 	 * 
 	 * <p>
-	 * If this bundle's state is <code>UNINSTALLED</code>, then an
-	 * <code>IllegalStateException</code> is thrown.
+	 * If this bundle's state is {@code UNINSTALLED}, then an {@code
+	 * IllegalStateException} is thrown.
 	 * 
 	 * @param name The name of the class to load.
 	 * @return The Class object for the requested class.
-	 * @throws ClassNotFoundException If no such class can be found or
-	 *         if this bundle is a fragment bundle or if the caller does not
-	 *         have the appropriate <code>AdminPermission[this,CLASS]</code>,
-	 *         and the Java Runtime Environment supports permissions.
-	 * @throws IllegalStateException If this bundle has been
-	 *         uninstalled.
+	 * @throws ClassNotFoundException If no such class can be found or if this
+	 *         bundle is a fragment bundle or if the caller does not have the
+	 *         appropriate {@code AdminPermission[this,CLASS]}, and the Java
+	 *         Runtime Environment supports permissions.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @since 1.3
 	 */
-	public Class loadClass(String name) throws ClassNotFoundException;
+	Class< ? > loadClass(String name) throws ClassNotFoundException;
 
 	/**
 	 * Find the specified resources from this bundle's class loader.
 	 * 
 	 * This bundle's class loader is called to search for the specified
-	 * resources. If this bundle's state is <code>INSTALLED</code>, this method
-	 * must attempt to resolve this bundle before attempting to get the
-	 * specified resources. If this bundle cannot be resolved, then only this
-	 * bundle must be searched for the specified resources. Imported packages
-	 * cannot be searched when a bundle has not been resolved. If this bundle is
-	 * a fragment bundle then <code>null</code> is returned.
+	 * resources. If this bundle's state is {@code INSTALLED}, this method must
+	 * attempt to resolve this bundle before attempting to get the specified
+	 * resources. If this bundle cannot be resolved, then only this bundle must
+	 * be searched for the specified resources. Imported packages cannot be
+	 * searched when a bundle has not been resolved. If this bundle is a
+	 * fragment bundle then {@code null} is returned.
 	 * <p>
 	 * Note: Jar and zip files are not required to include directory entries.
 	 * URLs to directory entries will not be returned if the bundle contents do
 	 * not contain directory entries.
 	 * 
-	 * @param name The name of the resource. See
-	 *        <code>ClassLoader.getResources</code> for a description of the
-	 *        format of a resource name.
-	 * @return An enumeration of URLs to the named resources, or
-	 *         <code>null</code> if the resource could not be found or if this
-	 *         bundle is a fragment bundle or if the caller does not have the
-	 *         appropriate <code>AdminPermission[this,RESOURCE]</code>, and the
-	 *         Java Runtime Environment supports permissions.
+	 * @param name The name of the resource. See {@code
+	 *        ClassLoader.getResources} for a description of the format of a
+	 *        resource name.
+	 * @return An enumeration of URLs to the named resources, or {@code null} if
+	 *         the resource could not be found or if this bundle is a fragment
+	 *         bundle or if the caller does not have the appropriate {@code
+	 *         AdminPermission[this,RESOURCE]}, and the Java Runtime Environment
+	 *         supports permissions.
 	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @throws IOException If there is an I/O error.
 	 * @since 1.3
 	 */
-	public Enumeration/* <URL> */getResources(String name) throws IOException;
+	Enumeration<URL> getResources(String name) throws IOException;
 
 	/**
-	 * Returns an Enumeration of all the paths (<code>String</code> objects)
-	 * to entries within this bundle whose longest sub-path matches the
-	 * specified path. This bundle's class loader is not used to search for
-	 * entries. Only the contents of this bundle are searched.
+	 * Returns an Enumeration of all the paths ({@code String} objects) to
+	 * entries within this bundle whose longest sub-path matches the specified
+	 * path. This bundle's class loader is not used to search for entries. Only
+	 * the contents of this bundle are searched.
 	 * <p>
 	 * The specified path is always relative to the root of this bundle and may
 	 * begin with a &quot;/&quot;. A path value of &quot;/&quot; indicates the
@@ -1011,16 +1021,14 @@
 	 * not contain directory entries.
 	 * 
 	 * @param path The path name for which to return entry paths.
-	 * @return An Enumeration of the entry paths (<code>String</code>
-	 *         objects) or <code>null</code> if no entry could be found or if
-	 *         the caller does not have the appropriate
-	 *         <code>AdminPermission[this,RESOURCE]</code> and the Java
-	 *         Runtime Environment supports permissions.
-	 * @throws IllegalStateException If this bundle has been
-	 *         uninstalled.
+	 * @return An Enumeration of the entry paths ({@code String} objects) or
+	 *         {@code null} if no entry could be found or if the caller does not
+	 *         have the appropriate {@code AdminPermission[this,RESOURCE]} and
+	 *         the Java Runtime Environment supports permissions.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @since 1.3
 	 */
-	public Enumeration/* <String> */getEntryPaths(String path);
+	Enumeration<String> getEntryPaths(String path);
 
 	/**
 	 * Returns a URL to the entry at the specified path in this bundle. This
@@ -1036,15 +1044,14 @@
 	 * not contain directory entries.
 	 * 
 	 * @param path The path name of the entry.
-	 * @return A URL to the entry, or <code>null</code> if no entry could be
-	 *         found or if the caller does not have the appropriate
-	 *         <code>AdminPermission[this,RESOURCE]</code> and the Java
-	 *         Runtime Environment supports permissions.
-	 * @throws IllegalStateException If this bundle has been
-	 *         uninstalled.
+	 * @return A URL to the entry, or {@code null} if no entry could be found or
+	 *         if the caller does not have the appropriate {@code
+	 *         AdminPermission[this,RESOURCE]} and the Java Runtime Environment
+	 *         supports permissions.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @since 1.3
 	 */
-	public URL getEntry(String path);
+	URL getEntry(String path);
 
 	/**
 	 * Returns the time when this bundle was last modified. A bundle is
@@ -1057,21 +1064,21 @@
 	 * @return The time when this bundle was last modified.
 	 * @since 1.3
 	 */
-	public long getLastModified();
+	long getLastModified();
 
 	/**
 	 * Returns entries in this bundle and its attached fragments. This bundle's
 	 * class loader is not used to search for entries. Only the contents of this
 	 * bundle and its attached fragments are searched for the specified entries.
 	 * 
-	 * If this bundle's state is <code>INSTALLED</code>, this method must
-	 * attempt to resolve this bundle before attempting to find entries.
+	 * If this bundle's state is {@code INSTALLED}, this method must attempt to
+	 * resolve this bundle before attempting to find entries.
 	 * 
 	 * <p>
 	 * This method is intended to be used to obtain configuration, setup,
 	 * localization and other information from this bundle. This method takes
 	 * into account that the &quot;contents&quot; of this bundle can be extended
-	 * with fragments. This &quot;bundle space&quot; is not a namespace with
+	 * with fragments. This &quot;bundle space&quot; is not a name space with
 	 * unique members; the same entry name can be present multiple times. This
 	 * method therefore returns an enumeration of URL objects. These URLs can
 	 * come from different JARs but have the same path name. This method can
@@ -1111,44 +1118,41 @@
 	 *        using the wildcard character (&quot;*&quot;). If null is
 	 *        specified, this is equivalent to &quot;*&quot; and matches all
 	 *        files.
-	 * @param recurse If <code>true</code>, recurse into subdirectories.
-	 *        Otherwise only return entries from the specified path.
+	 * @param recurse If {@code true}, recurse into subdirectories. Otherwise
+	 *        only return entries from the specified path.
 	 * @return An enumeration of URL objects for each matching entry, or
-	 *         <code>null</code> if an entry could not be found or if the caller
-	 *         does not have the appropriate
-	 *         <code>AdminPermission[this,RESOURCE]</code>, and the Java Runtime
+	 *         {@code null} if no matching entry could not be found or if the
+	 *         caller does not have the appropriate
+	 *         {@code AdminPermission[this,RESOURCE]}, and the Java Runtime
 	 *         Environment supports permissions. The URLs are sorted such that
 	 *         entries from this bundle are returned first followed by the
-	 *         entries from attached fragments in ascending bundle id order. If
-	 *         this bundle is a fragment, then only matching entries in this
-	 *         fragment are returned.
+	 *         entries from attached fragments in attachment order. If this
+	 *         bundle is a fragment, then only matching entries in this fragment
+	 *         are returned.
 	 * @throws IllegalStateException If this bundle has been uninstalled.
 	 * @since 1.3
 	 */
-	public Enumeration/* <URL> */findEntries(String path, String filePattern,
+	Enumeration<URL> findEntries(String path, String filePattern,
 			boolean recurse);
 
 	/**
-	 * Returns this bundle's {@link BundleContext}. The returned
-	 * <code>BundleContext</code> can be used by the caller to act on behalf
-	 * of this bundle.
+	 * Returns this bundle's {@link BundleContext}. The returned {@code
+	 * BundleContext} can be used by the caller to act on behalf of this bundle.
 	 * 
 	 * <p>
 	 * If this bundle is not in the {@link #STARTING}, {@link #ACTIVE}, or
 	 * {@link #STOPPING} states or this bundle is a fragment bundle, then this
-	 * bundle has no valid <code>BundleContext</code>. This method will
-	 * return <code>null</code> if this bundle has no valid
-	 * <code>BundleContext</code>.
+	 * bundle has no valid {@code BundleContext}. This method will return
+	 * {@code null} if this bundle has no valid {@code BundleContext}.
 	 * 
-	 * @return A <code>BundleContext</code> for this bundle or
-	 *         <code>null</code> if this bundle has no valid
-	 *         <code>BundleContext</code>.
-	 * @throws SecurityException If the caller does not have the
-	 *         appropriate <code>AdminPermission[this,CONTEXT]</code>, and
-	 *         the Java Runtime Environment supports permissions.
+	 * @return A {@code BundleContext} for this bundle or {@code null} if this
+	 *         bundle has no valid {@code BundleContext}.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdminPermission[this,CONTEXT]}, and the Java Runtime
+	 *         Environment supports permissions.
 	 * @since 1.4
 	 */
-	public BundleContext getBundleContext();
+	BundleContext getBundleContext();
 
 	/**
 	 * Return the certificates for the signers of this bundle and the
@@ -1158,37 +1162,81 @@
 	 *        on all signers of this bundle is returned. If
 	 *        {@link #SIGNERS_TRUSTED} is specified, then only information on
 	 *        the signers of this bundle trusted by the framework is returned.
-	 * @return The <code>X509Certificate</code>s for the signers of this bundle
-	 *         and the <code>X509Certificate</code> chains for those signers.
-	 *         The keys of the <code>Map</code> are the
-	 *         <code>X509Certificate</code>s of the signers of this bundle. The
-	 *         value for a key is a <code>List</code> containing the
-	 *         <code>X509Certificate</code> chain for the signer. The first item
-	 *         in the <code>List</code> is the signer's
-	 *         <code>X509Certificate</code> which is then followed by the rest
-	 *         of the <code>X509Certificate</code> chain. The returned
-	 *         <code>Map</code> will be empty if there are no signers. The
-	 *         returned <code>Map</code> is the property of the caller who is
-	 *         free to modify it.
-	 * @throws IllegalArgumentException If the specified
-	 *         <code>signersType</code> is not {@link #SIGNERS_ALL} or
-	 *         {@link #SIGNERS_TRUSTED}.
+	 * @return The {@code X509Certificate}s for the signers of this bundle and
+	 *         the {@code X509Certificate} chains for those signers. The keys of
+	 *         the {@code Map} are the {@code X509Certificate}s of the signers
+	 *         of this bundle. The value for a key is a {@code List} containing
+	 *         the {@code X509Certificate} chain for the signer. The first item
+	 *         in the {@code List} is the signer's {@code X509Certificate} which
+	 *         is then followed by the rest of the {@code X509Certificate}
+	 *         chain. The returned {@code Map} will be empty if there are no
+	 *         signers. The returned {@code Map} is the property of the caller
+	 *         who is free to modify it.
+	 * @throws IllegalArgumentException If the specified {@code signersType} is
+	 *         not {@link #SIGNERS_ALL} or {@link #SIGNERS_TRUSTED}.
 	 * @since 1.5
 	 */
-	public Map/* <X509Certificate, List<X509Certificate>> */getSignerCertificates(
+	Map<X509Certificate, List<X509Certificate>> getSignerCertificates(
 			int signersType);
-	
+
 	/**
-	 * Returns the version of this bundle as specified by its
-	 * <code>Bundle-Version</code> manifest header. If this bundle does not have a
-	 * specified version then {@link Version#emptyVersion} is returned.
+	 * Returns the version of this bundle as specified by its {@code
+	 * Bundle-Version} manifest header. If this bundle does not have a specified
+	 * version then {@link Version#emptyVersion} is returned.
 	 * 
 	 * <p>
-	 * This method must continue to return this bundle's version while
-	 * this bundle is in the <code>UNINSTALLED</code> state.
+	 * This method must continue to return this bundle's version while this
+	 * bundle is in the {@code UNINSTALLED} state.
 	 * 
 	 * @return The version of this bundle.
 	 * @since 1.5
 	 */
-	public Version getVersion();
+	Version getVersion();
+
+	/**
+	 * Adapt this bundle to the specified type.
+	 * 
+	 * <p>
+	 * Adapting this bundle to the specified type may require certain checks,
+	 * including security checks, to succeed. If a check does not succeed, then
+	 * this bundle cannot be adapted and {@code null} is returned.
+	 * 
+	 * @param <A> The type to which this bundle is to be adapted.
+	 * @param type Class object for the type to which this bundle is to be
+	 *        adapted.
+	 * @return The object, of the specified type, to which this bundle has been
+	 *         adapted or {@code null} if this bundle cannot be adapted to the
+	 *         specified type.
+	 * @throws SecurityException If the caller does not have the appropriate
+	 *         {@code AdaptPermission[type,this,ADAPT]}, and the Java Runtime
+	 *         Environment supports permissions.
+	 * @since 1.6
+	 */
+	<A> A adapt(Class<A> type);
+
+	/**
+	 * Creates a {@code File} object for a file in the persistent storage area
+	 * provided for this bundle by the Framework. This method will return
+	 * {@code null} if the platform does not have file system support or this
+	 * bundle is a fragment bundle.
+	 * 
+	 * <p>
+	 * A {@code File} object for the base directory of the persistent storage
+	 * area provided for this bundle by the Framework can be obtained by calling
+	 * this method with an empty string as {@code filename}.
+	 * 
+	 * <p>
+	 * If the Java Runtime Environment supports permissions, the Framework will
+	 * ensure that this bundle has the {@code java.io.FilePermission} with
+	 * actions {@code read},{@code write},{@code delete} for all files
+	 * (recursively) in the persistent storage area provided for this bundle.
+	 * 
+	 * @param filename A relative name to the file to be accessed.
+	 * @return A {@code File} object that represents the requested file or
+	 *         {@code null} if the platform does not have file system support or
+	 *         this bundle is a fragment bundle.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @since 1.6
+	 */
+	File getDataFile(String filename);
 }
diff --git a/framework/src/main/java/org/osgi/framework/BundleActivator.java b/framework/src/main/java/org/osgi/framework/BundleActivator.java
index 56660b1..aefb036 100644
--- a/framework/src/main/java/org/osgi/framework/BundleActivator.java
+++ b/framework/src/main/java/org/osgi/framework/BundleActivator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,33 +19,33 @@
 /**
  * Customizes the starting and stopping of a bundle.
  * <p>
- * <code>BundleActivator</code> is an interface that may be implemented when a
+ * {@code BundleActivator} is an interface that may be implemented when a
  * bundle is started or stopped. The Framework can create instances of a
- * bundle's <code>BundleActivator</code> as required. If an instance's
- * <code>BundleActivator.start</code> method executes successfully, it is
- * guaranteed that the same instance's <code>BundleActivator.stop</code>
+ * bundle's {@code BundleActivator} as required. If an instance's
+ * {@code BundleActivator.start} method executes successfully, it is
+ * guaranteed that the same instance's {@code BundleActivator.stop}
  * method will be called when the bundle is to be stopped. The Framework must
- * not concurrently call a <code>BundleActivator</code> object.
+ * not concurrently call a {@code BundleActivator} object.
  * 
  * <p>
- * <code>BundleActivator</code> is specified through the
- * <code>Bundle-Activator</code> Manifest header. A bundle can only specify a
- * single <code>BundleActivator</code> in the Manifest file. Fragment bundles
- * must not have a <code>BundleActivator</code>. The form of the Manifest
+ * {@code BundleActivator} is specified through the
+ * {@code Bundle-Activator} Manifest header. A bundle can only specify a
+ * single {@code BundleActivator} in the Manifest file. Fragment bundles
+ * must not have a {@code BundleActivator}. The form of the Manifest
  * header is:
  * 
  * <p>
- * <code>Bundle-Activator: <i>class-name</i></code>
+ * {@code Bundle-Activator: <i>class-name</i>}
  * 
  * <p>
- * where <code><i>class-name</i></code> is a fully qualified Java classname.
+ * where {@code <i>class-name</i>} is a fully qualified Java classname.
  * <p>
- * The specified <code>BundleActivator</code> class must have a public
- * constructor that takes no parameters so that a <code>BundleActivator</code>
- * object can be created by <code>Class.newInstance()</code>.
+ * The specified {@code BundleActivator} class must have a public
+ * constructor that takes no parameters so that a {@code BundleActivator}
+ * object can be created by {@code Class.newInstance()}.
  * 
  * @NotThreadSafe
- * @version $Revision: 6361 $
+ * @version $Id: 1b73057bd270ab07f0a16430dba16e5132eea24f $
  */
 
 public interface BundleActivator {
@@ -69,7 +69,7 @@
 	/**
 	 * Called when this bundle is stopped so the Framework can perform the
 	 * bundle-specific activities necessary to stop the bundle. In general, this
-	 * method should undo the work that the <code>BundleActivator.start</code>
+	 * method should undo the work that the {@code BundleActivator.start}
 	 * method started. There should be no active threads that were started by
 	 * this bundle when this bundle returns. A stopped bundle must not call any
 	 * Framework objects.
diff --git a/framework/src/main/java/org/osgi/framework/BundleContext.java b/framework/src/main/java/org/osgi/framework/BundleContext.java
index 44b3801..c587d03 100644
--- a/framework/src/main/java/org/osgi/framework/BundleContext.java
+++ b/framework/src/main/java/org/osgi/framework/BundleContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
 
 import java.io.File;
 import java.io.InputStream;
+import java.util.Collection;
 import java.util.Dictionary;
 
 /**
@@ -26,100 +27,107 @@
  * Framework.
  * 
  * <p>
- * <code>BundleContext</code> methods allow a bundle to:
+ * {@code BundleContext} methods allow a bundle to:
  * <ul>
  * <li>Subscribe to events published by the Framework.
  * <li>Register service objects with the Framework service registry.
- * <li>Retrieve <code>ServiceReferences</code> from the Framework service
- * registry.
+ * <li>Retrieve {@code ServiceReferences} from the Framework service registry.
  * <li>Get and release service objects for a referenced service.
  * <li>Install new bundles in the Framework.
  * <li>Get the list of bundles installed in the Framework.
  * <li>Get the {@link Bundle} object for a bundle.
- * <li>Create <code>File</code> objects for files in a persistent storage
- * area provided for the bundle by the Framework.
+ * <li>Create {@code File} objects for files in a persistent storage area
+ * provided for the bundle by the Framework.
  * </ul>
  * 
  * <p>
- * A <code>BundleContext</code> object will be created and provided to the
- * bundle associated with this context when it is started using the
- * {@link BundleActivator#start} method. The same <code>BundleContext</code>
- * object will be passed to the bundle associated with this context when it is
- * stopped using the {@link BundleActivator#stop} method. A
- * <code>BundleContext</code> object is generally for the private use of its
+ * A {@code BundleContext} object will be created for a bundle when the bundle
+ * is started. The {@code Bundle} object associated with a {@code BundleContext}
+ * object is called the <em>context bundle</em>.
+ * 
+ * <p>
+ * The {@code BundleContext} object will be passed to the
+ * {@link BundleActivator#start} method during activation of the context bundle.
+ * The same {@code BundleContext} object will be passed to the
+ * {@link BundleActivator#stop} method when the context bundle is stopped. A
+ * {@code BundleContext} object is generally for the private use of its
  * associated bundle and is not meant to be shared with other bundles in the
  * OSGi environment.
  * 
  * <p>
- * The <code>Bundle</code> object associated with a <code>BundleContext</code>
- * object is called the <em>context bundle</em>.
+ * The {@code BundleContext} object is only valid during the execution of its
+ * context bundle; that is, during the period from when the context bundle is in
+ * the {@code STARTING}, {@code STOPPING}, and {@code ACTIVE} bundle states. If
+ * the {@code BundleContext} object is used subsequently, an
+ * {@code IllegalStateException} must be thrown. The {@code BundleContext}
+ * object must never be reused after its context bundle is stopped.
  * 
  * <p>
- * The <code>BundleContext</code> object is only valid during the execution of
- * its context bundle; that is, during the period from when the context bundle
- * is in the <code>STARTING</code>, <code>STOPPING</code>, and
- * <code>ACTIVE</code> bundle states. If the <code>BundleContext</code>
- * object is used subsequently, an <code>IllegalStateException</code> must be
- * thrown. The <code>BundleContext</code> object must never be reused after
- * its context bundle is stopped.
+ * Two {@code BundleContext} objects are equal if they both refer to the same
+ * execution context of a bundle. The Framework is the only entity that can
+ * create {@code BundleContext} objects and they are only valid within the
+ * Framework that created them.
  * 
  * <p>
- * The Framework is the only entity that can create <code>BundleContext</code>
- * objects and they are only valid within the Framework that created them.
+ * A {@link Bundle} can be {@link Bundle#adapt(Class) adapted} to its
+ * {@code BundleContext}. In order for this to succeed, the caller must have the
+ * appropriate {@code AdminPermission[bundle,CONTEXT]} if the Java Runtime
+ * Environment supports permissions.
  * 
  * @ThreadSafe
- * @version $Revision: 6781 $
+ * @noimplement
+ * @version $Id: 6d4b5967b9fe706b1dfbdd42b3d759028ed9826d $
  */
 
-public interface BundleContext {
+public interface BundleContext extends BundleReference {
+
 	/**
 	 * Returns the value of the specified property. If the key is not found in
 	 * the Framework properties, the system properties are then searched. The
-	 * method returns <code>null</code> if the property is not found.
+	 * method returns {@code null} if the property is not found.
 	 * 
 	 * <p>
 	 * All bundles must have permission to read properties whose names start
 	 * with &quot;org.osgi.&quot;.
 	 * 
 	 * @param key The name of the requested property.
-	 * @return The value of the requested property, or <code>null</code> if the
+	 * @return The value of the requested property, or {@code null} if the
 	 *         property is undefined.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>PropertyPermission</code> to read the property, and the
-	 *         Java Runtime Environment supports permissions.
+	 *         {@code PropertyPermission} to read the property, and the Java
+	 *         Runtime Environment supports permissions.
 	 */
-	public String getProperty(String key);
+	String getProperty(String key);
 
 	/**
-	 * Returns the <code>Bundle</code> object associated with this
-	 * <code>BundleContext</code>. This bundle is called the context bundle.
+	 * Returns the {@code Bundle} object associated with this
+	 * {@code BundleContext}. This bundle is called the context bundle.
 	 * 
-	 * @return The <code>Bundle</code> object associated with this
-	 *         <code>BundleContext</code>.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @return The {@code Bundle} object associated with this
+	 *         {@code BundleContext}.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 */
-	public Bundle getBundle();
+	Bundle getBundle();
 
 	/**
-	 * Installs a bundle from the specified <code>InputStream</code> object.
+	 * Installs a bundle from the specified {@code InputStream} object.
 	 * 
 	 * <p>
-	 * If the specified <code>InputStream</code> is <code>null</code>, the
-	 * Framework must create the <code>InputStream</code> from which to read the
-	 * bundle by interpreting, in an implementation dependent manner, the
-	 * specified <code>location</code>.
+	 * If the specified {@code InputStream} is {@code null}, the Framework must
+	 * create the {@code InputStream} from which to read the bundle by
+	 * interpreting, in an implementation dependent manner, the specified
+	 * {@code location}.
 	 * 
 	 * <p>
-	 * The specified <code>location</code> identifier will be used as the
-	 * identity of the bundle. Every installed bundle is uniquely identified by
-	 * its location identifier which is typically in the form of a URL.
+	 * The specified {@code location} identifier will be used as the identity of
+	 * the bundle. Every installed bundle is uniquely identified by its location
+	 * identifier which is typically in the form of a URL.
 	 * 
 	 * <p>
 	 * The following steps are required to install a bundle:
 	 * <ol>
 	 * <li>If a bundle containing the same location identifier is already
-	 * installed, the <code>Bundle</code> object for that bundle is returned.
+	 * installed, the {@code Bundle} object for that bundle is returned.
 	 * 
 	 * <li>The bundle's content is read from the input stream. If this fails, a
 	 * {@link BundleException} is thrown.
@@ -127,71 +135,80 @@
 	 * <li>The bundle's associated resources are allocated. The associated
 	 * resources minimally consist of a unique identifier and a persistent
 	 * storage area if the platform has file system support. If this step fails,
-	 * a <code>BundleException</code> is thrown.
+	 * a {@code BundleException} is thrown.
 	 * 
-	 * <li>The bundle's state is set to <code>INSTALLED</code>.
+	 * <li>The bundle's state is set to {@code INSTALLED}.
 	 * 
 	 * <li>A bundle event of type {@link BundleEvent#INSTALLED} is fired.
 	 * 
-	 * <li>The <code>Bundle</code> object for the newly or previously installed
+	 * <li>The {@code Bundle} object for the newly or previously installed
 	 * bundle is returned.
 	 * </ol>
 	 * 
 	 * <b>Postconditions, no exceptions thrown </b>
 	 * <ul>
-	 * <li><code>getState()</code> in &#x007B; <code>INSTALLED</code>,
-	 * <code>RESOLVED</code> &#x007D;.
+	 * <li>{@code getState()} in &#x007B; {@code INSTALLED}, {@code RESOLVED}
+	 * &#x007D;.
 	 * <li>Bundle has a unique ID.
 	 * </ul>
 	 * <b>Postconditions, when an exception is thrown </b>
 	 * <ul>
-	 * <li>Bundle is not installed and no trace of the bundle exists.
+	 * <li>Bundle is not installed. If there was an existing bundle for the
+	 * specified location, then that bundle must still be in the state it was
+	 * prior to calling this method.</li>
 	 * </ul>
 	 * 
 	 * @param location The location identifier of the bundle to install.
-	 * @param input The <code>InputStream</code> object from which this bundle
-	 *        will be read or <code>null</code> to indicate the Framework must
-	 *        create the input stream from the specified location identifier.
-	 *        The input stream must always be closed when this method completes,
-	 *        even if an exception is thrown.
-	 * @return The <code>Bundle</code> object of the installed bundle.
-	 * @throws BundleException If the input stream cannot be read or the
-	 *         installation failed.
+	 * @param input The {@code InputStream} object from which this bundle will
+	 *        be read or {@code null} to indicate the Framework must create the
+	 *        input stream from the specified location identifier. The input
+	 *        stream must always be closed when this method completes, even if
+	 *        an exception is thrown.
+	 * @return The {@code Bundle} object of the installed bundle.
+	 * @throws BundleException If the installation failed. BundleException types
+	 *         thrown by this method include: {@link BundleException#READ_ERROR}
+	 *         , {@link BundleException#DUPLICATE_BUNDLE_ERROR},
+	 *         {@link BundleException#MANIFEST_ERROR}, and
+	 *         {@link BundleException#REJECTED_BY_HOOK}.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[installed bundle,LIFECYCLE]</code>, and the
-	 *         Java Runtime Environment supports permissions.
+	 *         {@code AdminPermission[installed bundle,LIFECYCLE]}, and the Java
+	 *         Runtime Environment supports permissions.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 */
-	public Bundle installBundle(String location, InputStream input)
+	Bundle installBundle(String location, InputStream input)
 			throws BundleException;
 
 	/**
-	 * Installs a bundle from the specified <code>location</code> identifier.
+	 * Installs a bundle from the specified {@code location} identifier.
 	 * 
 	 * <p>
 	 * This method performs the same function as calling
 	 * {@link #installBundle(String,InputStream)} with the specified
-	 * <code>location</code> identifier and a <code>null</code> InputStream.
+	 * {@code location} identifier and a {@code null} InputStream.
 	 * 
 	 * @param location The location identifier of the bundle to install.
-	 * @return The <code>Bundle</code> object of the installed bundle.
-	 * @throws BundleException If the installation failed.
+	 * @return The {@code Bundle} object of the installed bundle.
+	 * @throws BundleException If the installation failed. BundleException types
+	 *         thrown by this method include: {@link BundleException#READ_ERROR}
+	 *         , {@link BundleException#DUPLICATE_BUNDLE_ERROR},
+	 *         {@link BundleException#MANIFEST_ERROR}, and
+	 *         {@link BundleException#REJECTED_BY_HOOK}.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[installed bundle,LIFECYCLE]</code>, and the
-	 *         Java Runtime Environment supports permissions.
+	 *         {@code AdminPermission[installed bundle,LIFECYCLE]}, and the Java
+	 *         Runtime Environment supports permissions.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @see #installBundle(String, InputStream)
 	 */
-	public Bundle installBundle(String location) throws BundleException;
+	Bundle installBundle(String location) throws BundleException;
 
 	/**
 	 * Returns the bundle with the specified identifier.
 	 * 
 	 * @param id The identifier of the bundle to retrieve.
-	 * @return A <code>Bundle</code> object or <code>null</code> if the
-	 *         identifier does not match any installed bundle.
+	 * @return A {@code Bundle} object or {@code null} if the identifier does
+	 *         not match any installed bundle.
 	 */
-	public Bundle getBundle(long id);
+	Bundle getBundle(long id);
 
 	/**
 	 * Returns a list of all installed bundles.
@@ -201,179 +218,164 @@
 	 * Framework is a very dynamic environment, bundles can be installed or
 	 * uninstalled at anytime.
 	 * 
-	 * @return An array of <code>Bundle</code> objects, one object per
-	 *         installed bundle.
+	 * @return An array of {@code Bundle} objects, one object per installed
+	 *         bundle.
 	 */
-	public Bundle[] getBundles();
+	Bundle[] getBundles();
 
 	/**
-	 * Adds the specified <code>ServiceListener</code> object with the
-	 * specified <code>filter</code> to the context bundle's list of
-	 * listeners. See {@link Filter} for a description of the filter syntax.
-	 * <code>ServiceListener</code> objects are notified when a service has a
+	 * Adds the specified {@code ServiceListener} object with the specified
+	 * {@code filter} to the context bundle's list of listeners. See
+	 * {@link Filter} for a description of the filter syntax.
+	 * {@code ServiceListener} objects are notified when a service has a
 	 * lifecycle state change.
 	 * 
 	 * <p>
 	 * If the context bundle's list of listeners already contains a listener
-	 * <code>l</code> such that <code>(l==listener)</code>, then this
-	 * method replaces that listener's filter (which may be <code>null</code>)
-	 * with the specified one (which may be <code>null</code>).
+	 * {@code l} such that {@code (l==listener)}, then this method replaces that
+	 * listener's filter (which may be {@code null}) with the specified one
+	 * (which may be {@code null}).
 	 * 
 	 * <p>
 	 * The listener is called if the filter criteria is met. To filter based
 	 * upon the class of the service, the filter should reference the
-	 * {@link Constants#OBJECTCLASS} property. If <code>filter</code> is
-	 * <code>null</code>, all services are considered to match the filter.
+	 * {@link Constants#OBJECTCLASS} property. If {@code filter} is {@code null}
+	 * , all services are considered to match the filter.
 	 * 
 	 * <p>
-	 * When using a <code>filter</code>, it is possible that the
-	 * <code>ServiceEvent</code>s for the complete lifecycle of a service
-	 * will not be delivered to the listener. For example, if the
-	 * <code>filter</code> only matches when the property <code>x</code> has
-	 * the value <code>1</code>, the listener will not be called if the
-	 * service is registered with the property <code>x</code> not set to the
-	 * value <code>1</code>. Subsequently, when the service is modified
-	 * setting property <code>x</code> to the value <code>1</code>, the
-	 * filter will match and the listener will be called with a
-	 * <code>ServiceEvent</code> of type <code>MODIFIED</code>. Thus, the
-	 * listener will not be called with a <code>ServiceEvent</code> of type
-	 * <code>REGISTERED</code>.
+	 * When using a {@code filter}, it is possible that the {@code ServiceEvent}
+	 * s for the complete lifecycle of a service will not be delivered to the
+	 * listener. For example, if the {@code filter} only matches when the
+	 * property {@code x} has the value {@code 1}, the listener will not be
+	 * called if the service is registered with the property {@code x} not set
+	 * to the value {@code 1}. Subsequently, when the service is modified
+	 * setting property {@code x} to the value {@code 1}, the filter will match
+	 * and the listener will be called with a {@code ServiceEvent} of type
+	 * {@code MODIFIED}. Thus, the listener will not be called with a
+	 * {@code ServiceEvent} of type {@code REGISTERED}.
 	 * 
 	 * <p>
 	 * If the Java Runtime Environment supports permissions, the
-	 * <code>ServiceListener</code> object will be notified of a service event
-	 * only if the bundle that is registering it has the
-	 * <code>ServicePermission</code> to get the service using at least one of
-	 * the named classes the service was registered under.
+	 * {@code ServiceListener} object will be notified of a service event only
+	 * if the bundle that is registering it has the {@code ServicePermission} to
+	 * get the service using at least one of the named classes the service was
+	 * registered under.
 	 * 
-	 * @param listener The <code>ServiceListener</code> object to be added.
+	 * @param listener The {@code ServiceListener} object to be added.
 	 * @param filter The filter criteria.
-	 * @throws InvalidSyntaxException If <code>filter</code> contains an
-	 *         invalid filter string that cannot be parsed.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @throws InvalidSyntaxException If {@code filter} contains an invalid
+	 *         filter string that cannot be parsed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @see ServiceEvent
 	 * @see ServiceListener
 	 * @see ServicePermission
 	 */
-	public void addServiceListener(ServiceListener listener, String filter)
+	void addServiceListener(ServiceListener listener, String filter)
 			throws InvalidSyntaxException;
 
 	/**
-	 * Adds the specified <code>ServiceListener</code> object to the context
-	 * bundle's list of listeners.
+	 * Adds the specified {@code ServiceListener} object to the context bundle's
+	 * list of listeners.
 	 * 
 	 * <p>
 	 * This method is the same as calling
-	 * <code>BundleContext.addServiceListener(ServiceListener listener,
-	 * String filter)</code>
-	 * with <code>filter</code> set to <code>null</code>.
+	 * {@code BundleContext.addServiceListener(ServiceListener listener,
+	 * String filter)} with {@code filter} set to {@code null}.
 	 * 
-	 * @param listener The <code>ServiceListener</code> object to be added.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @param listener The {@code ServiceListener} object to be added.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @see #addServiceListener(ServiceListener, String)
 	 */
-	public void addServiceListener(ServiceListener listener);
+	void addServiceListener(ServiceListener listener);
 
 	/**
-	 * Removes the specified <code>ServiceListener</code> object from the
-	 * context bundle's list of listeners.
+	 * Removes the specified {@code ServiceListener} object from the context
+	 * bundle's list of listeners.
 	 * 
 	 * <p>
-	 * If <code>listener</code> is not contained in this context bundle's list
-	 * of listeners, this method does nothing.
+	 * If {@code listener} is not contained in this context bundle's list of
+	 * listeners, this method does nothing.
 	 * 
-	 * @param listener The <code>ServiceListener</code> to be removed.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @param listener The {@code ServiceListener} to be removed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 */
-	public void removeServiceListener(ServiceListener listener);
+	void removeServiceListener(ServiceListener listener);
 
 	/**
-	 * Adds the specified <code>BundleListener</code> object to the context
-	 * bundle's list of listeners if not already present. BundleListener objects
-	 * are notified when a bundle has a lifecycle state change.
+	 * Adds the specified {@code BundleListener} object to the context bundle's
+	 * list of listeners if not already present. BundleListener objects are
+	 * notified when a bundle has a lifecycle state change.
 	 * 
 	 * <p>
 	 * If the context bundle's list of listeners already contains a listener
-	 * <code>l</code> such that <code>(l==listener)</code>, this method
-	 * does nothing.
+	 * {@code l} such that {@code (l==listener)}, this method does nothing.
 	 * 
-	 * @param listener The <code>BundleListener</code> to be added.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @param listener The {@code BundleListener} to be added.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @throws SecurityException If listener is a
-	 *         <code>SynchronousBundleListener</code> and the caller does not
-	 *         have the appropriate
-	 *         <code>AdminPermission[context bundle,LISTENER]</code>, and the
-	 *         Java Runtime Environment supports permissions.
+	 *         {@code SynchronousBundleListener} and the caller does not have
+	 *         the appropriate {@code AdminPermission[context bundle,LISTENER]},
+	 *         and the Java Runtime Environment supports permissions.
 	 * @see BundleEvent
 	 * @see BundleListener
 	 */
-	public void addBundleListener(BundleListener listener);
+	void addBundleListener(BundleListener listener);
 
 	/**
-	 * Removes the specified <code>BundleListener</code> object from the
-	 * context bundle's list of listeners.
+	 * Removes the specified {@code BundleListener} object from the context
+	 * bundle's list of listeners.
 	 * 
 	 * <p>
-	 * If <code>listener</code> is not contained in the context bundle's list
-	 * of listeners, this method does nothing.
+	 * If {@code listener} is not contained in the context bundle's list of
+	 * listeners, this method does nothing.
 	 * 
-	 * @param listener The <code>BundleListener</code> object to be removed.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @param listener The {@code BundleListener} object to be removed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @throws SecurityException If listener is a
-	 *         <code>SynchronousBundleListener</code> and the caller does not
-	 *         have the appropriate
-	 *         <code>AdminPermission[context bundle,LISTENER]</code>, and the
-	 *         Java Runtime Environment supports permissions.
+	 *         {@code SynchronousBundleListener} and the caller does not have
+	 *         the appropriate {@code AdminPermission[context bundle,LISTENER]},
+	 *         and the Java Runtime Environment supports permissions.
 	 */
-	public void removeBundleListener(BundleListener listener);
+	void removeBundleListener(BundleListener listener);
 
 	/**
-	 * Adds the specified <code>FrameworkListener</code> object to the context
+	 * Adds the specified {@code FrameworkListener} object to the context
 	 * bundle's list of listeners if not already present. FrameworkListeners are
 	 * notified of general Framework events.
 	 * 
 	 * <p>
 	 * If the context bundle's list of listeners already contains a listener
-	 * <code>l</code> such that <code>(l==listener)</code>, this method
-	 * does nothing.
+	 * {@code l} such that {@code (l==listener)}, this method does nothing.
 	 * 
-	 * @param listener The <code>FrameworkListener</code> object to be added.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @param listener The {@code FrameworkListener} object to be added.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @see FrameworkEvent
 	 * @see FrameworkListener
 	 */
-	public void addFrameworkListener(FrameworkListener listener);
+	void addFrameworkListener(FrameworkListener listener);
 
 	/**
-	 * Removes the specified <code>FrameworkListener</code> object from the
-	 * context bundle's list of listeners.
+	 * Removes the specified {@code FrameworkListener} object from the context
+	 * bundle's list of listeners.
 	 * 
 	 * <p>
-	 * If <code>listener</code> is not contained in the context bundle's list
-	 * of listeners, this method does nothing.
+	 * If {@code listener} is not contained in the context bundle's list of
+	 * listeners, this method does nothing.
 	 * 
-	 * @param listener The <code>FrameworkListener</code> object to be
-	 *        removed.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @param listener The {@code FrameworkListener} object to be removed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 */
-	public void removeFrameworkListener(FrameworkListener listener);
+	void removeFrameworkListener(FrameworkListener listener);
 
 	/**
 	 * Registers the specified service object with the specified properties
 	 * under the specified class names into the Framework. A
-	 * <code>ServiceRegistration</code> object is returned. The
-	 * <code>ServiceRegistration</code> object is for the private use of the
-	 * bundle registering the service and should not be shared with other
-	 * bundles. The registering bundle is defined to be the context bundle.
-	 * Other bundles can locate the service by using either the
-	 * {@link #getServiceReferences} or {@link #getServiceReference} method.
+	 * {@code ServiceRegistration} object is returned. The
+	 * {@code ServiceRegistration} object is for the private use of the bundle
+	 * registering the service and should not be shared with other bundles. The
+	 * registering bundle is defined to be the context bundle. Other bundles can
+	 * locate the service by using either the {@link #getServiceReferences} or
+	 * {@link #getServiceReference} method.
 	 * 
 	 * <p>
 	 * A bundle can register a service object that implements the
@@ -383,59 +385,57 @@
 	 * <p>
 	 * The following steps are required to register a service:
 	 * <ol>
-	 * <li>If <code>service</code> is not a <code>ServiceFactory</code>, an
-	 * <code>IllegalArgumentException</code> is thrown if <code>service</code>
-	 * is not an <code>instanceof</code> all the specified class names.
+	 * <li>If {@code service} is not a {@code ServiceFactory}, an
+	 * {@code IllegalArgumentException} is thrown if {@code service} is not an
+	 * {@code instanceof} all the specified class names.
 	 * <li>The Framework adds the following service properties to the service
-	 * properties from the specified <code>Dictionary</code> (which may be
-	 * <code>null</code>): <br/>
+	 * properties from the specified {@code Dictionary} (which may be
+	 * {@code null}): <br/>
 	 * A property named {@link Constants#SERVICE_ID} identifying the
 	 * registration number of the service <br/>
 	 * A property named {@link Constants#OBJECTCLASS} containing all the
 	 * specified classes. <br/>
-	 * Properties with these names in the specified <code>Dictionary</code> will
-	 * be ignored.
+	 * Properties with these names in the specified {@code Dictionary} will be
+	 * ignored.
 	 * <li>The service is added to the Framework service registry and may now be
 	 * used by other bundles.
 	 * <li>A service event of type {@link ServiceEvent#REGISTERED} is fired.
-	 * <li>A <code>ServiceRegistration</code> object for this registration is
+	 * <li>A {@code ServiceRegistration} object for this registration is
 	 * returned.
 	 * </ol>
 	 * 
 	 * @param clazzes The class names under which the service can be located.
 	 *        The class names in this array will be stored in the service's
 	 *        properties under the key {@link Constants#OBJECTCLASS}.
-	 * @param service The service object or a <code>ServiceFactory</code>
-	 *        object.
+	 * @param service The service object or a {@code ServiceFactory} object.
 	 * @param properties The properties for this service. The keys in the
-	 *        properties object must all be <code>String</code> objects. See
+	 *        properties object must all be {@code String} objects. See
 	 *        {@link Constants} for a list of standard service property keys.
 	 *        Changes should not be made to this object after calling this
 	 *        method. To update the service's properties the
 	 *        {@link ServiceRegistration#setProperties} method must be called.
-	 *        The set of properties may be <code>null</code> if the service has
-	 *        no properties.
-	 * @return A <code>ServiceRegistration</code> object for use by the bundle
+	 *        The set of properties may be {@code null} if the service has no
+	 *        properties.
+	 * @return A {@code ServiceRegistration} object for use by the bundle
 	 *         registering the service to update the service's properties or to
 	 *         unregister the service.
 	 * @throws IllegalArgumentException If one of the following is true:
 	 *         <ul>
-	 *         <li><code>service</code> is <code>null</code>. <li><code>service
-	 *         </code> is not a <code>ServiceFactory</code> object and is not an
-	 *         instance of all the named classes in <code>clazzes</code>. <li>
-	 *         <code>properties</code> contains case variants of the same key
-	 *         name.
+	 *         <li>{@code service} is {@code null}. <li>{@code service} is not a
+	 *         {@code ServiceFactory} object and is not an instance of all the
+	 *         named classes in {@code clazzes}. <li> {@code properties}
+	 *         contains case variants of the same key name.
 	 *         </ul>
 	 * @throws SecurityException If the caller does not have the
-	 *         <code>ServicePermission</code> to register the service for all
-	 *         the named classes and the Java Runtime Environment supports
+	 *         {@code ServicePermission} to register the service for all the
+	 *         named classes and the Java Runtime Environment supports
 	 *         permissions.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @see ServiceRegistration
 	 * @see ServiceFactory
 	 */
-	public ServiceRegistration registerService(String[] clazzes,
-			Object service, Dictionary properties);
+	ServiceRegistration< ? > registerService(String[] clazzes, Object service,
+			Dictionary<String, ? > properties);
 
 	/**
 	 * Registers the specified service object with the specified properties
@@ -444,28 +444,53 @@
 	 * <p>
 	 * This method is otherwise identical to
 	 * {@link #registerService(String[], Object, Dictionary)} and is provided as
-	 * a convenience when <code>service</code> will only be registered under a
-	 * single class name. Note that even in this case the value of the service's
+	 * a convenience when {@code service} will only be registered under a single
+	 * class name. Note that even in this case the value of the service's
 	 * {@link Constants#OBJECTCLASS} property will be an array of string, rather
 	 * than just a single string.
 	 * 
 	 * @param clazz The class name under which the service can be located.
-	 * @param service The service object or a <code>ServiceFactory</code>
-	 *        object.
+	 * @param service The service object or a {@code ServiceFactory} object.
 	 * @param properties The properties for this service.
-	 * @return A <code>ServiceRegistration</code> object for use by the bundle
+	 * @return A {@code ServiceRegistration} object for use by the bundle
 	 *         registering the service to update the service's properties or to
 	 *         unregister the service.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @see #registerService(String[], Object, Dictionary)
 	 */
-	public ServiceRegistration registerService(String clazz, Object service,
-			Dictionary properties);
+	ServiceRegistration< ? > registerService(String clazz, Object service,
+			Dictionary<String, ? > properties);
 
 	/**
-	 * Returns an array of <code>ServiceReference</code> objects. The returned
-	 * array of <code>ServiceReference</code> objects contains services that
-	 * were registered under the specified class, match the specified filter
+	 * Registers the specified service object with the specified properties
+	 * under the specified class name with the Framework.
+	 * 
+	 * <p>
+	 * This method is otherwise identical to
+	 * {@link #registerService(String[], Object, Dictionary)} and is provided as
+	 * a convenience when {@code service} will only be registered under a single
+	 * class name. Note that even in this case the value of the service's
+	 * {@link Constants#OBJECTCLASS} property will be an array of string, rather
+	 * than just a single string.
+	 * 
+	 * @param <S> Type of Service.
+	 * @param clazz The class name under which the service can be located.
+	 * @param service The service object or a {@code ServiceFactory} object.
+	 * @param properties The properties for this service.
+	 * @return A {@code ServiceRegistration} object for use by the bundle
+	 *         registering the service to update the service's properties or to
+	 *         unregister the service.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see #registerService(String[], Object, Dictionary)
+	 * @since 1.6
+	 */
+	<S> ServiceRegistration<S> registerService(Class<S> clazz, S service,
+			Dictionary<String, ? > properties);
+
+	/**
+	 * Returns an array of {@code ServiceReference} objects. The returned array
+	 * of {@code ServiceReference} objects contains services that were
+	 * registered under the specified class, match the specified filter
 	 * expression, and the packages for the class names under which the services
 	 * were registered match the context bundle's packages as defined in
 	 * {@link ServiceReference#isAssignableTo(Bundle, String)}.
@@ -476,53 +501,51 @@
 	 * unregistered at any time.
 	 * 
 	 * <p>
-	 * The specified <code>filter</code> expression is used to select the
-	 * registered services whose service properties contain keys and values
-	 * which satisfy the filter expression. See {@link Filter} for a description
-	 * of the filter syntax. If the specified <code>filter</code> is
-	 * <code>null</code>, all registered services are considered to match the
-	 * filter. If the specified <code>filter</code> expression cannot be parsed,
-	 * an {@link InvalidSyntaxException} will be thrown with a human readable
+	 * The specified {@code filter} expression is used to select the registered
+	 * services whose service properties contain keys and values which satisfy
+	 * the filter expression. See {@link Filter} for a description of the filter
+	 * syntax. If the specified {@code filter} is {@code null}, all registered
+	 * services are considered to match the filter. If the specified
+	 * {@code filter} expression cannot be parsed, an
+	 * {@link InvalidSyntaxException} will be thrown with a human readable
 	 * message where the filter became unparsable.
 	 * 
 	 * <p>
-	 * The result is an array of <code>ServiceReference</code> objects for all
+	 * The result is an array of {@code ServiceReference} objects for all
 	 * services that meet all of the following conditions:
 	 * <ul>
-	 * <li>If the specified class name, <code>clazz</code>, is not
-	 * <code>null</code>, the service must have been registered with the
-	 * specified class name. The complete list of class names with which a
-	 * service was registered is available from the service's
-	 * {@link Constants#OBJECTCLASS objectClass} property.
-	 * <li>If the specified <code>filter</code> is not <code>null</code>, the
-	 * filter expression must match the service.
+	 * <li>If the specified class name, {@code clazz}, is not {@code null}, the
+	 * service must have been registered with the specified class name. The
+	 * complete list of class names with which a service was registered is
+	 * available from the service's {@link Constants#OBJECTCLASS objectClass}
+	 * property.
+	 * <li>If the specified {@code filter} is not {@code null}, the filter
+	 * expression must match the service.
 	 * <li>If the Java Runtime Environment supports permissions, the caller must
-	 * have <code>ServicePermission</code> with the <code>GET</code> action for
-	 * at least one of the class names under which the service was registered.
+	 * have {@code ServicePermission} with the {@code GET} action for at least
+	 * one of the class names under which the service was registered.
 	 * <li>For each class name with which the service was registered, calling
 	 * {@link ServiceReference#isAssignableTo(Bundle, String)} with the context
-	 * bundle and the class name on the service's <code>ServiceReference</code>
-	 * object must return <code>true</code>
+	 * bundle and the class name on the service's {@code ServiceReference}
+	 * object must return {@code true}
 	 * </ul>
 	 * 
 	 * @param clazz The class name with which the service was registered or
-	 *        <code>null</code> for all services.
-	 * @param filter The filter expression or <code>null</code> for all
-	 *        services.
-	 * @return An array of <code>ServiceReference</code> objects or
-	 *         <code>null</code> if no services are registered which satisfy the
-	 *         search.
-	 * @throws InvalidSyntaxException If the specified <code>filter</code>
-	 *         contains an invalid filter expression that cannot be parsed.
+	 *        {@code null} for all services.
+	 * @param filter The filter expression or {@code null} for all services.
+	 * @return An array of {@code ServiceReference} objects or {@code null} if
+	 *         no services are registered which satisfy the search.
+	 * @throws InvalidSyntaxException If the specified {@code filter} contains
+	 *         an invalid filter expression that cannot be parsed.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 */
-	public ServiceReference[] getServiceReferences(String clazz, String filter)
+	ServiceReference< ? >[] getServiceReferences(String clazz, String filter)
 			throws InvalidSyntaxException;
 
 	/**
-	 * Returns an array of <code>ServiceReference</code> objects. The returned
-	 * array of <code>ServiceReference</code> objects contains services that
-	 * were registered under the specified class and match the specified filter
+	 * Returns an array of {@code ServiceReference} objects. The returned array
+	 * of {@code ServiceReference} objects contains services that were
+	 * registered under the specified class and match the specified filter
 	 * expression.
 	 * 
 	 * <p>
@@ -531,61 +554,91 @@
 	 * unregistered at any time.
 	 * 
 	 * <p>
-	 * The specified <code>filter</code> expression is used to select the
-	 * registered services whose service properties contain keys and values
-	 * which satisfy the filter expression. See {@link Filter} for a description
-	 * of the filter syntax. If the specified <code>filter</code> is
-	 * <code>null</code>, all registered services are considered to match the
-	 * filter. If the specified <code>filter</code> expression cannot be parsed,
-	 * an {@link InvalidSyntaxException} will be thrown with a human readable
+	 * The specified {@code filter} expression is used to select the registered
+	 * services whose service properties contain keys and values which satisfy
+	 * the filter expression. See {@link Filter} for a description of the filter
+	 * syntax. If the specified {@code filter} is {@code null}, all registered
+	 * services are considered to match the filter. If the specified
+	 * {@code filter} expression cannot be parsed, an
+	 * {@link InvalidSyntaxException} will be thrown with a human readable
 	 * message where the filter became unparsable.
 	 * 
 	 * <p>
-	 * The result is an array of <code>ServiceReference</code> objects for all
+	 * The result is an array of {@code ServiceReference} objects for all
 	 * services that meet all of the following conditions:
 	 * <ul>
-	 * <li>If the specified class name, <code>clazz</code>, is not
-	 * <code>null</code>, the service must have been registered with the
-	 * specified class name. The complete list of class names with which a
-	 * service was registered is available from the service's
-	 * {@link Constants#OBJECTCLASS objectClass} property.
-	 * <li>If the specified <code>filter</code> is not <code>null</code>, the
-	 * filter expression must match the service.
+	 * <li>If the specified class name, {@code clazz}, is not {@code null}, the
+	 * service must have been registered with the specified class name. The
+	 * complete list of class names with which a service was registered is
+	 * available from the service's {@link Constants#OBJECTCLASS objectClass}
+	 * property.
+	 * <li>If the specified {@code filter} is not {@code null}, the filter
+	 * expression must match the service.
 	 * <li>If the Java Runtime Environment supports permissions, the caller must
-	 * have <code>ServicePermission</code> with the <code>GET</code> action for
-	 * at least one of the class names under which the service was registered.
+	 * have {@code ServicePermission} with the {@code GET} action for at least
+	 * one of the class names under which the service was registered.
 	 * </ul>
 	 * 
 	 * @param clazz The class name with which the service was registered or
-	 *        <code>null</code> for all services.
-	 * @param filter The filter expression or <code>null</code> for all
-	 *        services.
-	 * @return An array of <code>ServiceReference</code> objects or
-	 *         <code>null</code> if no services are registered which satisfy the
-	 *         search.
-	 * @throws InvalidSyntaxException If the specified <code>filter</code>
-	 *         contains an invalid filter expression that cannot be parsed.
+	 *        {@code null} for all services.
+	 * @param filter The filter expression or {@code null} for all services.
+	 * @return An array of {@code ServiceReference} objects or {@code null} if
+	 *         no services are registered which satisfy the search.
+	 * @throws InvalidSyntaxException If the specified {@code filter} contains
+	 *         an invalid filter expression that cannot be parsed.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @since 1.3
 	 */
-	public ServiceReference[] getAllServiceReferences(String clazz,
-			String filter) throws InvalidSyntaxException;
+	ServiceReference< ? >[] getAllServiceReferences(String clazz, String filter)
+			throws InvalidSyntaxException;
 
 	/**
-	 * Returns a <code>ServiceReference</code> object for a service that
-	 * implements and was registered under the specified class.
+	 * Returns a {@code ServiceReference} object for a service that implements
+	 * and was registered under the specified class.
 	 * 
 	 * <p>
-	 * The returned <code>ServiceReference</code> object is valid at the time of
-	 * the call to this method. However as the Framework is a very dynamic
+	 * The returned {@code ServiceReference} object is valid at the time of the
+	 * call to this method. However as the Framework is a very dynamic
 	 * environment, services can be modified or unregistered at any time.
 	 * 
 	 * <p>
 	 * This method is the same as calling
-	 * {@link BundleContext#getServiceReferences(String, String)} with a
-	 * <code>null</code> filter expression. It is provided as a convenience for
-	 * when the caller is interested in any service that implements the
-	 * specified class.
+	 * {@link #getServiceReferences(String, String)} with a {@code null} filter
+	 * expression and then finding the reference with the highest priority. It
+	 * is provided as a convenience for when the caller is interested in any
+	 * service that implements the specified class.
+	 * <p>
+	 * If multiple such services exist, the service with the highest priority is
+	 * selected. This priority is defined as the service reference with the
+	 * highest ranking (as specified in its {@link Constants#SERVICE_RANKING}
+	 * property) is returned.
+	 * <p>
+	 * If there is a tie in ranking, the service with the lowest service ID (as
+	 * specified in its {@link Constants#SERVICE_ID} property); that is, the
+	 * service that was registered first is returned.
+	 * 
+	 * @param clazz The class name with which the service was registered.
+	 * @return A {@code ServiceReference} object, or {@code null} if no services
+	 *         are registered which implement the named class.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @see #getServiceReferences(String, String)
+	 */
+	ServiceReference< ? > getServiceReference(String clazz);
+
+	/**
+	 * Returns a {@code ServiceReference} object for a service that implements
+	 * and was registered under the specified class.
+	 * 
+	 * <p>
+	 * The returned {@code ServiceReference} object is valid at the time of the
+	 * call to this method. However as the Framework is a very dynamic
+	 * environment, services can be modified or unregistered at any time.
+	 * 
+	 * <p>
+	 * This method is the same as calling
+	 * {@link #getServiceReferences(Class, String)} with a {@code null} filter
+	 * expression. It is provided as a convenience for when the caller is
+	 * interested in any service that implements the specified class.
 	 * <p>
 	 * If multiple such services exist, the service with the highest ranking (as
 	 * specified in its {@link Constants#SERVICE_RANKING} property) is returned.
@@ -594,17 +647,76 @@
 	 * specified in its {@link Constants#SERVICE_ID} property); that is, the
 	 * service that was registered first is returned.
 	 * 
+	 * @param <S> Type of Service.
 	 * @param clazz The class name with which the service was registered.
-	 * @return A <code>ServiceReference</code> object, or <code>null</code> if
-	 *         no services are registered which implement the named class.
+	 * @return A {@code ServiceReference} object, or {@code null} if no services
+	 *         are registered which implement the named class.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
-	 * @see #getServiceReferences(String, String)
+	 * @see #getServiceReferences(Class, String)
+	 * @since 1.6
 	 */
-	public ServiceReference getServiceReference(String clazz);
+	<S> ServiceReference<S> getServiceReference(Class<S> clazz);
+
+	/**
+	 * Returns a collection of {@code ServiceReference} objects. The returned
+	 * collection of {@code ServiceReference} objects contains services that
+	 * were registered under the specified class, match the specified filter
+	 * expression, and the packages for the class names under which the services
+	 * were registered match the context bundle's packages as defined in
+	 * {@link ServiceReference#isAssignableTo(Bundle, String)}.
+	 * 
+	 * <p>
+	 * The collection is valid at the time of the call to this method. However
+	 * since the Framework is a very dynamic environment, services can be
+	 * modified or unregistered at any time.
+	 * 
+	 * <p>
+	 * The specified {@code filter} expression is used to select the registered
+	 * services whose service properties contain keys and values which satisfy
+	 * the filter expression. See {@link Filter} for a description of the filter
+	 * syntax. If the specified {@code filter} is {@code null}, all registered
+	 * services are considered to match the filter. If the specified
+	 * {@code filter} expression cannot be parsed, an
+	 * {@link InvalidSyntaxException} will be thrown with a human readable
+	 * message where the filter became unparsable.
+	 * 
+	 * <p>
+	 * The result is a collection of {@code ServiceReference} objects for all
+	 * services that meet all of the following conditions:
+	 * <ul>
+	 * <li>If the specified class name, {@code clazz}, is not {@code null}, the
+	 * service must have been registered with the specified class name. The
+	 * complete list of class names with which a service was registered is
+	 * available from the service's {@link Constants#OBJECTCLASS objectClass}
+	 * property.
+	 * <li>If the specified {@code filter} is not {@code null}, the filter
+	 * expression must match the service.
+	 * <li>If the Java Runtime Environment supports permissions, the caller must
+	 * have {@code ServicePermission} with the {@code GET} action for at least
+	 * one of the class names under which the service was registered.
+	 * <li>For each class name with which the service was registered, calling
+	 * {@link ServiceReference#isAssignableTo(Bundle, String)} with the context
+	 * bundle and the class name on the service's {@code ServiceReference}
+	 * object must return {@code true}
+	 * </ul>
+	 * 
+	 * @param <S> Type of Service
+	 * @param clazz The class name with which the service was registered. Must
+	 *        not be {@code null}.
+	 * @param filter The filter expression or {@code null} for all services.
+	 * @return A collection of {@code ServiceReference} objects. May be empty if
+	 *         no services are registered which satisfy the search.
+	 * @throws InvalidSyntaxException If the specified {@code filter} contains
+	 *         an invalid filter expression that cannot be parsed.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
+	 * @since 1.6
+	 */
+	<S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz,
+			String filter) throws InvalidSyntaxException;
 
 	/**
 	 * Returns the service object referenced by the specified
-	 * <code>ServiceReference</code> object.
+	 * {@code ServiceReference} object.
 	 * <p>
 	 * A bundle's use of a service is tracked by the bundle's use count of that
 	 * service. Each time a service's service object is returned by
@@ -617,60 +729,59 @@
 	 * no longer use that service.
 	 * 
 	 * <p>
-	 * This method will always return <code>null</code> when the service
-	 * associated with this <code>reference</code> has been unregistered.
+	 * This method will always return {@code null} when the service associated
+	 * with this {@code reference} has been unregistered.
 	 * 
 	 * <p>
 	 * The following steps are required to get the service object:
 	 * <ol>
-	 * <li>If the service has been unregistered, <code>null</code> is returned.
+	 * <li>If the service has been unregistered, {@code null} is returned.
+	 * <li>If the context bundle's use count for the service is currently zero
+	 * and the service was registered with an object implementing the
+	 * {@code ServiceFactory} interface, the
+	 * {@link ServiceFactory#getService(Bundle, ServiceRegistration)} method is
+	 * called to create a service object for the context bundle. If the service
+	 * object returned by the {@code ServiceFactory} object is {@code null}, not
+	 * an {@code instanceof} all the classes named when the service was
+	 * registered or the {@code ServiceFactory} object throws an exception or
+	 * will be recursively called for the context bundle, {@code null} is
+	 * returned and a Framework event of type {@link FrameworkEvent#ERROR}
+	 * containing a {@link ServiceException} describing the error is fired. <br>
+	 * This service object is cached by the Framework. While the context
+	 * bundle's use count for the service is greater than zero, subsequent calls
+	 * to get the services's service object for the context bundle will return
+	 * the cached service object.
 	 * <li>The context bundle's use count for this service is incremented by
 	 * one.
-	 * <li>If the context bundle's use count for the service is currently one
-	 * and the service was registered with an object implementing the
-	 * <code>ServiceFactory</code> interface, the
-	 * {@link ServiceFactory#getService(Bundle, ServiceRegistration)} method is
-	 * called to create a service object for the context bundle. This service
-	 * object is cached by the Framework. While the context bundle's use count
-	 * for the service is greater than zero, subsequent calls to get the
-	 * services's service object for the context bundle will return the cached
-	 * service object. <br>
-	 * If the service object returned by the <code>ServiceFactory</code> object
-	 * is not an <code>instanceof</code> all the classes named when the service
-	 * was registered or the <code>ServiceFactory</code> object throws an
-	 * exception, <code>null</code> is returned and a Framework event of type
-	 * {@link FrameworkEvent#ERROR} containing a {@link ServiceException}
-	 * describing the error is fired.
 	 * <li>The service object for the service is returned.
 	 * </ol>
 	 * 
+	 * @param <S> Type of Service.
 	 * @param reference A reference to the service.
 	 * @return A service object for the service associated with
-	 *         <code>reference</code> or <code>null</code> if the service is not
+	 *         {@code reference} or {@code null} if the service is not
 	 *         registered, the service object returned by a
-	 *         <code>ServiceFactory</code> does not implement the classes under
-	 *         which it was registered or the <code>ServiceFactory</code> threw
-	 *         an exception.
+	 *         {@code ServiceFactory} does not implement the classes under which
+	 *         it was registered or the {@code ServiceFactory} threw an
+	 *         exception.
 	 * @throws SecurityException If the caller does not have the
-	 *         <code>ServicePermission</code> to get the service using at least
-	 *         one of the named classes the service was registered under and the
+	 *         {@code ServicePermission} to get the service using at least one
+	 *         of the named classes the service was registered under and the
 	 *         Java Runtime Environment supports permissions.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @throws IllegalArgumentException If the specified
-	 *         <code>ServiceReference</code> was not created by the same
-	 *         framework instance as this <code>BundleContext</code>.
+	 *         {@code ServiceReference} was not created by the same framework
+	 *         instance as this {@code BundleContext}.
 	 * @see #ungetService(ServiceReference)
 	 * @see ServiceFactory
 	 */
-	public Object getService(ServiceReference reference);
+	<S> S getService(ServiceReference<S> reference);
 
 	/**
 	 * Releases the service object referenced by the specified
-	 * <code>ServiceReference</code> object. If the context bundle's use count
-	 * for the service is zero, this method returns <code>false</code>.
-	 * Otherwise, the context bundle's use count for the service is decremented
-	 * by one.
+	 * {@code ServiceReference} object. If the context bundle's use count for
+	 * the service is zero, this method returns {@code false}. Otherwise, the
+	 * context bundle's use count for the service is decremented by one.
 	 * 
 	 * <p>
 	 * The service's service object should no longer be used and all references
@@ -681,76 +792,81 @@
 	 * The following steps are required to unget the service object:
 	 * <ol>
 	 * <li>If the context bundle's use count for the service is zero or the
-	 * service has been unregistered, <code>false</code> is returned.
+	 * service has been unregistered, {@code false} is returned.
 	 * <li>The context bundle's use count for this service is decremented by
 	 * one.
 	 * <li>If the context bundle's use count for the service is currently zero
-	 * and the service was registered with a <code>ServiceFactory</code> object,
-	 * the
+	 * and the service was registered with a {@code ServiceFactory} object, the
 	 * {@link ServiceFactory#ungetService(Bundle, ServiceRegistration, Object)}
 	 * method is called to release the service object for the context bundle.
-	 * <li><code>true</code> is returned.
+	 * <li>{@code true} is returned.
 	 * </ol>
 	 * 
 	 * @param reference A reference to the service to be released.
-	 * @return <code>false</code> if the context bundle's use count for the
-	 *         service is zero or if the service has been unregistered;
-	 *         <code>true</code> otherwise.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @return {@code false} if the context bundle's use count for the service
+	 *         is zero or if the service has been unregistered; {@code true}
+	 *         otherwise.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @throws IllegalArgumentException If the specified
-	 *         <code>ServiceReference</code> was not created by the same
-	 *         framework instance as this <code>BundleContext</code>.
+	 *         {@code ServiceReference} was not created by the same framework
+	 *         instance as this {@code BundleContext}.
 	 * @see #getService
 	 * @see ServiceFactory
 	 */
-	public boolean ungetService(ServiceReference reference);
+	boolean ungetService(ServiceReference< ? > reference);
 
 	/**
-	 * Creates a <code>File</code> object for a file in the persistent storage
-	 * area provided for the bundle by the Framework. This method will return
-	 * <code>null</code> if the platform does not have file system support.
+	 * Creates a {@code File} object for a file in the persistent storage area
+	 * provided for the bundle by the Framework. This method will return
+	 * {@code null} if the platform does not have file system support.
 	 * 
 	 * <p>
-	 * A <code>File</code> object for the base directory of the persistent
-	 * storage area provided for the context bundle by the Framework can be
-	 * obtained by calling this method with an empty string as
-	 * <code>filename</code>.
+	 * A {@code File} object for the base directory of the persistent storage
+	 * area provided for the context bundle by the Framework can be obtained by
+	 * calling this method with an empty string as {@code filename}.
 	 * 
 	 * <p>
 	 * If the Java Runtime Environment supports permissions, the Framework will
-	 * ensure that the bundle has the <code>java.io.FilePermission</code> with
-	 * actions <code>read</code>,<code>write</code>,<code>delete</code>
-	 * for all files (recursively) in the persistent storage area provided for
-	 * the context bundle.
+	 * ensure that the bundle has the {@code java.io.FilePermission} with
+	 * actions {@code read},{@code write},{@code delete} for all files
+	 * (recursively) in the persistent storage area provided for the context
+	 * bundle.
 	 * 
 	 * @param filename A relative name to the file to be accessed.
-	 * @return A <code>File</code> object that represents the requested file
-	 *         or <code>null</code> if the platform does not have file system
-	 *         support.
-	 * @throws IllegalStateException If this BundleContext is no
-	 *         longer valid.
+	 * @return A {@code File} object that represents the requested file or
+	 *         {@code null} if the platform does not have file system support.
+	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 */
-	public File getDataFile(String filename);
+	File getDataFile(String filename);
 
 	/**
-	 * Creates a <code>Filter</code> object. This <code>Filter</code> object may
-	 * be used to match a <code>ServiceReference</code> object or a
-	 * <code>Dictionary</code> object.
+	 * Creates a {@code Filter} object. This {@code Filter} object may be used
+	 * to match a {@code ServiceReference} object or a {@code Dictionary}
+	 * object.
 	 * 
 	 * <p>
 	 * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
 	 * thrown with a human readable message where the filter became unparsable.
 	 * 
 	 * @param filter The filter string.
-	 * @return A <code>Filter</code> object encapsulating the filter string.
-	 * @throws InvalidSyntaxException If <code>filter</code> contains an invalid
+	 * @return A {@code Filter} object encapsulating the filter string.
+	 * @throws InvalidSyntaxException If {@code filter} contains an invalid
 	 *         filter string that cannot be parsed.
-	 * @throws NullPointerException If <code>filter</code> is null.
+	 * @throws NullPointerException If {@code filter} is null.
 	 * @throws IllegalStateException If this BundleContext is no longer valid.
 	 * @see "Framework specification for a description of the filter string syntax."
 	 * @see FrameworkUtil#createFilter(String)
 	 * @since 1.1
 	 */
-	public Filter createFilter(String filter) throws InvalidSyntaxException;
+	Filter createFilter(String filter) throws InvalidSyntaxException;
+
+	/**
+	 * Returns the bundle with the specified location.
+	 * 
+	 * @param location The location of the bundle to retrieve.
+	 * @return A {@code Bundle} object or {@code null} if the location does not
+	 *         match any installed bundle.
+	 * @since 1.6
+	 */
+	Bundle getBundle(String location);
 }
diff --git a/framework/src/main/java/org/osgi/framework/BundleEvent.java b/framework/src/main/java/org/osgi/framework/BundleEvent.java
index 7a8fb8d..13c68be 100644
--- a/framework/src/main/java/org/osgi/framework/BundleEvent.java
+++ b/framework/src/main/java/org/osgi/framework/BundleEvent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,8 +21,8 @@
 /**
  * An event from the Framework describing a bundle lifecycle change.
  * <p>
- * <code>BundleEvent</code> objects are delivered to
- * <code>SynchronousBundleListener</code>s and <code>BundleListener</code>s
+ * {@code BundleEvent} objects are delivered to
+ * {@code SynchronousBundleListener}s and {@code BundleListener}s
  * when a change occurs in a bundle's lifecycle. A type code is used to identify
  * the event type for future extendability.
  * 
@@ -32,7 +32,7 @@
  * @Immutable
  * @see BundleListener
  * @see SynchronousBundleListener
- * @version $Revision: 6542 $
+ * @version $Id: ed3c40cd707bed45681cadce114a6cc5db27a844 $
  */
 
 public class BundleEvent extends EventObject {
@@ -113,7 +113,7 @@
 	 * {@link BundleActivator#start(BundleContext) BundleActivator start} method
 	 * is about to be called if the bundle has a bundle activator class. This
 	 * event is only delivered to {@link SynchronousBundleListener}s. It is not
-	 * delivered to <code>BundleListener</code>s.
+	 * delivered to {@code BundleListener}s.
 	 * 
 	 * @see Bundle#start()
 	 * @since 1.3
@@ -127,7 +127,7 @@
 	 * {@link BundleActivator#stop(BundleContext) BundleActivator stop} method
 	 * is about to be called if the bundle has a bundle activator class. This
 	 * event is only delivered to {@link SynchronousBundleListener}s. It is not
-	 * delivered to <code>BundleListener</code>s.
+	 * delivered to {@code BundleListener}s.
 	 * 
 	 * @see Bundle#stop()
 	 * @since 1.3
@@ -140,25 +140,55 @@
 	 * The bundle has a {@link Constants#ACTIVATION_LAZY lazy activation policy}
 	 * and is waiting to be activated. It is now in the
 	 * {@link Bundle#STARTING STARTING} state and has a valid
-	 * <code>BundleContext</code>. This event is only delivered to
+	 * {@code BundleContext}. This event is only delivered to
 	 * {@link SynchronousBundleListener}s. It is not delivered to
-	 * <code>BundleListener</code>s.
+	 * {@code BundleListener}s.
 	 * 
 	 * @since 1.4
 	 */
 	public final static int	LAZY_ACTIVATION		= 0x00000200;
 
 	/**
+	 * Bundle that was the origin of the event. For install event type, this is
+	 * the bundle whose context was used to install the bundle. Otherwise it is
+	 * the bundle itself.
+	 * 
+	 * @since 1.6
+	 */
+	private final Bundle	origin;
+
+	/**
 	 * Creates a bundle event of the specified type.
 	 * 
 	 * @param type The event type.
 	 * @param bundle The bundle which had a lifecycle change.
+	 * @param origin The bundle which is the origin of the event. For the event
+	 *        type {@link #INSTALLED}, this is the bundle whose context was used
+	 *        to install the bundle. Otherwise it is the bundle itself.
+	 * @since 1.6
 	 */
+	public BundleEvent(int type, Bundle bundle, Bundle origin) {
+		super(bundle);
+		if (origin == null) {
+			throw new IllegalArgumentException("null origin");
+		}
+		this.bundle = bundle;
+		this.type = type;
+		this.origin = origin;
+	}
 
+	/**
+	 * Creates a bundle event of the specified type.
+	 * 
+	 * @param type The event type.
+	 * @param bundle The bundle which had a lifecycle change. This bundle is
+	 *        used as the origin of the event.
+	 */
 	public BundleEvent(int type, Bundle bundle) {
 		super(bundle);
 		this.bundle = bundle;
 		this.type = type;
+		this.origin = bundle;
 	}
 
 	/**
@@ -188,8 +218,21 @@
 	 * 
 	 * @return The type of lifecycle event.
 	 */
-
 	public int getType() {
 		return type;
 	}
+
+	/**
+	 * Returns the bundle that was the origin of the event.
+	 * 
+	 * <p>
+	 * For the event type {@link #INSTALLED}, this is the bundle whose context
+	 * was used to install the bundle. Otherwise it is the bundle itself.
+	 * 
+	 * @return The bundle that was the origin of the event.
+	 * @since 1.6
+	 */
+	public Bundle getOrigin() {
+		return origin;
+	}
 }
diff --git a/framework/src/main/java/org/osgi/framework/BundleException.java b/framework/src/main/java/org/osgi/framework/BundleException.java
index 500d147..9cae61a 100644
--- a/framework/src/main/java/org/osgi/framework/BundleException.java
+++ b/framework/src/main/java/org/osgi/framework/BundleException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,9 +21,9 @@
  * occurred.
  * 
  * <p>
- * A <code>BundleException</code> object is created by the Framework to denote
+ * A {@code BundleException} object is created by the Framework to denote
  * an exception condition in the lifecycle of a bundle.
- * <code>BundleException</code>s should not be created by bundle developers.
+ * {@code BundleException}s should not be created by bundle developers.
  * A type code is used to identify the exception type for future extendability.
  * 
  * <p>
@@ -32,7 +32,7 @@
  * <p>
  * This exception conforms to the general purpose exception chaining mechanism.
  * 
- * @version $Revision: 6083 $
+ * @version $Id: 9e117ec9667b040f7752e342aa07d6c7d5bf0275 $
  */
 
 public class BundleException extends Exception {
@@ -45,13 +45,14 @@
 	private final int		type;
 
 	/**
-	 * No exception type is unspecified.
+	 * No exception type is specified.
 	 * 
 	 * @since 1.5
 	 */
 	public static final int	UNSPECIFIED				= 0;
 	/**
-	 * The operation was unsupported.
+	 * The operation was unsupported. This type can be used anywhere a 
+	 * BundleException can be thrown.
 	 * 
 	 * @since 1.5
 	 */
@@ -102,8 +103,12 @@
 	public static final int	NATIVECODE_ERROR		= 8;
 
 	/**
-	 * The install or update operation failed because another 
-	 * already installed bundle has the same symbolic name and version.
+	 * The install or update operation failed because another already installed
+	 * bundle has the same symbolic name and version. This exception type will
+	 * only occur if the framework is configured to only allow a single bundle
+	 * to be installed for a given symbolic name and version.
+	 * 
+	 * @see Constants#FRAMEWORK_BSNVERSION
 	 * @since 1.5
 	 */
 	public static final int	DUPLICATE_BUNDLE_ERROR	= 9;
@@ -117,7 +122,22 @@
 	public static final int	START_TRANSIENT_ERROR	= 10;
 
 	/**
-	 * Creates a <code>BundleException</code> with the specified message and
+	 * The framework received an error while reading the input stream for a
+	 * bundle.
+	 * 
+	 * @since 1.6
+	 */
+	public static final int	READ_ERROR				= 11;
+
+	/**
+	 * A framework hook rejected the operation.
+	 * 
+	 * @since 1.6
+	 */
+	public static final int	REJECTED_BY_HOOK		= 12;
+
+	/**
+	 * Creates a {@code BundleException} with the specified message and
 	 * exception cause.
 	 * 
 	 * @param msg The associated message.
@@ -128,7 +148,7 @@
 	}
 
 	/**
-	 * Creates a <code>BundleException</code> with the specified message.
+	 * Creates a {@code BundleException} with the specified message.
 	 * 
 	 * @param msg The message.
 	 */
@@ -137,7 +157,7 @@
 	}
 
 	/**
-	 * Creates a <code>BundleException</code> with the specified message, type
+	 * Creates a {@code BundleException} with the specified message, type
 	 * and exception cause.
 	 * 
 	 * @param msg The associated message.
@@ -151,7 +171,7 @@
 	}
 
 	/**
-	 * Creates a <code>BundleException</code> with the specified message and
+	 * Creates a {@code BundleException} with the specified message and
 	 * type.
 	 * 
 	 * @param msg The message.
@@ -164,29 +184,29 @@
 	}
 
 	/**
-	 * Returns the cause of this exception or <code>null</code> if no cause was
+	 * Returns the cause of this exception or {@code null} if no cause was
 	 * specified when this exception was created.
 	 * 
 	 * <p>
 	 * This method predates the general purpose exception chaining mechanism.
-	 * The <code>getCause()</code> method is now the preferred means of
+	 * The {@code getCause()} method is now the preferred means of
 	 * obtaining this information.
 	 * 
-	 * @return The result of calling <code>getCause()</code>.
+	 * @return The result of calling {@code getCause()}.
 	 */
 	public Throwable getNestedException() {
 		return getCause();
 	}
 
 	/**
-	 * Returns the cause of this exception or <code>null</code> if no cause was
+	 * Returns the cause of this exception or {@code null} if no cause was
 	 * set.
 	 * 
-	 * @return The cause of this exception or <code>null</code> if no cause was
+	 * @return The cause of this exception or {@code null} if no cause was
 	 *         set.
 	 * @since 1.3
 	 */
-    public Throwable getCause() {
+	public Throwable getCause() {
 		return super.getCause();
 	}
 
@@ -206,7 +226,7 @@
 	}
 
 	/**
-	 * Returns the type for this exception or <code>UNSPECIFIED</code> if the
+	 * Returns the type for this exception or {@code UNSPECIFIED} if the
 	 * type was unspecified or unknown.
 	 * 
 	 * @return The type of this exception.
diff --git a/framework/src/main/java/org/osgi/framework/BundleListener.java b/framework/src/main/java/org/osgi/framework/BundleListener.java
index 9dd7151..d9bb54c 100644
--- a/framework/src/main/java/org/osgi/framework/BundleListener.java
+++ b/framework/src/main/java/org/osgi/framework/BundleListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,29 +19,29 @@
 import java.util.EventListener;
 
 /**
- * A <code>BundleEvent</code> listener. <code>BundleListener</code> is a
+ * A {@code BundleEvent} listener. {@code BundleListener} is a
  * listener interface that may be implemented by a bundle developer. When a
- * <code>BundleEvent</code> is fired, it is asynchronously delivered to a
- * <code>BundleListener</code>. The Framework delivers
- * <code>BundleEvent</code> objects to a <code>BundleListener</code> in
- * order and must not concurrently call a <code>BundleListener</code>.
+ * {@code BundleEvent} is fired, it is asynchronously delivered to a
+ * {@code BundleListener}. The Framework delivers
+ * {@code BundleEvent} objects to a {@code BundleListener} in
+ * order and must not concurrently call a {@code BundleListener}.
  * <p>
- * A <code>BundleListener</code> object is registered with the Framework using
+ * A {@code BundleListener} object is registered with the Framework using
  * the {@link BundleContext#addBundleListener} method.
- * <code>BundleListener</code>s are called with a <code>BundleEvent</code>
+ * {@code BundleListener}s are called with a {@code BundleEvent}
  * object when a bundle has been installed, resolved, started, stopped, updated,
  * unresolved, or uninstalled.
  * 
  * @see BundleEvent
  * @NotThreadSafe
- * @version $Revision: 5673 $
+ * @version $Id: 77cdaebd3ac97c6798fc3043957abd1bd6d01ccb $
  */
 
 public interface BundleListener extends EventListener {
 	/**
 	 * Receives notification that a bundle has had a lifecycle change.
 	 * 
-	 * @param event The <code>BundleEvent</code>.
+	 * @param event The {@code BundleEvent}.
 	 */
 	public void bundleChanged(BundleEvent event);
 }
diff --git a/framework/src/main/java/org/osgi/framework/BundlePermission.java b/framework/src/main/java/org/osgi/framework/BundlePermission.java
index 8677e69..e6f9356 100644
--- a/framework/src/main/java/org/osgi/framework/BundlePermission.java
+++ b/framework/src/main/java/org/osgi/framework/BundlePermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,10 +23,12 @@
 import java.security.BasicPermission;
 import java.security.Permission;
 import java.security.PermissionCollection;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -50,13 +52,13 @@
  * </pre>
  * 
  * <p>
- * <code>BundlePermission</code> has four actions: <code>provide</code>,
- * <code>require</code>,<code>host</code>, and <code>fragment</code>. The
- * <code>provide</code> action implies the <code>require</code> action.
+ * {@code BundlePermission} has four actions: {@code provide},
+ * {@code require},{@code host}, and {@code fragment}. The
+ * {@code provide} action implies the {@code require} action.
  * 
  * @since 1.3
  * @ThreadSafe
- * @version $Revision: 6860 $
+ * @version $Id: d30c9c987cc13007ed19d3a9fdd11b00739591c0 $
  */
 
 public final class BundlePermission extends BasicPermission {
@@ -64,24 +66,24 @@
 	private static final long	serialVersionUID	= 3257846601685873716L;
 
 	/**
-	 * The action string <code>provide</code>. The <code>provide</code> action
-	 * implies the <code>require</code> action.
+	 * The action string {@code provide}. The {@code provide} action
+	 * implies the {@code require} action.
 	 */
 	public final static String	PROVIDE				= "provide";
 
 	/**
-	 * The action string <code>require</code>. The <code>require</code> action
-	 * is implied by the <code>provide</code> action.
+	 * The action string {@code require}. The {@code require} action
+	 * is implied by the {@code provide} action.
 	 */
 	public final static String	REQUIRE				= "require";
 
 	/**
-	 * The action string <code>host</code>.
+	 * The action string {@code host}.
 	 */
 	public final static String	HOST				= "host";
 
 	/**
-	 * The action string <code>fragment</code>.
+	 * The action string {@code fragment}.
 	 */
 	public final static String	FRAGMENT			= "fragment";
 
@@ -113,14 +115,14 @@
 	 * Bundle Permissions are granted over all possible versions of a bundle.
 	 * 
 	 * A bundle that needs to provide a bundle must have the appropriate
-	 * <code>BundlePermission</code> for the symbolic name; a bundle that
-	 * requires a bundle must have the appropriate <code>BundlePermssion</code>
+	 * {@code BundlePermission} for the symbolic name; a bundle that
+	 * requires a bundle must have the appropriate {@code BundlePermssion}
 	 * for that symbolic name; a bundle that specifies a fragment host must have
-	 * the appropriate <code>BundlePermission</code> for that symbolic name.
+	 * the appropriate {@code BundlePermission} for that symbolic name.
 	 * 
 	 * @param symbolicName The bundle symbolic name.
-	 * @param actions <code>provide</code>,<code>require</code>,
-	 *        <code>host</code>,<code>fragment</code> (canonical order).
+	 * @param actions {@code provide},{@code require},
+	 *        {@code host},{@code fragment} (canonical order).
 	 */
 	public BundlePermission(String symbolicName, String actions) {
 		this(symbolicName, parseActions(actions));
@@ -278,9 +280,9 @@
 	 * 
 	 * <p>
 	 * This method checks that the symbolic name of the target is implied by the
-	 * symbolic name of this object. The list of <code>BundlePermission</code>
+	 * symbolic name of this object. The list of {@code BundlePermission}
 	 * actions must either match or allow for the list of the target object to
-	 * imply the target <code>BundlePermission</code> action.
+	 * imply the target {@code BundlePermission} action.
 	 * <p>
 	 * The permission to provide a bundle implies the permission to require the
 	 * named symbolic name.
@@ -293,8 +295,8 @@
 	 * </pre>
 	 * 
 	 * @param p The requested permission.
-	 * @return <code>true</code> if the specified <code>BundlePermission</code>
-	 *         action is implied by this object; <code>false</code> otherwise.
+	 * @return {@code true} if the specified {@code BundlePermission}
+	 *         action is implied by this object; {@code false} otherwise.
 	 */
 	public boolean implies(Permission p) {
 		if (!(p instanceof BundlePermission)) {
@@ -310,15 +312,15 @@
 
 	/**
 	 * Returns the canonical string representation of the
-	 * <code>BundlePermission</code> actions.
+	 * {@code BundlePermission} actions.
 	 * 
 	 * <p>
-	 * Always returns present <code>BundlePermission</code> actions in the
-	 * following order: <code>provide</code>, <code>require</code>,
-	 * <code>host</code>, <code>fragment</code>.
+	 * Always returns present {@code BundlePermission} actions in the
+	 * following order: {@code provide}, {@code require},
+	 * {@code host}, {@code fragment}.
 	 * 
-	 * @return Canonical string representation of the <code>BundlePermission
-	 *         </code> actions.
+	 * @return Canonical string representation of the {@code BundlePermission
+	 *         } actions.
 	 */
 	public String getActions() {
 		String result = actions;
@@ -357,28 +359,28 @@
 	}
 
 	/**
-	 * Returns a new <code>PermissionCollection</code> object suitable for
-	 * storing <code>BundlePermission</code> objects.
+	 * Returns a new {@code PermissionCollection} object suitable for
+	 * storing {@code BundlePermission} objects.
 	 * 
-	 * @return A new <code>PermissionCollection</code> object.
+	 * @return A new {@code PermissionCollection} object.
 	 */
 	public PermissionCollection newPermissionCollection() {
 		return new BundlePermissionCollection();
 	}
 
 	/**
-	 * Determines the equality of two <code>BundlePermission</code> objects.
+	 * Determines the equality of two {@code BundlePermission} objects.
 	 * 
 	 * This method checks that specified bundle has the same bundle symbolic
-	 * name and <code>BundlePermission</code> actions as this
-	 * <code>BundlePermission</code> object.
+	 * name and {@code BundlePermission} actions as this
+	 * {@code BundlePermission} object.
 	 * 
 	 * @param obj The object to test for equality with this
-	 *        <code>BundlePermission</code> object.
-	 * @return <code>true</code> if <code>obj</code> is a
-	 *         <code>BundlePermission</code>, and has the same bundle symbolic
-	 *         name and actions as this <code>BundlePermission</code> object;
-	 *         <code>false</code> otherwise.
+	 *        {@code BundlePermission} object.
+	 * @return {@code true} if {@code obj} is a
+	 *         {@code BundlePermission}, and has the same bundle symbolic
+	 *         name and actions as this {@code BundlePermission} object;
+	 *         {@code false} otherwise.
 	 */
 	public boolean equals(Object obj) {
 		if (obj == this) {
@@ -408,7 +410,7 @@
 
 	/**
 	 * WriteObject is called to save the state of the
-	 * <code>BundlePermission</code> object to a stream. The actions are
+	 * {@code BundlePermission} object to a stream. The actions are
 	 * serialized, and the superclass takes care of the name.
 	 */
 	private synchronized void writeObject(java.io.ObjectOutputStream s)
@@ -433,7 +435,7 @@
 }
 
 /**
- * Stores a set of <code>BundlePermission</code> permissions.
+ * Stores a set of {@code BundlePermission} permissions.
  * 
  * @see java.security.Permission
  * @see java.security.Permissions
@@ -448,7 +450,7 @@
 	 * 
 	 * @GuardedBy this
 	 */
-	private transient Map		permissions;
+	private transient Map<String, BundlePermission>	permissions;
 
 	/**
 	 * Boolean saying if "*" is in the collection.
@@ -463,17 +465,17 @@
 	 * 
 	 */
 	public BundlePermissionCollection() {
-		permissions = new HashMap();
+		permissions = new HashMap<String, BundlePermission>();
 		all_allowed = false;
 	}
 
 	/**
 	 * Add a permission to this permission collection.
 	 * 
-	 * @param permission The <code>BundlePermission</code> object to add.
+	 * @param permission The {@code BundlePermission} object to add.
 	 * @throws IllegalArgumentException If the permission is not a
-	 *         <code>BundlePermission</code> instance.
-	 * @throws SecurityException If this <code>BundlePermissionCollection</code>
+	 *         {@code BundlePermission} instance.
+	 * @throws SecurityException If this {@code BundlePermissionCollection}
 	 *         object has been marked read-only.
 	 */
 	public void add(final Permission permission) {
@@ -488,8 +490,8 @@
 		final BundlePermission bp = (BundlePermission) permission;
 		final String name = bp.getName();
 		synchronized (this) {
-			Map pc = permissions;
-			BundlePermission existing = (BundlePermission) pc.get(name);
+			Map<String, BundlePermission> pc = permissions;
+			BundlePermission existing = pc.get(name);
 			if (existing != null) {
 				final int oldMask = existing.getActionsMask();
 				final int newMask = bp.getActionsMask();
@@ -512,12 +514,12 @@
 
 	/**
 	 * Determines if the specified permissions implies the permissions expressed
-	 * in <code>permission</code>.
+	 * in {@code permission}.
 	 * 
 	 * @param permission The Permission object to compare with this
-	 *        <code>BundlePermission</code> object.
-	 * @return <code>true</code> if <code>permission</code> is a proper subset
-	 *         of a permission in the set; <code>false</code> otherwise.
+	 *        {@code BundlePermission} object.
+	 * @return {@code true} if {@code permission} is a proper subset
+	 *         of a permission in the set; {@code false} otherwise.
 	 */
 	public boolean implies(final Permission permission) {
 		if (!(permission instanceof BundlePermission)) {
@@ -530,10 +532,10 @@
 		BundlePermission bp;
 
 		synchronized (this) {
-			Map pc = permissions;
+			Map<String, BundlePermission> pc = permissions;
 			/* short circuit if the "*" Permission was added */
 			if (all_allowed) {
-				bp = (BundlePermission) pc.get("*");
+				bp = pc.get("*");
 				if (bp != null) {
 					effective |= bp.getActionsMask();
 					if ((effective & desired) == desired) {
@@ -541,7 +543,7 @@
 					}
 				}
 			}
-			bp = (BundlePermission) pc.get(requestedName);
+			bp = pc.get(requestedName);
 			// strategy:
 			// Check for full match first. Then work our way up the
 			// name looking for matches on a.b.*
@@ -557,7 +559,7 @@
 			int offset = requestedName.length() - 1;
 			while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
 				requestedName = requestedName.substring(0, last + 1) + "*";
-				bp = (BundlePermission) pc.get(requestedName);
+				bp = pc.get(requestedName);
 				if (bp != null) {
 					effective |= bp.getActionsMask();
 					if ((effective & desired) == desired) {
@@ -573,13 +575,14 @@
 	}
 
 	/**
-	 * Returns an enumeration of all <code>BundlePermission</code> objects in
+	 * Returns an enumeration of all {@code BundlePermission} objects in
 	 * the container.
 	 * 
-	 * @return Enumeration of all <code>BundlePermission</code> objects.
+	 * @return Enumeration of all {@code BundlePermission} objects.
 	 */
-	public synchronized Enumeration elements() {
-		return Collections.enumeration(permissions.values());
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		return Collections.enumeration(all);
 	}
 	
 	/* serialization logic */
@@ -589,7 +592,8 @@
 
 	private synchronized void writeObject(ObjectOutputStream out)
 			throws IOException {
-		Hashtable hashtable = new Hashtable(permissions);
+		Hashtable<String, BundlePermission> hashtable = new Hashtable<String, BundlePermission>(
+				permissions);
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", hashtable);
 		pfields.put("all_allowed", all_allowed);
@@ -599,8 +603,9 @@
 	private synchronized void readObject(java.io.ObjectInputStream in)
 			throws IOException, ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		Hashtable hashtable = (Hashtable) gfields.get("permissions", null);
-		permissions = new HashMap(hashtable);
+		Hashtable<String, BundlePermission> hashtable = (Hashtable<String, BundlePermission>) gfields
+				.get("permissions", null);
+		permissions = new HashMap<String, BundlePermission>(hashtable);
 		all_allowed = gfields.get("all_allowed", false);
 	}
 }
diff --git a/framework/src/main/java/org/osgi/framework/BundleReference.java b/framework/src/main/java/org/osgi/framework/BundleReference.java
index f9c4183..97340f7 100644
--- a/framework/src/main/java/org/osgi/framework/BundleReference.java
+++ b/framework/src/main/java/org/osgi/framework/BundleReference.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2009, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,15 +21,16 @@
  * 
  * @since 1.5
  * @ThreadSafe
- * @version $Revision: 6860 $
+ * @noimplement
+ * @version $Id: e61bd3e020264b04022a430fe09a85ee3aabf1a3 $
  */
 public interface BundleReference {
 	/**
-	 * Returns the <code>Bundle</code> object associated with this
-	 * <code>BundleReference</code>.
+	 * Returns the {@code Bundle} object associated with this
+	 * {@code BundleReference}.
 	 * 
-	 * @return The <code>Bundle</code> object associated with this
-	 *         <code>BundleReference</code>.
+	 * @return The {@code Bundle} object associated with this
+	 *         {@code BundleReference}.
 	 */
 	public Bundle getBundle();
 }
diff --git a/framework/src/main/java/org/osgi/framework/CapabilityPermission.java b/framework/src/main/java/org/osgi/framework/CapabilityPermission.java
new file mode 100644
index 0000000..bcac790
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/CapabilityPermission.java
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework;
+
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.security.AccessController;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A bundle's authority to provide or require a capability.
+ * <ul>
+ * <li>The {@code provide} action allows a bundle to provide a capability
+ * matching the specified filter.
+ * <li>The {@code require} action allows a bundle to require a capability
+ * matching the specified filter.
+ * </ul>
+ * 
+ * @ThreadSafe
+ * @version $Id: bab1ac06b46613f6cff39b291295d8b3e51d58ce $
+ * @since 1.6
+ */
+
+public final class CapabilityPermission extends BasicPermission {
+	static final long								serialVersionUID	= -7662148639076511574L;
+	/**
+	 * The action string {@code require}.
+	 */
+	public final static String						REQUIRE				= "require";
+	/**
+	 * The action string {@code provide}.
+	 */
+	public final static String						PROVIDE				= "provide";
+
+	private final static int						ACTION_REQUIRE		= 0x00000001;
+	private final static int						ACTION_PROVIDE		= 0x00000002;
+	private final static int						ACTION_ALL			= ACTION_REQUIRE
+																				| ACTION_PROVIDE;
+	final static int								ACTION_NONE			= 0;
+
+	/**
+	 * The actions mask.
+	 */
+	transient int									action_mask;
+
+	/**
+	 * The actions in canonical form.
+	 * 
+	 * @serial
+	 */
+	private volatile String							actions				= null;
+
+	/**
+	 * The attributes of the requested capability. Must be null if not
+	 * constructed with attributes.
+	 */
+	transient final Map<String, Object>				attributes;
+
+	/**
+	 * The bundle of the requested capability. Must be null if not constructed
+	 * with bundle.
+	 */
+	transient final Bundle							bundle;
+
+	/**
+	 * If this CapabilityPermission was constructed with a filter, this holds a
+	 * Filter matching object used to evaluate the filter in implies.
+	 */
+	transient Filter								filter;
+
+	/**
+	 * This map holds the properties of the permission, used to match a filter
+	 * in implies. This is not initialized until necessary, and then cached in
+	 * this object.
+	 */
+	private transient volatile Map<String, Object>	properties;
+
+	/**
+	 * Create a new CapabilityPermission.
+	 * 
+	 * <p>
+	 * The name is specified as a dot-separated string. Wildcards may be used.
+	 * 
+	 * <pre>
+	 * name ::= &lt;namespace&gt; | &lt;namespace ending in &quot;.*&quot;&gt; | *
+	 * </pre>
+	 * 
+	 * Examples:
+	 * 
+	 * <pre>
+	 * com.acme.capability.*
+	 * org.foo.capability
+	 * *
+	 * </pre>
+	 * 
+	 * For the {@code require} action, the name can also be a filter expression.
+	 * The filter gives access to the capability attributes as well as the
+	 * following attributes:
+	 * <ul>
+	 * <li>signer - A Distinguished Name chain used to sign the bundle providing
+	 * the capability. Wildcards in a DN are not matched according to the filter
+	 * string rules, but according to the rules defined for a DN chain.</li>
+	 * <li>location - The location of the bundle providing the capability.</li>
+	 * <li>id - The bundle ID of the bundle providing the capability.</li>
+	 * <li>name - The symbolic name of the bundle providing the capability.</li>
+	 * <li>capability.namespace - The name space of the required capability.</li>
+	 * </ul>
+	 * Since the above attribute names may conflict with attribute names of a
+	 * capability, you can prefix an attribute name with '@' in the filter
+	 * expression to match against the capability attributes and not one of the
+	 * above attributes. Filter attribute names are processed in a case
+	 * sensitive manner.
+	 * 
+	 * <p>
+	 * There are two possible actions: {@code require} and {@code provide}. The
+	 * {@code require} permission allows the owner of this permission to require
+	 * a capability matching the attributes. The {@code provide} permission
+	 * allows the bundle to provide a capability in the specified capability
+	 * name space.
+	 * 
+	 * @param name The capability name space or a filter over the attributes.
+	 * @param actions {@code require},{@code provide} (canonical order)
+	 * @throws IllegalArgumentException If the specified name is a filter
+	 *         expression and either the specified action is not {@code require}
+	 *         or the filter has an invalid syntax.
+	 */
+	public CapabilityPermission(String name, String actions) {
+		this(name, parseActions(actions));
+		if ((this.filter != null)
+				&& ((action_mask & ACTION_ALL) != ACTION_REQUIRE)) {
+			throw new IllegalArgumentException(
+					"invalid action string for filter expression");
+		}
+	}
+
+	/**
+	 * Creates a new requested {@code CapabilityPermission} object to be used by
+	 * code that must perform {@code checkPermission} for the {@code require}
+	 * action. {@code CapabilityPermission} objects created with this
+	 * constructor cannot be added to a {@code CapabilityPermission} permission
+	 * collection.
+	 * 
+	 * @param namespace The requested capability name space.
+	 * @param attributes The requested capability attributes.
+	 * @param providingBundle The bundle providing the requested capability.
+	 * @param actions The action {@code require}.
+	 * @throws IllegalArgumentException If the specified action is not
+	 *         {@code require} or attributes or providingBundle are {@code null}
+	 *         .
+	 */
+	public CapabilityPermission(String namespace, Map<String, ? > attributes,
+			Bundle providingBundle, String actions) {
+		super(namespace);
+		setTransients(namespace, parseActions(actions));
+		if (attributes == null) {
+			throw new IllegalArgumentException("attributes must not be null");
+		}
+		if (providingBundle == null) {
+			throw new IllegalArgumentException("bundle must not be null");
+		}
+		this.attributes = new HashMap<String, Object>(attributes);
+		this.bundle = providingBundle;
+		if ((action_mask & ACTION_ALL) != ACTION_REQUIRE) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+	}
+
+	/**
+	 * Package private constructor used by CapabilityPermissionCollection.
+	 * 
+	 * @param name class name
+	 * @param mask action mask
+	 */
+	CapabilityPermission(String name, int mask) {
+		super(name);
+		setTransients(name, mask);
+		this.attributes = null;
+		this.bundle = null;
+	}
+
+	/**
+	 * Called by constructors and when deserialized.
+	 * 
+	 * @param mask action mask
+	 */
+	private void setTransients(String name, int mask) {
+		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+		action_mask = mask;
+		filter = parseFilter(name);
+	}
+
+	/**
+	 * Parse action string into action mask.
+	 * 
+	 * @param actions Action string.
+	 * @return action mask.
+	 */
+	private static int parseActions(String actions) {
+		boolean seencomma = false;
+
+		int mask = ACTION_NONE;
+
+		if (actions == null) {
+			return mask;
+		}
+
+		char[] a = actions.toCharArray();
+
+		int i = a.length - 1;
+		if (i < 0)
+			return mask;
+
+		while (i != -1) {
+			char c;
+
+			// skip whitespace
+			while ((i != -1)
+					&& ((c = a[i]) == ' ' || c == '\r' || c == '\n'
+							|| c == '\f' || c == '\t'))
+				i--;
+
+			// check for the known strings
+			int matchlen;
+
+			if (i >= 6 && (a[i - 6] == 'r' || a[i - 6] == 'R')
+					&& (a[i - 5] == 'e' || a[i - 5] == 'E')
+					&& (a[i - 4] == 'q' || a[i - 4] == 'Q')
+					&& (a[i - 3] == 'u' || a[i - 3] == 'U')
+					&& (a[i - 2] == 'i' || a[i - 2] == 'I')
+					&& (a[i - 1] == 'r' || a[i - 1] == 'R')
+					&& (a[i] == 'e' || a[i] == 'E')) {
+				matchlen = 7;
+				mask |= ACTION_REQUIRE;
+			}
+			else
+				if (i >= 6 && (a[i - 6] == 'p' || a[i - 6] == 'P')
+						&& (a[i - 5] == 'r' || a[i - 5] == 'R')
+						&& (a[i - 4] == 'o' || a[i - 4] == 'O')
+						&& (a[i - 3] == 'v' || a[i - 3] == 'V')
+						&& (a[i - 2] == 'i' || a[i - 2] == 'I')
+						&& (a[i - 1] == 'd' || a[i - 1] == 'D')
+						&& (a[i] == 'e' || a[i] == 'E')) {
+					matchlen = 7;
+					mask |= ACTION_PROVIDE;
+				}
+				else {
+					// parse error
+					throw new IllegalArgumentException("invalid permission: "
+							+ actions);
+				}
+
+			// make sure we didn't just match the tail of a word
+			// like "ackbarfprovide". Also, skip to the comma.
+			seencomma = false;
+			while (i >= matchlen && !seencomma) {
+				switch (a[i - matchlen]) {
+					case ',' :
+						seencomma = true;
+						/* FALLTHROUGH */
+					case ' ' :
+					case '\r' :
+					case '\n' :
+					case '\f' :
+					case '\t' :
+						break;
+					default :
+						throw new IllegalArgumentException(
+								"invalid permission: " + actions);
+				}
+				i--;
+			}
+
+			// point i at the location of the comma minus one (or -1).
+			i -= matchlen;
+		}
+
+		if (seencomma) {
+			throw new IllegalArgumentException("invalid permission: " + actions);
+		}
+
+		return mask;
+	}
+
+	/**
+	 * Parse filter string into a Filter object.
+	 * 
+	 * @param filterString The filter string to parse.
+	 * @return a Filter for this bundle. If the specified filterString is not a
+	 *         filter expression, then {@code null} is returned.
+	 * @throws IllegalArgumentException If the filter syntax is invalid.
+	 */
+	private static Filter parseFilter(String filterString) {
+		filterString = filterString.trim();
+		if (filterString.charAt(0) != '(') {
+			return null;
+		}
+
+		try {
+			return FrameworkUtil.createFilter(filterString);
+		}
+		catch (InvalidSyntaxException e) {
+			IllegalArgumentException iae = new IllegalArgumentException(
+					"invalid filter");
+			iae.initCause(e);
+			throw iae;
+		}
+	}
+
+	/**
+	 * Determines if a {@code CapabilityPermission} object "implies" the
+	 * specified permission.
+	 * 
+	 * @param p The target permission to check.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	public boolean implies(Permission p) {
+		if (!(p instanceof CapabilityPermission)) {
+			return false;
+		}
+		CapabilityPermission requested = (CapabilityPermission) p;
+		if (bundle != null) {
+			return false;
+		}
+		// if requested permission has a filter, then it is an invalid argument
+		if (requested.filter != null) {
+			return false;
+		}
+		return implies0(requested, ACTION_NONE);
+	}
+
+	/**
+	 * Internal implies method. Used by the implies and the permission
+	 * collection implies methods.
+	 * 
+	 * @param requested The requested CapabilityPermission which has already be
+	 *        validated as a proper argument. The requested CapabilityPermission
+	 *        must not have a filter expression.
+	 * @param effective The effective actions with which to start.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
+	 */
+	boolean implies0(CapabilityPermission requested, int effective) {
+		/* check actions first - much faster */
+		effective |= action_mask;
+		final int desired = requested.action_mask;
+		if ((effective & desired) != desired) {
+			return false;
+		}
+		/* Get filter if any */
+		Filter f = filter;
+		if (f == null) {
+			return super.implies(requested);
+		}
+		return f.matches(requested.getProperties());
+	}
+
+	/**
+	 * Returns the canonical string representation of the actions. Always
+	 * returns present actions in the following order: {@code require},
+	 * {@code provide}.
+	 * 
+	 * @return The canonical string representation of the actions.
+	 */
+	public String getActions() {
+		String result = actions;
+		if (result == null) {
+			StringBuffer sb = new StringBuffer();
+			boolean comma = false;
+
+			int mask = action_mask;
+			if ((mask & ACTION_REQUIRE) == ACTION_REQUIRE) {
+				sb.append(REQUIRE);
+				comma = true;
+			}
+
+			if ((mask & ACTION_PROVIDE) == ACTION_PROVIDE) {
+				if (comma)
+					sb.append(',');
+				sb.append(PROVIDE);
+			}
+
+			actions = result = sb.toString();
+		}
+
+		return result;
+	}
+
+	/**
+	 * Returns a new {@code PermissionCollection} object for storing
+	 * {@code CapabilityPermission} objects.
+	 * 
+	 * @return A new {@code PermissionCollection} object suitable for storing
+	 *         {@code CapabilityPermission} objects.
+	 */
+	public PermissionCollection newPermissionCollection() {
+		return new CapabilityPermissionCollection();
+	}
+
+	/**
+	 * Determines the equality of two CapabilityPermission objects.
+	 * 
+	 * Checks that specified object has the same name and action as this
+	 * {@code CapabilityPermission}.
+	 * 
+	 * @param obj The object to test for equality.
+	 * @return true if obj is a {@code CapabilityPermission}, and has the same
+	 *         name and actions as this {@code CapabilityPermission} object;
+	 *         {@code false} otherwise.
+	 */
+	public boolean equals(Object obj) {
+		if (obj == this) {
+			return true;
+		}
+
+		if (!(obj instanceof CapabilityPermission)) {
+			return false;
+		}
+
+		CapabilityPermission cp = (CapabilityPermission) obj;
+
+		return (action_mask == cp.action_mask)
+				&& getName().equals(cp.getName())
+				&& ((attributes == cp.attributes) || ((attributes != null) && (attributes
+						.equals(cp.attributes))))
+				&& ((bundle == cp.bundle) || ((bundle != null) && bundle
+						.equals(cp.bundle)));
+	}
+
+	/**
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return Hash code value for this object.
+	 */
+	public int hashCode() {
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		if (attributes != null) {
+			h = 31 * h + attributes.hashCode();
+		}
+		if (bundle != null) {
+			h = 31 * h + bundle.hashCode();
+		}
+		return h;
+	}
+
+	/**
+	 * WriteObject is called to save the state of this permission to a stream.
+	 * The actions are serialized, and the superclass takes care of the name.
+	 */
+	private synchronized void writeObject(java.io.ObjectOutputStream s)
+			throws IOException {
+		if (bundle != null) {
+			throw new NotSerializableException("cannot serialize");
+		}
+		// Write out the actions. The superclass takes care of the name
+		// call getActions to make sure actions field is initialized
+		if (actions == null)
+			getActions();
+		s.defaultWriteObject();
+	}
+
+	/**
+	 * readObject is called to restore the state of this permission from a
+	 * stream.
+	 */
+	private synchronized void readObject(java.io.ObjectInputStream s)
+			throws IOException, ClassNotFoundException {
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		setTransients(getName(), parseActions(actions));
+	}
+
+	/**
+	 * Called by {@code <@link CapabilityPermission#implies(Permission)>}. This
+	 * method is only called on a requested permission which cannot have a
+	 * filter set.
+	 * 
+	 * @return a map of properties for this permission.
+	 */
+	private Map<String, Object> getProperties() {
+		Map<String, Object> result = properties;
+		if (result != null) {
+			return result;
+		}
+		final Map<String, Object> props = new HashMap<String, Object>(5);
+		props.put("capability.namespace", getName());
+		if (bundle == null) {
+			return properties = props;
+		}
+		AccessController.doPrivileged(new PrivilegedAction<Object>() {
+			public Object run() {
+				props.put("id", new Long(bundle.getBundleId()));
+				props.put("location", bundle.getLocation());
+				String name = bundle.getSymbolicName();
+				if (name != null) {
+					props.put("name", name);
+				}
+				SignerProperty signer = new SignerProperty(bundle);
+				if (signer.isBundleSigned()) {
+					props.put("signer", signer);
+				}
+				return null;
+			}
+		});
+		return properties = new Properties(props, attributes);
+	}
+
+	static private final class Properties extends AbstractMap<String, Object> {
+		private final Map<String, Object>							properties;
+		private final Map<String, Object>							attributes;
+		private transient volatile Set<Map.Entry<String, Object>>	entries;
+
+		Properties(Map<String, Object> properties,
+				Map<String, Object> attributes) {
+			this.properties = properties;
+			this.attributes = attributes;
+			entries = null;
+		}
+
+		public Object get(Object k) {
+			if (!(k instanceof String)) {
+				return null;
+			}
+			String key = (String) k;
+			if (key.charAt(0) == '@') {
+				return attributes.get(key.substring(1));
+			}
+			Object value = properties.get(key);
+			if (value != null) { // fall back to service properties
+				return value;
+			}
+			return attributes.get(key);
+		}
+
+		public Set<Map.Entry<String, Object>> entrySet() {
+			if (entries != null) {
+				return entries;
+			}
+			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(
+					attributes.size() + properties.size());
+			all.addAll(attributes.entrySet());
+			all.addAll(properties.entrySet());
+			return entries = Collections.unmodifiableSet(all);
+		}
+	}
+}
+
+/**
+ * Stores a set of CapabilityPermission permissions.
+ * 
+ * @see java.security.Permission
+ * @see java.security.Permissions
+ * @see java.security.PermissionCollection
+ */
+final class CapabilityPermissionCollection extends PermissionCollection {
+	static final long							serialVersionUID	= -615322242639008920L;
+
+	/**
+	 * Table of permissions.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private Map<String, CapabilityPermission>	permissions;
+
+	/**
+	 * Boolean saying if "*" is in the collection.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private boolean								all_allowed;
+
+	/**
+	 * Table of permissions with filter expressions.
+	 * 
+	 * @serial
+	 * @GuardedBy this
+	 */
+	private Map<String, CapabilityPermission>	filterPermissions;
+
+	/**
+	 * Creates an empty CapabilityPermissionCollection object.
+	 */
+	public CapabilityPermissionCollection() {
+		permissions = new HashMap<String, CapabilityPermission>();
+		all_allowed = false;
+	}
+
+	/**
+	 * Adds a permission to this permission collection.
+	 * 
+	 * @param permission The Permission object to add.
+	 * @throws IllegalArgumentException If the specified permission is not a
+	 *         CapabilityPermission object.
+	 * @throws SecurityException If this {@code CapabilityPermissionCollection}
+	 *         object has been marked read-only.
+	 */
+	public void add(final Permission permission) {
+		if (!(permission instanceof CapabilityPermission)) {
+			throw new IllegalArgumentException("invalid permission: "
+					+ permission);
+		}
+		if (isReadOnly()) {
+			throw new SecurityException("attempt to add a Permission to a "
+					+ "readonly PermissionCollection");
+		}
+
+		final CapabilityPermission cp = (CapabilityPermission) permission;
+		if (cp.bundle != null) {
+			throw new IllegalArgumentException("cannot add to collection: "
+					+ cp);
+		}
+
+		final String name = cp.getName();
+		final Filter f = cp.filter;
+		synchronized (this) {
+			/* select the bucket for the permission */
+			Map<String, CapabilityPermission> pc;
+			if (f != null) {
+				pc = filterPermissions;
+				if (pc == null) {
+					filterPermissions = pc = new HashMap<String, CapabilityPermission>();
+				}
+			}
+			else {
+				pc = permissions;
+			}
+			final CapabilityPermission existing = pc.get(name);
+
+			if (existing != null) {
+				final int oldMask = existing.action_mask;
+				final int newMask = cp.action_mask;
+				if (oldMask != newMask) {
+					pc.put(name, new CapabilityPermission(name, oldMask
+							| newMask));
+				}
+			}
+			else {
+				pc.put(name, cp);
+			}
+
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Determines if a set of permissions implies the permissions expressed in
+	 * {@code permission}.
+	 * 
+	 * @param permission The Permission object to compare.
+	 * @return {@code true} if {@code permission} is a proper subset of a
+	 *         permission in the set; {@code false} otherwise.
+	 */
+	public boolean implies(final Permission permission) {
+		if (!(permission instanceof CapabilityPermission)) {
+			return false;
+		}
+		final CapabilityPermission requested = (CapabilityPermission) permission;
+		/* if requested permission has a filter, then it is an invalid argument */
+		if (requested.filter != null) {
+			return false;
+		}
+
+		String requestedName = requested.getName();
+		final int desired = requested.action_mask;
+		int effective = CapabilityPermission.ACTION_NONE;
+
+		Collection<CapabilityPermission> perms;
+		synchronized (this) {
+			Map<String, CapabilityPermission> pc = permissions;
+			CapabilityPermission cp;
+			/* short circuit if the "*" Permission was added */
+			if (all_allowed) {
+				cp = pc.get("*");
+				if (cp != null) {
+					effective |= cp.action_mask;
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+			}
+
+			/*
+			 * strategy: Check for full match first. Then work our way up the
+			 * name looking for matches on a.b.*
+			 */
+			cp = pc.get(requestedName);
+			if (cp != null) {
+				/* we have a direct hit! */
+				effective |= cp.action_mask;
+				if ((effective & desired) == desired) {
+					return true;
+				}
+			}
+			/* work our way up the tree... */
+			int last;
+			int offset = requestedName.length() - 1;
+			while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
+				requestedName = requestedName.substring(0, last + 1) + "*";
+				cp = pc.get(requestedName);
+				if (cp != null) {
+					effective |= cp.action_mask;
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
+				offset = last - 1;
+			}
+			/*
+			 * we don't have to check for "*" as it was already checked before
+			 * we were called.
+			 */
+			pc = filterPermissions;
+			if (pc == null) {
+				return false;
+			}
+			perms = pc.values();
+		}
+		/* iterate one by one over filteredPermissions */
+		for (CapabilityPermission perm : perms) {
+			if (perm.implies0(requested, effective)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Returns an enumeration of all the {@code CapabilityPermission} objects in
+	 * the container.
+	 * 
+	 * @return Enumeration of all the CapabilityPermission objects.
+	 */
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		Map<String, CapabilityPermission> pc = filterPermissions;
+		if (pc != null) {
+			all.addAll(pc.values());
+		}
+		return Collections.enumeration(all);
+	}
+
+	/* serialization logic */
+	private static final ObjectStreamField[]	serialPersistentFields	= {
+			new ObjectStreamField("permissions", HashMap.class),
+			new ObjectStreamField("all_allowed", Boolean.TYPE),
+			new ObjectStreamField("filterPermissions", HashMap.class)	};
+
+	private synchronized void writeObject(ObjectOutputStream out)
+			throws IOException {
+		ObjectOutputStream.PutField pfields = out.putFields();
+		pfields.put("permissions", permissions);
+		pfields.put("all_allowed", all_allowed);
+		pfields.put("filterPermissions", filterPermissions);
+		out.writeFields();
+	}
+
+	private synchronized void readObject(java.io.ObjectInputStream in)
+			throws IOException, ClassNotFoundException {
+		ObjectInputStream.GetField gfields = in.readFields();
+		HashMap<String, CapabilityPermission> p = (HashMap<String, CapabilityPermission>) gfields
+				.get("permissions", null);
+		permissions = p;
+		all_allowed = gfields.get("all_allowed", false);
+		HashMap<String, CapabilityPermission> fp = (HashMap<String, CapabilityPermission>) gfields
+				.get("filterPermissions", null);
+		filterPermissions = fp;
+	}
+}
diff --git a/framework/src/main/java/org/osgi/framework/Configurable.java b/framework/src/main/java/org/osgi/framework/Configurable.java
index b30910c..d82da9b 100644
--- a/framework/src/main/java/org/osgi/framework/Configurable.java
+++ b/framework/src/main/java/org/osgi/framework/Configurable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,20 +20,20 @@
  * Supports a configuration object.
  * 
  * <p>
- * <code>Configurable</code> is an interface that should be used by a bundle
+ * {@code Configurable} is an interface that should be used by a bundle
  * developer in support of a configurable service. Bundles that need to
  * configure a service may test to determine if the service object is an
- * <code>instanceof Configurable</code>.
+ * {@code instanceof Configurable}.
  * 
  * @deprecated As of 1.2. Please use Configuration Admin service.
- * @version $Revision: 6361 $
+ * @version $Id: 29705c0c238aa456cda1b1a13458079bf1542771 $
  */
 public interface Configurable {
 	/**
 	 * Returns this service's configuration object.
 	 * 
 	 * <p>
-	 * Services implementing <code>Configurable</code> should take care when
+	 * Services implementing {@code Configurable} should take care when
 	 * returning a service configuration object since this object is probably
 	 * sensitive.
 	 * <p>
diff --git a/framework/src/main/java/org/osgi/framework/Constants.java b/framework/src/main/java/org/osgi/framework/Constants.java
index 16a10d8..b71a12d 100644
--- a/framework/src/main/java/org/osgi/framework/Constants.java
+++ b/framework/src/main/java/org/osgi/framework/Constants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2011). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,16 +16,19 @@
 
 package org.osgi.framework;
 
+import org.osgi.framework.launch.Framework;
+
 /**
  * Defines standard names for the OSGi environment system properties, service
  * properties, and Manifest header attribute keys.
  * 
  * <p>
- * The values associated with these keys are of type
- * <code>String</code>, unless otherwise indicated.
+ * The values associated with these keys are of type {@code String}, unless
+ * otherwise indicated.
  * 
  * @since 1.1
- * @version $Revision: 6552 $
+ * @noimplement
+ * @version $Id: 517c954ed7d34d2ee762933466f69fa03db7cd37 $
  */
 
 public interface Constants {
@@ -33,7 +36,7 @@
 	 * Location identifier of the OSGi <i>system bundle </i>, which is defined
 	 * to be &quot;System Bundle&quot;.
 	 */
-	public static final String	SYSTEM_BUNDLE_LOCATION					= "System Bundle";
+	String	SYSTEM_BUNDLE_LOCATION					= "System Bundle";
 
 	/**
 	 * Alias for the symbolic name of the OSGi <i>system bundle </i>. It is
@@ -41,50 +44,50 @@
 	 * 
 	 * @since 1.3
 	 */
-	public static final String	SYSTEM_BUNDLE_SYMBOLICNAME				= "system.bundle";
+	String	SYSTEM_BUNDLE_SYMBOLICNAME				= "system.bundle";
 
 	/**
 	 * Manifest header identifying the bundle's category.
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_CATEGORY							= "Bundle-Category";
+	String	BUNDLE_CATEGORY							= "Bundle-Category";
 
 	/**
 	 * Manifest header identifying a list of directories and embedded JAR files,
 	 * which are bundle resources used to extend the bundle's classpath.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_CLASSPATH						= "Bundle-ClassPath";
+	String	BUNDLE_CLASSPATH						= "Bundle-ClassPath";
 
 	/**
 	 * Manifest header identifying the bundle's copyright information.
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_COPYRIGHT						= "Bundle-Copyright";
+	String	BUNDLE_COPYRIGHT						= "Bundle-Copyright";
 
 	/**
 	 * Manifest header containing a brief description of the bundle's
 	 * functionality.
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_DESCRIPTION						= "Bundle-Description";
+	String	BUNDLE_DESCRIPTION						= "Bundle-Description";
 
 	/**
 	 * Manifest header identifying the bundle's name.
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_NAME								= "Bundle-Name";
+	String	BUNDLE_NAME								= "Bundle-Name";
 
 	/**
 	 * Manifest header identifying a number of hardware environments and the
@@ -92,20 +95,20 @@
 	 * these environments.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_NATIVECODE						= "Bundle-NativeCode";
+	String	BUNDLE_NATIVECODE						= "Bundle-NativeCode";
 
 	/**
 	 * Manifest header identifying the packages that the bundle offers to the
 	 * Framework for export.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	EXPORT_PACKAGE							= "Export-Package";
+	String	EXPORT_PACKAGE							= "Export-Package";
 
 	/**
 	 * Manifest header identifying the fully qualified class names of the
@@ -113,108 +116,108 @@
 	 * only).
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 * 
 	 * @deprecated As of 1.2.
 	 */
-	public static final String	EXPORT_SERVICE							= "Export-Service";
+	String	EXPORT_SERVICE							= "Export-Service";
 
 	/**
 	 * Manifest header identifying the packages on which the bundle depends.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	IMPORT_PACKAGE							= "Import-Package";
+	String	IMPORT_PACKAGE							= "Import-Package";
 
 	/**
 	 * Manifest header identifying the packages that the bundle may dynamically
 	 * import during execution.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 * 
 	 * @since 1.2
 	 */
-	public static final String	DYNAMICIMPORT_PACKAGE					= "DynamicImport-Package";
+	String	DYNAMICIMPORT_PACKAGE					= "DynamicImport-Package";
 
 	/**
 	 * Manifest header identifying the fully qualified class names of the
 	 * services that the bundle requires (used for informational purposes only).
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 * 
 	 * @deprecated As of 1.2.
 	 */
-	public static final String	IMPORT_SERVICE							= "Import-Service";
+	String	IMPORT_SERVICE							= "Import-Service";
 
 	/**
 	 * Manifest header identifying the bundle's vendor.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_VENDOR							= "Bundle-Vendor";
+	String	BUNDLE_VENDOR							= "Bundle-Vendor";
 
 	/**
 	 * Manifest header identifying the bundle's version.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_VERSION							= "Bundle-Version";
+	String	BUNDLE_VERSION							= "Bundle-Version";
 
 	/**
 	 * Manifest header identifying the bundle's documentation URL, from which
 	 * further information about the bundle may be obtained.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_DOCURL							= "Bundle-DocURL";
+	String	BUNDLE_DOCURL							= "Bundle-DocURL";
 
 	/**
 	 * Manifest header identifying the contact address where problems with the
 	 * bundle may be reported; for example, an email address.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_CONTACTADDRESS					= "Bundle-ContactAddress";
+	String	BUNDLE_CONTACTADDRESS					= "Bundle-ContactAddress";
 
 	/**
 	 * Manifest header attribute identifying the bundle's activator class.
 	 * 
 	 * <p>
 	 * If present, this header specifies the name of the bundle resource class
-	 * that implements the <code>BundleActivator</code> interface and whose
-	 * <code>start</code> and <code>stop</code> methods are called by the
-	 * Framework when the bundle is started and stopped, respectively.
+	 * that implements the {@code BundleActivator} interface and whose
+	 * {@code start} and {@code stop} methods are called by the Framework when
+	 * the bundle is started and stopped, respectively.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_ACTIVATOR						= "Bundle-Activator";
+	String	BUNDLE_ACTIVATOR						= "Bundle-Activator";
 
 	/**
 	 * Manifest header identifying the location from which a new bundle version
 	 * is obtained during a bundle update operation.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 */
-	public static final String	BUNDLE_UPDATELOCATION					= "Bundle-UpdateLocation";
+	String	BUNDLE_UPDATELOCATION					= "Bundle-UpdateLocation";
 
 	/**
 	 * Manifest header attribute identifying the version of a package specified
@@ -223,7 +226,7 @@
 	 * @deprecated As of 1.3. This has been replaced by
 	 *             {@link #VERSION_ATTRIBUTE}.
 	 */
-	public static final String	PACKAGE_SPECIFICATION_VERSION			= "specification-version";
+	String	PACKAGE_SPECIFICATION_VERSION			= "specification-version";
 
 	/**
 	 * Manifest header attribute identifying the processor required to run
@@ -239,7 +242,7 @@
 	 * 
 	 * @see #BUNDLE_NATIVECODE
 	 */
-	public static final String	BUNDLE_NATIVECODE_PROCESSOR				= "processor";
+	String	BUNDLE_NATIVECODE_PROCESSOR				= "processor";
 
 	/**
 	 * Manifest header attribute identifying the operating system required to
@@ -255,7 +258,7 @@
 	 * 
 	 * @see #BUNDLE_NATIVECODE
 	 */
-	public static final String	BUNDLE_NATIVECODE_OSNAME				= "osname";
+	String	BUNDLE_NATIVECODE_OSNAME				= "osname";
 
 	/**
 	 * Manifest header attribute identifying the operating system version
@@ -271,7 +274,7 @@
 	 * 
 	 * @see #BUNDLE_NATIVECODE
 	 */
-	public static final String	BUNDLE_NATIVECODE_OSVERSION				= "osversion";
+	String	BUNDLE_NATIVECODE_OSVERSION				= "osversion";
 
 	/**
 	 * Manifest header attribute identifying the language in which the native
@@ -287,7 +290,7 @@
 	 * 
 	 * @see #BUNDLE_NATIVECODE
 	 */
-	public static final String	BUNDLE_NATIVECODE_LANGUAGE				= "language";
+	String	BUNDLE_NATIVECODE_LANGUAGE				= "language";
 
 	/**
 	 * Manifest header identifying the required execution environment for the
@@ -296,27 +299,28 @@
 	 * environments it implements.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 * 
 	 * @since 1.2
+	 * @deprecated As of 1.6. Replaced by the {@code osgi.ee} capability.
 	 */
-	public static final String	BUNDLE_REQUIREDEXECUTIONENVIRONMENT		= "Bundle-RequiredExecutionEnvironment";
+	String	BUNDLE_REQUIREDEXECUTIONENVIRONMENT		= "Bundle-RequiredExecutionEnvironment";
 
 	/**
 	 * Manifest header identifying the bundle's symbolic name.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	BUNDLE_SYMBOLICNAME						= "Bundle-SymbolicName";
+	String	BUNDLE_SYMBOLICNAME						= "Bundle-SymbolicName";
 
 	/**
 	 * Manifest header directive identifying whether a bundle is a singleton.
-	 * The default value is <code>false</code>.
+	 * The default value is {@code false}.
 	 * 
 	 * <p>
 	 * The directive value is encoded in the Bundle-SymbolicName manifest header
@@ -326,14 +330,10 @@
 	 *     Bundle-SymbolicName: com.acme.module.test; singleton:=true
 	 * </pre>
 	 * 
-	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
-	 * 
 	 * @see #BUNDLE_SYMBOLICNAME
 	 * @since 1.3
 	 */
-	public final static String	SINGLETON_DIRECTIVE						= "singleton";
+	String	SINGLETON_DIRECTIVE						= "singleton";
 
 	/**
 	 * Manifest header directive identifying if and when a fragment may attach
@@ -354,7 +354,7 @@
 	 * @see #FRAGMENT_ATTACHMENT_NEVER
 	 * @since 1.3
 	 */
-	public final static String	FRAGMENT_ATTACHMENT_DIRECTIVE			= "fragment-attachment";
+	String	FRAGMENT_ATTACHMENT_DIRECTIVE			= "fragment-attachment";
 
 	/**
 	 * Manifest header directive value identifying a fragment attachment type of
@@ -373,7 +373,7 @@
 	 * @see #FRAGMENT_ATTACHMENT_DIRECTIVE
 	 * @since 1.3
 	 */
-	public final static String	FRAGMENT_ATTACHMENT_ALWAYS				= "always";
+	String	FRAGMENT_ATTACHMENT_ALWAYS				= "always";
 
 	/**
 	 * Manifest header directive value identifying a fragment attachment type of
@@ -392,7 +392,7 @@
 	 * @see #FRAGMENT_ATTACHMENT_DIRECTIVE
 	 * @since 1.3
 	 */
-	public final static String	FRAGMENT_ATTACHMENT_RESOLVETIME			= "resolve-time";
+	String	FRAGMENT_ATTACHMENT_RESOLVETIME			= "resolve-time";
 
 	/**
 	 * Manifest header directive value identifying a fragment attachment type of
@@ -410,46 +410,45 @@
 	 * @see #FRAGMENT_ATTACHMENT_DIRECTIVE
 	 * @since 1.3
 	 */
-	public final static String	FRAGMENT_ATTACHMENT_NEVER				= "never";
+	String	FRAGMENT_ATTACHMENT_NEVER				= "never";
 
 	/**
 	 * Manifest header identifying the base name of the bundle's localization
 	 * entries.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 * 
 	 * @see #BUNDLE_LOCALIZATION_DEFAULT_BASENAME
 	 * @since 1.3
 	 */
-	public final static String	BUNDLE_LOCALIZATION						= "Bundle-Localization";
+	String	BUNDLE_LOCALIZATION						= "Bundle-Localization";
 
 	/**
-	 * Default value for the <code>Bundle-Localization</code> manifest header.
+	 * Default value for the {@code Bundle-Localization} manifest header.
 	 * 
 	 * @see #BUNDLE_LOCALIZATION
 	 * @since 1.3
 	 */
-	public final static String	BUNDLE_LOCALIZATION_DEFAULT_BASENAME	= "OSGI-INF/l10n/bundle";
+	String	BUNDLE_LOCALIZATION_DEFAULT_BASENAME	= "OSGI-INF/l10n/bundle";
 
 	/**
 	 * Manifest header identifying the symbolic names of other bundles required
 	 * by the bundle.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	REQUIRE_BUNDLE							= "Require-Bundle";
+	String	REQUIRE_BUNDLE							= "Require-Bundle";
 
 	/**
 	 * Manifest header attribute identifying a range of versions for a bundle
-	 * specified in the <code>Require-Bundle</code> or
-	 * <code>Fragment-Host</code> manifest headers. The default value is
-	 * <code>0.0.0</code>.
+	 * specified in the {@code Require-Bundle} or {@code Fragment-Host} manifest
+	 * headers. The default value is {@code 0.0.0}.
 	 * 
 	 * <p>
 	 * The attribute value is encoded in the Require-Bundle manifest header
@@ -469,19 +468,19 @@
 	 * @see #REQUIRE_BUNDLE
 	 * @since 1.3
 	 */
-	public static final String	BUNDLE_VERSION_ATTRIBUTE				= "bundle-version";
+	String	BUNDLE_VERSION_ATTRIBUTE				= "bundle-version";
 
 	/**
 	 * Manifest header identifying the symbolic name of another bundle for which
 	 * that the bundle is a fragment.
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	FRAGMENT_HOST							= "Fragment-Host";
+	String	FRAGMENT_HOST							= "Fragment-Host";
 
 	/**
 	 * Manifest header attribute is used for selection by filtering based upon
@@ -497,7 +496,7 @@
 	 * @see #BUNDLE_NATIVECODE
 	 * @since 1.3
 	 */
-	public final static String	SELECTION_FILTER_ATTRIBUTE				= "selection-filter";
+	String	SELECTION_FILTER_ATTRIBUTE				= "selection-filter";
 
 	/**
 	 * Manifest header identifying the bundle manifest version. A bundle
@@ -509,12 +508,12 @@
 	 * specifically, by version 1.3 of the OSGi Core Specification is "2".
 	 * 
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 * 
 	 * @since 1.3
 	 */
-	public final static String	BUNDLE_MANIFESTVERSION					= "Bundle-ManifestVersion";
+	String	BUNDLE_MANIFESTVERSION					= "Bundle-ManifestVersion";
 
 	/**
 	 * Manifest header attribute identifying the version of a package specified
@@ -525,14 +524,14 @@
 	 * manifest header like:
 	 * 
 	 * <pre>
-	 *     Import-Package: org.osgi.framework; version=&quot;1.1&quot;
+	 *     Export-Package: org.osgi.framework; version=&quot;1.1&quot;
 	 * </pre>
 	 * 
 	 * @see #EXPORT_PACKAGE
 	 * @see #IMPORT_PACKAGE
 	 * @since 1.3
 	 */
-	public final static String	VERSION_ATTRIBUTE						= "version";
+	String	VERSION_ATTRIBUTE						= "version";
 
 	/**
 	 * Manifest header attribute identifying the symbolic name of a bundle that
@@ -549,88 +548,96 @@
 	 * @see #IMPORT_PACKAGE
 	 * @since 1.3
 	 */
-	public final static String	BUNDLE_SYMBOLICNAME_ATTRIBUTE			= "bundle-symbolic-name";
+	String	BUNDLE_SYMBOLICNAME_ATTRIBUTE			= "bundle-symbolic-name";
 
 	/**
 	 * Manifest header directive identifying the resolution type in the
-	 * Import-Package or Require-Bundle manifest header. The default value is
-	 * {@link #RESOLUTION_MANDATORY mandatory}.
+	 * Import-Package, Require-Bundle or Require-Capability manifest header. The
+	 * default value is {@link #RESOLUTION_MANDATORY mandatory}.
 	 * 
 	 * <p>
-	 * The directive value is encoded in the Import-Package or Require-Bundle
-	 * manifest header like:
+	 * The directive value is encoded in the Import-Package, Require-Bundle or
+	 * Require-Capability manifest header like:
 	 * 
 	 * <pre>
 	 *     Import-Package: org.osgi.framework; resolution:=&quot;optional&quot;
 	 *     Require-Bundle: com.acme.module.test; resolution:=&quot;optional&quot;
+	 *     Require-Capability: com.acme.capability; resolution:=&quot;optional&quot;
 	 * </pre>
 	 * 
 	 * @see #IMPORT_PACKAGE
 	 * @see #REQUIRE_BUNDLE
+	 * @see #REQUIRE_CAPABILITY
 	 * @see #RESOLUTION_MANDATORY
 	 * @see #RESOLUTION_OPTIONAL
 	 * @since 1.3
 	 */
-	public final static String	RESOLUTION_DIRECTIVE					= "resolution";
+	String	RESOLUTION_DIRECTIVE					= "resolution";
 
 	/**
 	 * Manifest header directive value identifying a mandatory resolution type.
-	 * A mandatory resolution type indicates that the import package or require
-	 * bundle must be resolved when the bundle is resolved. If such an import or
-	 * require bundle cannot be resolved, the module fails to resolve.
+	 * A mandatory resolution type indicates that the import package, require
+	 * bundle or require capability must be resolved when the bundle is
+	 * resolved. If such an import, require bundle or require capability cannot
+	 * be resolved, the module fails to resolve.
 	 * 
 	 * <p>
-	 * The directive value is encoded in the Import-Package or Require-Bundle
-	 * manifest header like:
+	 * The directive value is encoded in the Import-Package, Require-Bundle or
+	 * Require-Capability manifest header like:
 	 * 
 	 * <pre>
-	 *     Import-Package: org.osgi.framework; resolution:=&quot;manditory&quot;
-	 *     Require-Bundle: com.acme.module.test; resolution:=&quot;manditory&quot;
+	 *     Import-Package: org.osgi.framework; resolution:=&quot;mandatory&quot;
+	 *     Require-Bundle: com.acme.module.test; resolution:=&quot;mandatory&quot;
+	 *     Require-Capability: com.acme.capability; resolution:=&quot;mandatory&quot;
 	 * </pre>
 	 * 
 	 * @see #RESOLUTION_DIRECTIVE
 	 * @since 1.3
 	 */
-	public final static String	RESOLUTION_MANDATORY					= "mandatory";
+	String	RESOLUTION_MANDATORY					= "mandatory";
 
 	/**
 	 * Manifest header directive value identifying an optional resolution type.
-	 * An optional resolution type indicates that the import or require bundle
-	 * is optional and the bundle may be resolved without the import or require
-	 * bundle being resolved. If the import or require bundle is not resolved
-	 * when the bundle is resolved, the import or require bundle may not be
-	 * resolved before the bundle is refreshed.
+	 * An optional resolution type indicates that the import, require bundle or
+	 * require capability is optional and the bundle may be resolved without the
+	 * import, require bundle or require capability being resolved. If the
+	 * import, require bundle or require capability is not resolved when the
+	 * bundle is resolved, the import, require bundle or require capability may
+	 * not be resolved until the bundle is refreshed.
 	 * 
 	 * <p>
-	 * The directive value is encoded in the Import-Package or Require-Bundle
-	 * manifest header like:
+	 * The directive value is encoded in the Import-Package, Require-Bundle or
+	 * Require-Capability manifest header like:
 	 * 
 	 * <pre>
 	 *     Import-Package: org.osgi.framework; resolution:=&quot;optional&quot;
 	 *     Require-Bundle: com.acme.module.test; resolution:=&quot;optional&quot;
+	 *     Require-Capability: com.acme.capability; resolution:=&quot;optional&quot;
 	 * </pre>
 	 * 
 	 * @see #RESOLUTION_DIRECTIVE
 	 * @since 1.3
 	 */
-	public final static String	RESOLUTION_OPTIONAL						= "optional";
+	String	RESOLUTION_OPTIONAL						= "optional";
 
 	/**
 	 * Manifest header directive identifying a list of packages that an exported
-	 * package uses.
+	 * package or provided capability uses.
 	 * 
 	 * <p>
-	 * The directive value is encoded in the Export-Package manifest header
-	 * like:
+	 * The directive value is encoded in the Export-Package or
+	 * Provide-Capability manifest header like:
 	 * 
 	 * <pre>
 	 *     Export-Package: org.osgi.util.tracker; uses:=&quot;org.osgi.framework&quot;
+	 *     Provide-Capability: com.acme.capability; uses:=&quot;com.acme.service&quot;
 	 * </pre>
 	 * 
 	 * @see #EXPORT_PACKAGE
+	 * @see #PROVIDE_CAPABILITY
 	 * @since 1.3
 	 */
-	public final static String	USES_DIRECTIVE							= "uses";
+	String	USES_DIRECTIVE							= "uses";
 
 	/**
 	 * Manifest header directive identifying a list of classes to include in the
@@ -660,7 +667,7 @@
 	 * @see #BUNDLE_ACTIVATIONPOLICY
 	 * @since 1.3
 	 */
-	public final static String	INCLUDE_DIRECTIVE						= "include";
+	String	INCLUDE_DIRECTIVE						= "include";
 
 	/**
 	 * Manifest header directive identifying a list of classes to exclude in the
@@ -689,7 +696,7 @@
 	 * @see #BUNDLE_ACTIVATIONPOLICY
 	 * @since 1.3
 	 */
-	public final static String	EXCLUDE_DIRECTIVE						= "exclude";
+	String	EXCLUDE_DIRECTIVE						= "exclude";
 
 	/**
 	 * Manifest header directive identifying names of matching attributes which
@@ -707,7 +714,7 @@
 	 * @see #EXPORT_PACKAGE
 	 * @since 1.3
 	 */
-	public final static String	MANDATORY_DIRECTIVE						= "mandatory";
+	String	MANDATORY_DIRECTIVE						= "mandatory";
 
 	/**
 	 * Manifest header directive identifying the visibility of a required bundle
@@ -727,7 +734,7 @@
 	 * @see #VISIBILITY_REEXPORT
 	 * @since 1.3
 	 */
-	public final static String	VISIBILITY_DIRECTIVE					= "visibility";
+	String	VISIBILITY_DIRECTIVE					= "visibility";
 
 	/**
 	 * Manifest header directive value identifying a private visibility type. A
@@ -746,7 +753,7 @@
 	 * @see #VISIBILITY_DIRECTIVE
 	 * @since 1.3
 	 */
-	public final static String	VISIBILITY_PRIVATE						= "private";
+	String	VISIBILITY_PRIVATE						= "private";
 
 	/**
 	 * Manifest header directive value identifying a reexport visibility type. A
@@ -766,7 +773,7 @@
 	 * @see #VISIBILITY_DIRECTIVE
 	 * @since 1.3
 	 */
-	public final static String	VISIBILITY_REEXPORT						= "reexport";
+	String	VISIBILITY_REEXPORT						= "reexport";
 
 	/**
 	 * Manifest header directive identifying the type of the extension fragment.
@@ -783,7 +790,7 @@
 	 * @see #EXTENSION_BOOTCLASSPATH
 	 * @since 1.3
 	 */
-	public final static String	EXTENSION_DIRECTIVE						= "extension";
+	String	EXTENSION_DIRECTIVE						= "extension";
 
 	/**
 	 * Manifest header directive value identifying the type of extension
@@ -800,7 +807,7 @@
 	 * @see #EXTENSION_DIRECTIVE
 	 * @since 1.3
 	 */
-	public final static String	EXTENSION_FRAMEWORK						= "framework";
+	String	EXTENSION_FRAMEWORK						= "framework";
 
 	/**
 	 * Manifest header directive value identifying the type of extension
@@ -817,20 +824,20 @@
 	 * @see #EXTENSION_DIRECTIVE
 	 * @since 1.3
 	 */
-	public final static String	EXTENSION_BOOTCLASSPATH					= "bootclasspath";
+	String	EXTENSION_BOOTCLASSPATH					= "bootclasspath";
 
 	/**
 	 * Manifest header identifying the bundle's activation policy.
 	 * <p>
-	 * The attribute value may be retrieved from the <code>Dictionary</code>
-	 * object returned by the <code>Bundle.getHeaders</code> method.
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
 	 * 
 	 * @since 1.4
 	 * @see #ACTIVATION_LAZY
 	 * @see #INCLUDE_DIRECTIVE
 	 * @see #EXCLUDE_DIRECTIVE
 	 */
-	public final static String	BUNDLE_ACTIVATIONPOLICY					= "Bundle-ActivationPolicy";
+	String	BUNDLE_ACTIVATIONPOLICY					= "Bundle-ActivationPolicy";
 
 	/**
 	 * Bundle activation policy declaring the bundle must be activated when the
@@ -854,16 +861,16 @@
 	 * @see Bundle#START_ACTIVATION_POLICY
 	 * @since 1.4
 	 */
-	public final static String	ACTIVATION_LAZY							= "lazy";
+	String	ACTIVATION_LAZY							= "lazy";
 
 	/**
 	 * Framework environment property identifying the Framework version.
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 */
-	public static final String	FRAMEWORK_VERSION						= "org.osgi.framework.version";
+	String	FRAMEWORK_VERSION						= "org.osgi.framework.version";
 
 	/**
 	 * Framework environment property identifying the Framework implementation
@@ -871,79 +878,79 @@
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 */
-	public static final String	FRAMEWORK_VENDOR						= "org.osgi.framework.vendor";
+	String	FRAMEWORK_VENDOR						= "org.osgi.framework.vendor";
 
 	/**
-	 * Framework environment property identifying the Framework implementation
+	 * Framework launching property identifying the Framework implementation
 	 * language (see ISO 639 for possible values).
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 */
-	public static final String	FRAMEWORK_LANGUAGE						= "org.osgi.framework.language";
+	String	FRAMEWORK_LANGUAGE						= "org.osgi.framework.language";
 
 	/**
-	 * Framework environment property identifying the Framework host-computer's
+	 * Framework launching property identifying the Framework host-computer's
 	 * operating system.
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 */
-	public static final String	FRAMEWORK_OS_NAME						= "org.osgi.framework.os.name";
+	String	FRAMEWORK_OS_NAME						= "org.osgi.framework.os.name";
 
 	/**
-	 * Framework environment property identifying the Framework host-computer's
+	 * Framework launching property identifying the Framework host-computer's
 	 * operating system version number.
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 */
-	public static final String	FRAMEWORK_OS_VERSION					= "org.osgi.framework.os.version";
+	String	FRAMEWORK_OS_VERSION					= "org.osgi.framework.os.version";
 
 	/**
-	 * Framework environment property identifying the Framework host-computer's
+	 * Framework launching property identifying the Framework host-computer's
 	 * processor name.
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 */
-	public static final String	FRAMEWORK_PROCESSOR						= "org.osgi.framework.processor";
+	String	FRAMEWORK_PROCESSOR						= "org.osgi.framework.processor";
 
 	/**
-	 * Framework environment property identifying execution environments
-	 * provided by the Framework.
+	 * Framework launching property identifying execution environments provided
+	 * by the Framework.
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 * 
 	 * @since 1.2
+	 * @deprecated As of 1.6. Replaced by the {@code osgi.ee} capability.
 	 */
-	public static final String	FRAMEWORK_EXECUTIONENVIRONMENT			= "org.osgi.framework.executionenvironment";
+	String	FRAMEWORK_EXECUTIONENVIRONMENT			= "org.osgi.framework.executionenvironment";
 
 	/**
-	 * Framework environment property identifying packages for which the
-	 * Framework must delegate class loading to the parent class loader of the
-	 * bundle.
+	 * Framework launching property identifying packages for which the Framework
+	 * must delegate class loading to the parent class loader of the bundle.
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 * 
 	 * @see #FRAMEWORK_BUNDLE_PARENT
 	 * @since 1.3
 	 */
-	public static final String	FRAMEWORK_BOOTDELEGATION				= "org.osgi.framework.bootdelegation";
+	String	FRAMEWORK_BOOTDELEGATION				= "org.osgi.framework.bootdelegation";
 
 	/**
-	 * Framework environment property identifying packages which the system
-	 * bundle must export.
+	 * Framework launching property identifying packages which the system bundle
+	 * must export.
 	 * 
 	 * <p>
 	 * If this property is not specified then the framework must calculate a
@@ -951,15 +958,15 @@
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 * 
 	 * @since 1.3
 	 */
-	public static final String	FRAMEWORK_SYSTEMPACKAGES				= "org.osgi.framework.system.packages";
+	String	FRAMEWORK_SYSTEMPACKAGES				= "org.osgi.framework.system.packages";
 
 	/**
-	 * Framework environment property identifying extra packages which the
-	 * system bundle must export from the current execution environment.
+	 * Framework launching property identifying extra packages which the system
+	 * bundle must export from the current execution environment.
 	 * 
 	 * <p>
 	 * This property is useful for configuring extra system packages in addition
@@ -967,84 +974,84 @@
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 * 
 	 * @see #FRAMEWORK_SYSTEMPACKAGES
 	 * @since 1.5
 	 */
-	public static final String	FRAMEWORK_SYSTEMPACKAGES_EXTRA			= "org.osgi.framework.system.packages.extra";
+	String	FRAMEWORK_SYSTEMPACKAGES_EXTRA			= "org.osgi.framework.system.packages.extra";
 
 	/**
 	 * Framework environment property identifying whether the Framework supports
 	 * framework extension bundles.
 	 * 
 	 * <p>
-	 * As of version 1.4, the value of this property must be <code>true</code>.
-	 * The Framework must support framework extension bundles.
+	 * As of version 1.4, the value of this property must be {@code true}. The
+	 * Framework must support framework extension bundles.
 	 * 
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 * 
 	 * @since 1.3
 	 */
-	public static final String	SUPPORTS_FRAMEWORK_EXTENSION			= "org.osgi.supports.framework.extension";
+	String	SUPPORTS_FRAMEWORK_EXTENSION			= "org.osgi.supports.framework.extension";
 
 	/**
 	 * Framework environment property identifying whether the Framework supports
 	 * bootclasspath extension bundles.
 	 * 
 	 * <p>
-	 * If the value of this property is <code>true</code>, then the Framework
+	 * If the value of this property is {@code true}, then the Framework
 	 * supports bootclasspath extension bundles. The default value is
-	 * <code>false</code>.
+	 * {@code false}.
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 * 
 	 * @since 1.3
 	 */
-	public static final String	SUPPORTS_BOOTCLASSPATH_EXTENSION		= "org.osgi.supports.bootclasspath.extension";
+	String	SUPPORTS_BOOTCLASSPATH_EXTENSION		= "org.osgi.supports.bootclasspath.extension";
 
 	/**
 	 * Framework environment property identifying whether the Framework supports
 	 * fragment bundles.
 	 * 
 	 * <p>
-	 * As of version 1.4, the value of this property must be <code>true</code>.
-	 * The Framework must support fragment bundles.
+	 * As of version 1.4, the value of this property must be {@code true}. The
+	 * Framework must support fragment bundles.
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 * 
 	 * @since 1.3
 	 */
-	public static final String	SUPPORTS_FRAMEWORK_FRAGMENT				= "org.osgi.supports.framework.fragment";
+	String	SUPPORTS_FRAMEWORK_FRAGMENT				= "org.osgi.supports.framework.fragment";
 
 	/**
 	 * Framework environment property identifying whether the Framework supports
 	 * the {@link #REQUIRE_BUNDLE Require-Bundle} manifest header.
 	 * 
 	 * <p>
-	 * As of version 1.4, the value of this property must be <code>true</code>.
-	 * The Framework must support the <code>Require-Bundle</code> manifest
-	 * header.
+	 * As of version 1.4, the value of this property must be {@code true}. The
+	 * Framework must support the {@code Require-Bundle} manifest header.
 	 * <p>
 	 * The value of this property may be retrieved by calling the
-	 * <code>BundleContext.getProperty</code> method.
+	 * {@code BundleContext.getProperty} method.
 	 * 
 	 * @since 1.3
 	 */
-	public static final String	SUPPORTS_FRAMEWORK_REQUIREBUNDLE		= "org.osgi.supports.framework.requirebundle";
+	String	SUPPORTS_FRAMEWORK_REQUIREBUNDLE		= "org.osgi.supports.framework.requirebundle";
 
 	/**
-	 * Specifies the type of security manager the framework must use. If not
-	 * specified then the framework will not set the VM security manager.
+	 * Framework launching property specifying the type of security manager the
+	 * framework must use. If not specified then the framework will not set the
+	 * VM security manager.
 	 * 
 	 * @see #FRAMEWORK_SECURITY_OSGI
 	 * @since 1.5
 	 */
-	public final static String	FRAMEWORK_SECURITY						= "org.osgi.framework.security";
+	String	FRAMEWORK_SECURITY						= "org.osgi.framework.security";
 
 	/**
 	 * Specifies that a security manager that supports all security aspects of
@@ -1053,39 +1060,40 @@
 	 * 
 	 * <p>
 	 * If this value is specified and there is a security manager already
-	 * installed, then a <code>SecurityException</code> must be thrown when the
+	 * installed, then a {@code SecurityException} must be thrown when the
 	 * Framework is initialized.
 	 * 
 	 * @see #FRAMEWORK_SECURITY
 	 * @since 1.5
 	 */
-	public final static String	FRAMEWORK_SECURITY_OSGI					= "osgi";
+	String	FRAMEWORK_SECURITY_OSGI					= "osgi";
 
 	/**
-	 * Specified the persistent storage area used by the framework. The value of
-	 * this property must be a valid file path in the file system to a
-	 * directory. If the specified directory does not exist then the framework
-	 * will create the directory. If the specified path exists but is not a
-	 * directory or if the framework fails to create the storage directory, then
-	 * framework initialization must fail. The framework is free to use this
-	 * directory as it sees fit. This area can not be shared with anything else.
+	 * Framework launching property specifying the persistent storage area used
+	 * by the framework. The value of this property must be a valid file path in
+	 * the file system to a directory. If the specified directory does not exist
+	 * then the framework will create the directory. If the specified path
+	 * exists but is not a directory or if the framework fails to create the
+	 * storage directory, then framework initialization must fail. The framework
+	 * is free to use this directory as it sees fit. This area can not be shared
+	 * with anything else.
 	 * <p>
 	 * If this property is not set, the framework should use a reasonable
 	 * platform default for the persistent storage area.
 	 * 
 	 * @since 1.5
 	 */
-	public final static String	FRAMEWORK_STORAGE						= "org.osgi.framework.storage";
+	String	FRAMEWORK_STORAGE						= "org.osgi.framework.storage";
 
 	/**
-	 * Specifies if and when the persistent storage area for the framework
-	 * should be cleaned. If this property is not set, then the framework
-	 * storage area must not be cleaned.
+	 * Framework launching property specifying if and when the persistent
+	 * storage area for the framework should be cleaned. If this property is not
+	 * set, then the framework storage area must not be cleaned.
 	 * 
 	 * @see #FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT
 	 * @since 1.5
 	 */
-	public final static String	FRAMEWORK_STORAGE_CLEAN					= "org.osgi.framework.storage.clean";
+	String	FRAMEWORK_STORAGE_CLEAN					= "org.osgi.framework.storage.clean";
 
 	/**
 	 * Specifies that the framework storage area must be cleaned before the
@@ -1095,29 +1103,29 @@
 	 * 
 	 * @since 1.5
 	 */
-	public final static String  FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT			= "onFirstInit";
+	String	FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT		= "onFirstInit";
 
 	/**
-	 * 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. If this property is not set, then only the library name
-	 * returned by <code>System.mapLibraryName(String)</code> will be used to
-	 * search. This is needed for certain operating systems which allow more
-	 * than one extension for a library. For example, AIX allows library
-	 * extensions of <code>.a</code> and <code>.so</code>, but
-	 * <code>System.mapLibraryName(String)</code> will only return names with
-	 * the <code>.a</code> extension.
+	 * Framework launching property specifying a comma separated list of
+	 * additional library file extensions that must be used when a bundle's
+	 * class loader is searching for native libraries. If this property is not
+	 * set, then only the library name returned by
+	 * {@code System.mapLibraryName(String)} will be used to search. This is
+	 * needed for certain operating systems which allow more than one extension
+	 * for a library. For example, AIX allows library extensions of {@code .a}
+	 * and {@code .so}, but {@code System.mapLibraryName(String)} will only
+	 * return names with the {@code .a} extension.
 	 * 
 	 * @since 1.5
 	 */
-	public final static String	FRAMEWORK_LIBRARY_EXTENSIONS			= "org.osgi.framework.library.extensions";
+	String	FRAMEWORK_LIBRARY_EXTENSIONS			= "org.osgi.framework.library.extensions";
 
 	/**
-	 * Specifies an optional OS specific command to set file permissions on
-	 * extracted native code. On some operating systems, it is required that
-	 * native libraries be set to executable. This optional property allows you
-	 * to specify the command. For example, on a UNIX style OS, this property
-	 * could have the following value.
+	 * Framework launching property specifying an optional OS specific command
+	 * to set file permissions on extracted native code. On some operating
+	 * systems, it is required that native libraries be set to executable. This
+	 * optional property allows you to specify the command. For example, on a
+	 * UNIX style OS, this property could have the following value.
 	 * 
 	 * <pre>
 	 * chmod +rx ${abspath}
@@ -1128,16 +1136,24 @@
 	 * 
 	 * @since 1.5
 	 */
-	public final static String	FRAMEWORK_EXECPERMISSION				= "org.osgi.framework.command.execpermission";
+	String	FRAMEWORK_EXECPERMISSION				= "org.osgi.framework.command.execpermission";
 
 	/**
-	 * Specifies the trust repositories used by the framework. The value is a
-	 * <code>java.io.File.pathSeparator</code> separated list of valid file
-	 * paths to files that contain key stores of type <code>JKS</code>. The
-	 * framework will use the key stores as trust repositories to authenticate
-	 * certificates of trusted signers. The key stores are only used as
-	 * read-only trust repositories to access public keys. No passwords are
-	 * required to access the key stores' public keys.
+	 * Specified the substitution string for the absolute path of a file.
+	 * 
+	 * @see #FRAMEWORK_EXECPERMISSION
+	 * @since 1.6
+	 */
+	String	FRAMEWORK_COMMAND_ABSPATH				= "abspath";
+
+	/**
+	 * Framework launching property specifying the trust repositories used by
+	 * the framework. The value is a {@code java.io.File.pathSeparator}
+	 * separated list of valid file paths to files that contain key stores of
+	 * type {@code JKS}. The framework will use the key stores as trust
+	 * repositories to authenticate certificates of trusted signers. The key
+	 * stores are only used as read-only trust repositories to access public
+	 * keys. No passwords are required to access the key stores' public keys.
 	 * <p>
 	 * Note that framework implementations are allowed to use other trust
 	 * repositories in addition to the trust repositories specified by this
@@ -1146,27 +1162,29 @@
 	 * 
 	 * @since 1.5
 	 */
-	public final static String	FRAMEWORK_TRUST_REPOSITORIES			= "org.osgi.framework.trust.repositories";
+	String	FRAMEWORK_TRUST_REPOSITORIES			= "org.osgi.framework.trust.repositories";
 
 	/**
-	 * Specifies the current windowing system. The framework should provide a
-	 * reasonable default if this is not set.
+	 * Framework launching property specifying the current windowing system. The
+	 * framework should provide a reasonable default if this is not set.
 	 * 
 	 * @since 1.5
 	 */
-	public final static String	FRAMEWORK_WINDOWSYSTEM					= "org.osgi.framework.windowsystem";
+	String	FRAMEWORK_WINDOWSYSTEM					= "org.osgi.framework.windowsystem";
 
 	/**
-	 * Specifies the beginning start level of the framework.
+	 * Framework launching property specifying the beginning start level of the
+	 * framework.
 	 * 
-	 * @see "Core Specification, section 8.2.3."
+	 * @see "Core Specification, Starting the Framework."
 	 * @since 1.5
 	 */
-	public final static String	FRAMEWORK_BEGINNING_STARTLEVEL			= "org.osgi.framework.startlevel.beginning";
+	String	FRAMEWORK_BEGINNING_STARTLEVEL			= "org.osgi.framework.startlevel.beginning";
 
 	/**
-	 * Specifies the parent class loader type for all bundle class loaders.
-	 * Default value is {@link #FRAMEWORK_BUNDLE_PARENT_BOOT boot}.
+	 * Framework launching property specifying the parent class loader type for
+	 * all bundle class loaders. Default value is
+	 * {@link #FRAMEWORK_BUNDLE_PARENT_BOOT boot}.
 	 * 
 	 * @see #FRAMEWORK_BUNDLE_PARENT_BOOT
 	 * @see #FRAMEWORK_BUNDLE_PARENT_EXT
@@ -1174,7 +1192,7 @@
 	 * @see #FRAMEWORK_BUNDLE_PARENT_FRAMEWORK
 	 * @since 1.5
 	 */
-	public final static String FRAMEWORK_BUNDLE_PARENT 					= "org.osgi.framework.bundle.parent";
+	String	FRAMEWORK_BUNDLE_PARENT					= "org.osgi.framework.bundle.parent";
 
 	/**
 	 * Specifies to use of the boot class loader as the parent class loader for
@@ -1183,7 +1201,7 @@
 	 * @since 1.5
 	 * @see #FRAMEWORK_BUNDLE_PARENT
 	 */
-	public final static String	FRAMEWORK_BUNDLE_PARENT_BOOT			= "boot";
+	String	FRAMEWORK_BUNDLE_PARENT_BOOT			= "boot";
 
 	/**
 	 * Specifies to use the extension class loader as the parent class loader
@@ -1192,48 +1210,48 @@
 	 * @since 1.5
 	 * @see #FRAMEWORK_BUNDLE_PARENT
 	 */
-	public final static String	FRAMEWORK_BUNDLE_PARENT_EXT				= "ext";
+	String	FRAMEWORK_BUNDLE_PARENT_EXT				= "ext";
 
 	/**
 	 * Specifies to use the application class loader as the parent class loader
-	 * for all bundle class loaders.  Depending on how the framework is 
-	 * launched, this may refer to the same class loader as 
+	 * for all bundle class loaders. Depending on how the framework is launched,
+	 * this may refer to the same class loader as
 	 * {@link #FRAMEWORK_BUNDLE_PARENT_FRAMEWORK}.
 	 * 
 	 * @since 1.5
 	 * @see #FRAMEWORK_BUNDLE_PARENT
 	 */
-	public final static String	FRAMEWORK_BUNDLE_PARENT_APP				= "app";
+	String	FRAMEWORK_BUNDLE_PARENT_APP				= "app";
 
 	/**
 	 * Specifies to use the framework class loader as the parent class loader
 	 * for all bundle class loaders. The framework class loader is the class
-	 * loader used to load the framework implementation.  Depending on how the 
-	 * framework is launched, this may refer to the same class loader as 
+	 * loader used to load the framework implementation. Depending on how the
+	 * framework is launched, this may refer to the same class loader as
 	 * {@link #FRAMEWORK_BUNDLE_PARENT_APP}.
 	 * 
 	 * @since 1.5
 	 * @see #FRAMEWORK_BUNDLE_PARENT
 	 */
-	public final static String	FRAMEWORK_BUNDLE_PARENT_FRAMEWORK		= "framework";
+	String	FRAMEWORK_BUNDLE_PARENT_FRAMEWORK		= "framework";
 
 	/*
 	 * Service properties.
 	 */
-	
+
 	/**
 	 * Service property identifying all of the class names under which a service
 	 * was registered in the Framework. The value of this property must be of
-	 * type <code>String[]</code>.
+	 * type {@code String[]}.
 	 * 
 	 * <p>
 	 * This property is set by the Framework when a service is registered.
 	 */
-	public static final String	OBJECTCLASS								= "objectClass";
+	String	OBJECTCLASS								= "objectClass";
 
 	/**
 	 * Service property identifying a service's registration number. The value
-	 * of this property must be of type <code>Long</code>.
+	 * of this property must be of type {@code Long}.
 	 * 
 	 * <p>
 	 * The value of this property is assigned by the Framework when a service is
@@ -1241,72 +1259,426 @@
 	 * previously assigned values since the Framework was started. These values
 	 * are NOT persistent across restarts of the Framework.
 	 */
-	public static final String	SERVICE_ID								= "service.id";
+	String	SERVICE_ID								= "service.id";
 
 	/**
 	 * Service property identifying a service's persistent identifier.
 	 * 
 	 * <p>
-	 * This property may be supplied in the <code>properties</code>
-	 * <code>Dictionary</code> object passed to the
-	 * <code>BundleContext.registerService</code> method. The value of this
-	 * property must be of type <code>String</code>, <code>String[]</code>, or
-	 * <code>Collection</code> of <code>String</code>.
+	 * This property may be supplied in the {@code properties}
+	 * {@code Dictionary} object passed to the
+	 * {@code BundleContext.registerService} method. The value of this property
+	 * must be of type {@code String}, {@code String[]}, or {@code Collection}
+	 * of {@code String}.
 	 * 
 	 * <p>
 	 * A service's persistent identifier uniquely identifies the service and
 	 * persists across multiple Framework invocations.
 	 * 
 	 * <p>
-	 * By convention, every bundle has its own unique namespace, starting with
+	 * By convention, every bundle has its own unique name space, starting with
 	 * the bundle's identifier (see {@link Bundle#getBundleId}) and followed by
 	 * a dot (.). A bundle may use this as the prefix of the persistent
 	 * identifiers for the services it registers.
 	 */
-	public static final String	SERVICE_PID								= "service.pid";
+	String	SERVICE_PID								= "service.pid";
 
 	/**
 	 * Service property identifying a service's ranking number.
 	 * 
 	 * <p>
-	 * This property may be supplied in the <code>properties
-	 * Dictionary</code> object passed to the
-	 * <code>BundleContext.registerService</code> method. The value of this
-	 * property must be of type <code>Integer</code>.
+	 * This property may be supplied in the {@code properties
+	 * Dictionary} object passed to the {@code BundleContext.registerService}
+	 * method. The value of this property must be of type {@code Integer}.
 	 * 
 	 * <p>
 	 * The service ranking is used by the Framework to determine the <i>natural
-	 * order</i> of services, see {@link ServiceReference#compareTo(Object)},
-	 * and the <i>default</i> service to be returned from a call to the
+	 * order</i> of services, see {@link ServiceReference#compareTo}, and the
+	 * <i>default</i> service to be returned from a call to the
 	 * {@link BundleContext#getServiceReference} method.
 	 * 
 	 * <p>
 	 * The default ranking is zero (0). A service with a ranking of
-	 * <code>Integer.MAX_VALUE</code> is very likely to be returned as the
-	 * default service, whereas a service with a ranking of
-	 * <code>Integer.MIN_VALUE</code> is very unlikely to be returned.
+	 * {@code Integer.MAX_VALUE} is very likely to be returned as the default
+	 * service, whereas a service with a ranking of {@code Integer.MIN_VALUE} is
+	 * very unlikely to be returned.
 	 * 
 	 * <p>
-	 * If the supplied property value is not of type <code>Integer</code>, it is
+	 * If the supplied property value is not of type {@code Integer}, it is
 	 * deemed to have a ranking value of zero.
 	 */
-	public static final String	SERVICE_RANKING							= "service.ranking";
+	String	SERVICE_RANKING							= "service.ranking";
 
 	/**
 	 * Service property identifying a service's vendor.
 	 * 
 	 * <p>
-	 * This property may be supplied in the properties <code>Dictionary</code>
-	 * object passed to the <code>BundleContext.registerService</code> method.
+	 * This property may be supplied in the properties {@code Dictionary} object
+	 * passed to the {@code BundleContext.registerService} method.
 	 */
-	public static final String	SERVICE_VENDOR							= "service.vendor";
+	String	SERVICE_VENDOR							= "service.vendor";
 
 	/**
 	 * Service property identifying a service's description.
 	 * 
 	 * <p>
-	 * This property may be supplied in the properties <code>Dictionary</code>
-	 * object passed to the <code>BundleContext.registerService</code> method.
+	 * This property may be supplied in the properties {@code Dictionary} object
+	 * passed to the {@code BundleContext.registerService} method.
 	 */
-	public static final String	SERVICE_DESCRIPTION						= "service.description"; 
+	String	SERVICE_DESCRIPTION						= "service.description";
+
+	/**
+	 * Framework environment property identifying the Framework's universally
+	 * unique identifier (UUID). A UUID represents a 128-bit value. A new UUID
+	 * is generated by the {@link Framework#init()} method each time a framework
+	 * is initialized. The value of this property must conform to the UUID
+	 * string representation specified in <a
+	 * href="http://www.ietf.org/rfc/rfc4122.txt">RFC 4122</a>.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @since 1.6
+	 */
+	String	FRAMEWORK_UUID							= "org.osgi.framework.uuid";
+
+	/**
+	 * Service property identifying the configuration types supported by a
+	 * distribution provider. Registered by the distribution provider on one of
+	 * its services to indicate the supported configuration types.
+	 * 
+	 * <p>
+	 * The value of this property must be of type {@code String},
+	 * {@code String[]}, or {@code Collection} of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	REMOTE_CONFIGS_SUPPORTED				= "remote.configs.supported";
+
+	/**
+	 * Service property identifying the intents supported by a distribution
+	 * provider. Registered by the distribution provider on one of its services
+	 * to indicate the vocabulary of implemented intents.
+	 * 
+	 * <p>
+	 * The value of this property must be of type {@code String},
+	 * {@code String[]}, or {@code Collection} of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	REMOTE_INTENTS_SUPPORTED				= "remote.intents.supported";
+
+	/**
+	 * Service property identifying the configuration types that should be used
+	 * to export the service. Each configuration type represents the
+	 * configuration parameters for an endpoint. A distribution provider should
+	 * create an endpoint for each configuration type that it supports.
+	 * 
+	 * <p>
+	 * This property may be supplied in the {@code properties}
+	 * {@code Dictionary} object passed to the
+	 * {@code BundleContext.registerService} method. The value of this property
+	 * must be of type {@code String}, {@code String[]}, or {@code Collection}
+	 * of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_EXPORTED_CONFIGS				= "service.exported.configs";
+
+	/**
+	 * Service property identifying the intents that the distribution provider
+	 * must implement to distribute the service. Intents listed in this property
+	 * are reserved for intents that are critical for the code to function
+	 * correctly, for example, ordering of messages. These intents should not be
+	 * configurable.
+	 * 
+	 * <p>
+	 * This property may be supplied in the {@code properties}
+	 * {@code Dictionary} object passed to the
+	 * {@code BundleContext.registerService} method. The value of this property
+	 * must be of type {@code String}, {@code String[]}, or {@code Collection}
+	 * of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_EXPORTED_INTENTS				= "service.exported.intents";
+
+	/**
+	 * Service property identifying the extra intents that the distribution
+	 * provider must implement to distribute the service. This property is
+	 * merged with the {@code service.exported.intents} property before the
+	 * distribution provider interprets the listed intents; it has therefore the
+	 * same semantics but the property should be configurable so the
+	 * administrator can choose the intents based on the topology. Bundles
+	 * should therefore make this property configurable, for example through the
+	 * Configuration Admin service.
+	 * 
+	 * <p>
+	 * This property may be supplied in the {@code properties}
+	 * {@code Dictionary} object passed to the
+	 * {@code BundleContext.registerService} method. The value of this property
+	 * must be of type {@code String}, {@code String[]}, or {@code Collection}
+	 * of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_EXPORTED_INTENTS_EXTRA			= "service.exported.intents.extra";
+
+	/**
+	 * Service property marking the service for export. It defines the
+	 * interfaces under which this service can be exported. This list must be a
+	 * subset of the types under which the service was registered. The single
+	 * value of an asterisk (&quot;*&quot;, &#92;u002A) indicates all the
+	 * interface types under which the service was registered excluding the
+	 * non-interface types. It is strongly recommended to only export interface
+	 * types and not concrete classes due to the complexity of creating proxies
+	 * for some type of concrete classes.
+	 * 
+	 * <p>
+	 * This property may be supplied in the {@code properties}
+	 * {@code Dictionary} object passed to the
+	 * {@code BundleContext.registerService} method. The value of this property
+	 * must be of type {@code String}, {@code String[]}, or {@code Collection}
+	 * of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_EXPORTED_INTERFACES				= "service.exported.interfaces";
+
+	/**
+	 * Service property identifying the service as imported. This service
+	 * property must be set by a distribution provider to any value when it
+	 * registers the endpoint proxy as an imported service. A bundle can use
+	 * this property to filter out imported services.
+	 * 
+	 * <p>
+	 * The value of this property may be of any type.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_IMPORTED						= "service.imported";
+
+	/**
+	 * Service property identifying the configuration types used to import the
+	 * service. Any associated properties for this configuration types must be
+	 * properly mapped to the importing system. For example, a URL in these
+	 * properties must point to a valid resource when used in the importing
+	 * framework. If multiple configuration types are listed in this property,
+	 * then they must be synonyms for exactly the same remote endpoint that is
+	 * used to export this service.
+	 * 
+	 * <p>
+	 * The value of this property must be of type {@code String},
+	 * {@code String[]}, or {@code Collection} of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 * @see #SERVICE_EXPORTED_CONFIGS
+	 */
+	String	SERVICE_IMPORTED_CONFIGS				= "service.imported.configs";
+
+	/**
+	 * Service property identifying the intents that this service implement.
+	 * This property has a dual purpose:
+	 * <ul>
+	 * <li>A bundle can use this service property to notify the distribution
+	 * provider that these intents are already implemented by the exported
+	 * service object.</li>
+	 * <li>A distribution provider must use this property to convey the combined
+	 * intents of: the exporting service, the intents that the exporting
+	 * distribution provider adds, and the intents that the importing
+	 * distribution provider adds.</li>
+	 * </ul>
+	 * 
+	 * To export a service, a distribution provider must expand any qualified
+	 * intents. Both the exporting and importing distribution providers must
+	 * recognize all intents before a service can be distributed.
+	 * 
+	 * <p>
+	 * The value of this property must be of type {@code String},
+	 * {@code String[]}, or {@code Collection} of {@code String}.
+	 * 
+	 * @since 1.6
+	 * @see "Remote Services Specification"
+	 */
+	String	SERVICE_INTENTS							= "service.intents";
+
+	/**
+	 * Manifest header identifying the capabilities that the bundle offers to
+	 * provide to other bundles.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.6
+	 */
+	String	PROVIDE_CAPABILITY						= "Provide-Capability";
+
+	/**
+	 * Manifest header identifying the capabilities on which the bundle depends.
+	 * 
+	 * <p>
+	 * The header value may be retrieved from the {@code Dictionary} object
+	 * returned by the {@code Bundle.getHeaders} method.
+	 * 
+	 * @since 1.6
+	 */
+	String	REQUIRE_CAPABILITY						= "Require-Capability";
+
+	/**
+	 * Manifest header directive identifying the effective time of the provided
+	 * capability. The default value is {@link #EFFECTIVE_RESOLVE resolve}.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Provide-Capability manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Provide-Capability: com.acme.capability; effective:=&quot;resolve&quot;
+	 * </pre>
+	 * 
+	 * @see #PROVIDE_CAPABILITY
+	 * @see #EFFECTIVE_RESOLVE
+	 * @see #EFFECTIVE_ACTIVE
+	 * @since 1.6
+	 */
+	String	EFFECTIVE_DIRECTIVE						= "effective";
+
+	/**
+	 * Manifest header directive value identifying a capability that is
+	 * effective at resolve time. Capabilities with an effective time of resolve
+	 * are the only capabilities which are processed by the resolver.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Provide-Capability manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Provide-Capability: com.acme.capability; effective:=&quot;resolve&quot;
+	 * </pre>
+	 * 
+	 * @see #EFFECTIVE_DIRECTIVE
+	 * @since 1.6
+	 */
+	String	EFFECTIVE_RESOLVE						= "resolve";
+
+	/**
+	 * Manifest header directive value identifying a capability that is
+	 * effective at active time. Capabilities with an effective time of active
+	 * are ignored by the resolver.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Provide-Capability manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Provide-Capability: com.acme.capability; effective:=&quot;active&quot;
+	 * </pre>
+	 * 
+	 * @see #EFFECTIVE_DIRECTIVE
+	 * @since 1.6
+	 */
+	String	EFFECTIVE_ACTIVE						= "active";
+
+	/**
+	 * Manifest header directive identifying the capability filter specified in
+	 * the Require-Capability manifest header.
+	 * 
+	 * <p>
+	 * The directive value is encoded in the Require-Capability manifest header
+	 * like:
+	 * 
+	 * <pre>
+	 *     Require-Capability: com.acme.capability; filter:=&quot;(someattr=somevalue)&quot;
+	 * </pre>
+	 * 
+	 * @see #REQUIRE_CAPABILITY
+	 * @since 1.6
+	 */
+	String	FILTER_DIRECTIVE						= "filter";
+
+	/**
+	 * Framework launching property identifying capabilities which the system
+	 * bundle must provide.
+	 * 
+	 * <p>
+	 * If this property is not specified then the framework must calculate a
+	 * reasonable default value for the current execution environment.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @since 1.6
+	 */
+	String	FRAMEWORK_SYSTEMCAPABILITIES			= "org.osgi.framework.system.capabilities";
+
+	/**
+	 * Framework launching property identifying extra capabilities which the
+	 * system bundle must additionally provide.
+	 * 
+	 * <p>
+	 * This property is useful for configuring extra system capabilities in
+	 * addition to the system capabilities calculated by the framework.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @see #FRAMEWORK_SYSTEMCAPABILITIES
+	 * @since 1.6
+	 */
+	String	FRAMEWORK_SYSTEMCAPABILITIES_EXTRA		= "org.osgi.framework.system.capabilities.extra";
+
+	/**
+	 * Framework launching property specifying whether multiple bundles having
+	 * the same {@link #BUNDLE_SYMBOLICNAME symbolic name} and
+	 * {@link #BUNDLE_VERSION version} may be installed.
+	 * 
+	 * <p>
+	 * Default value is {@link #FRAMEWORK_BSNVERSION_SINGLE single} in this
+	 * release of the specification. This default may change to
+	 * {@link #FRAMEWORK_BSNVERSION_MULTIPLE multiple} in a future specification
+	 * release. Therefore, code must not assume the default behavior is
+	 * {@code single} and should interrogate the value of this property to
+	 * determine the behavior.
+	 * 
+	 * <p>
+	 * The value of this property may be retrieved by calling the
+	 * {@code BundleContext.getProperty} method.
+	 * 
+	 * @see #FRAMEWORK_BSNVERSION_MULTIPLE
+	 * @see #FRAMEWORK_BSNVERSION_SINGLE
+	 * @since 1.6
+	 */
+	String	FRAMEWORK_BSNVERSION					= "org.osgi.framework.bsnversion";
+
+	/**
+	 * Specifies the framework will allow multiple bundles to be installed
+	 * having the same symbolic name and version.
+	 * 
+	 * @since 1.6
+	 * @see #FRAMEWORK_BSNVERSION
+	 */
+	String	FRAMEWORK_BSNVERSION_MULTIPLE			= "multiple";
+
+	/**
+	 * Specifies the framework will only allow a single bundle to be installed
+	 * for a given symbolic name and version. It will be an error to install a
+	 * bundle or update a bundle to have the same symbolic name and version as
+	 * another installed bundle.
+	 * 
+	 * @since 1.6
+	 * @see #FRAMEWORK_BSNVERSION
+	 */
+	String	FRAMEWORK_BSNVERSION_SINGLE				= "single";
 }
diff --git a/framework/src/main/java/org/osgi/framework/Filter.java b/framework/src/main/java/org/osgi/framework/Filter.java
index 81c3e5b..a9bb6c3 100644
--- a/framework/src/main/java/org/osgi/framework/Filter.java
+++ b/framework/src/main/java/org/osgi/framework/Filter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,17 +16,16 @@
 package org.osgi.framework;
 
 import java.util.Dictionary;
+import java.util.Map;
 
 /**
- * An RFC 1960-based Filter.
+ * An <a href="http://www.ietf.org/rfc/rfc1960.txt">RFC 1960</a>-based Filter.
  * <p>
- * <code>Filter</code>s can be created by calling
- * {@link BundleContext#createFilter} or {@link FrameworkUtil#createFilter} with
- * a filter string.
+ * {@code Filter}s can be created by calling {@link BundleContext#createFilter}
+ * or {@link FrameworkUtil#createFilter} with a filter string.
  * <p>
- * A <code>Filter</code> can be used numerous times to determine if the match
- * argument matches the filter string that was used to create the
- * <code>Filter</code>.
+ * A {@code Filter} can be used numerous times to determine if the match
+ * argument matches the filter string that was used to create the {@code Filter}.
  * <p>
  * Some examples of LDAP filters are:
  * 
@@ -38,86 +37,100 @@
  * </pre>
  * 
  * @since 1.1
- * @see "Core Specification, section 5.5, for a description of the filter string syntax."
+ * @see "Core Specification, Filters, for a description of the filter string syntax."
  * @ThreadSafe
- * @version $Revision: 6860 $
+ * @noimplement
+ * @version $Id: 4d21267f4b85d1912d73f7e2c049cc968c4237f9 $
  */
 public interface Filter {
 	/**
 	 * Filter using a service's properties.
 	 * <p>
-	 * This <code>Filter</code> is executed using the keys and values of the
-	 * referenced service's properties. The keys are case insensitively matched
-	 * with this <code>Filter</code>.
+	 * This {@code Filter} is executed using the keys and values of the
+	 * referenced service's properties. The keys are looked up in a case
+	 * insensitive manner.
 	 * 
 	 * @param reference The reference to the service whose properties are used
 	 *        in the match.
-	 * @return <code>true</code> if the service's properties match this
-	 *         <code>Filter</code>; <code>false</code> otherwise.
+	 * @return {@code true} if the service's properties match this
+	 *         {@code Filter}; {@code false} otherwise.
 	 */
-	public boolean match(ServiceReference reference);
+	boolean match(ServiceReference< ? > reference);
 
 	/**
-	 * Filter using a <code>Dictionary</code>. This <code>Filter</code> is
-	 * executed using the specified <code>Dictionary</code>'s keys and values.
-	 * The keys are case insensitively matched with this <code>Filter</code>.
+	 * Filter using a {@code Dictionary} with case insensitive key lookup. This
+	 * {@code Filter} is executed using the specified {@code Dictionary}'s keys
+	 * and values. The keys are looked up in a case insensitive manner.
 	 * 
-	 * @param dictionary The <code>Dictionary</code> whose keys are used in the
-	 *        match.
-	 * @return <code>true</code> if the <code>Dictionary</code>'s keys and
-	 *         values match this filter; <code>false</code> otherwise.
-	 * @throws IllegalArgumentException If <code>dictionary</code> contains case
+	 * @param dictionary The {@code Dictionary} whose key/value pairs are used
+	 *        in the match.
+	 * @return {@code true} if the {@code Dictionary}'s values match this
+	 *         filter; {@code false} otherwise.
+	 * @throws IllegalArgumentException If {@code dictionary} contains case
 	 *         variants of the same key name.
 	 */
-	public boolean match(Dictionary dictionary);
+	boolean match(Dictionary<String, ? > dictionary);
 
 	/**
-	 * Returns this <code>Filter</code>'s filter string.
+	 * Returns this {@code Filter}'s filter string.
 	 * <p>
 	 * The filter string is normalized by removing whitespace which does not
 	 * affect the meaning of the filter.
 	 * 
-	 * @return This <code>Filter</code>'s filter string.
+	 * @return This {@code Filter}'s filter string.
 	 */
-	public String toString();
+	String toString();
 
 	/**
-	 * Compares this <code>Filter</code> to another <code>Filter</code>.
+	 * Compares this {@code Filter} to another {@code Filter}.
 	 * 
 	 * <p>
-	 * This method returns the result of calling
-	 * <code>this.toString().equals(obj.toString())</code>.
+	 * This implementation returns the result of calling
+	 * {@code this.toString().equals(obj.toString())}.
 	 * 
-	 * @param obj The object to compare against this <code>Filter</code>.
-	 * @return If the other object is a <code>Filter</code> object, then returns
+	 * @param obj The object to compare against this {@code Filter}.
+	 * @return If the other object is a {@code Filter} object, then returns
 	 *         the result of calling
-	 *         <code>this.toString().equals(obj.toString())</code>;
-	 *         <code>false</code> otherwise.
+	 *         {@code this.toString().equals(obj.toString())};
+	 *         {@code false} otherwise.
 	 */
-	public boolean equals(Object obj);
+	boolean equals(Object obj);
 
 	/**
-	 * Returns the hashCode for this <code>Filter</code>.
+	 * Returns the hashCode for this {@code Filter}.
 	 * 
 	 * <p>
-	 * This method returns the result of calling
-	 * <code>this.toString().hashCode()</code>.
+	 * This implementation returns the result of calling
+	 * {@code this.toString().hashCode()}.
 	 * 
-	 * @return The hashCode of this <code>Filter</code>.
+	 * @return The hashCode of this {@code Filter}.
 	 */
-	public int hashCode();
+	int hashCode();
 
 	/**
-	 * Filter with case sensitivity using a <code>Dictionary</code>. This
-	 * <code>Filter</code> is executed using the specified
-	 * <code>Dictionary</code>'s keys and values. The keys are case sensitively
-	 * matched with this <code>Filter</code>.
+	 * Filter using a {@code Dictionary}. This {@code Filter} is executed using
+	 * the specified {@code Dictionary}'s keys and values. The keys are looked
+	 * up in a normal manner respecting case.
 	 * 
-	 * @param dictionary The <code>Dictionary</code> whose keys are used in the
-	 *        match.
-	 * @return <code>true</code> if the <code>Dictionary</code>'s keys and
-	 *         values match this filter; <code>false</code> otherwise.
+	 * @param dictionary The {@code Dictionary} whose key/value pairs are used
+	 *        in the match.
+	 * @return {@code true} if the {@code Dictionary}'s values match this
+	 *         filter; {@code false} otherwise.
 	 * @since 1.3
 	 */
-	public boolean matchCase(Dictionary dictionary);
+	boolean matchCase(Dictionary<String, ? > dictionary);
+
+	/**
+	 * Filter using a {@code Map}. This {@code Filter} is executed using the
+	 * specified {@code Map}'s keys and values. The keys are looked up in a
+	 * normal manner respecting case.
+	 * 
+	 * @param map The {@code Map} whose key/value pairs are used in the match.
+	 *        Maps with {@code null} key or values are not supported. A
+	 *        {@code null} value is considered not present to the filter.
+	 * @return {@code true} if the {@code Map}'s values match this filter;
+	 *         {@code false} otherwise.
+	 * @since 1.6
+	 */
+	boolean matches(Map<String, ? > map);
 }
diff --git a/framework/src/main/java/org/osgi/framework/FrameworkEvent.java b/framework/src/main/java/org/osgi/framework/FrameworkEvent.java
index 747b249..d309699 100644
--- a/framework/src/main/java/org/osgi/framework/FrameworkEvent.java
+++ b/framework/src/main/java/org/osgi/framework/FrameworkEvent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,12 +18,15 @@
 
 import java.util.EventObject;
 
+import org.osgi.framework.startlevel.FrameworkStartLevel;
+import org.osgi.framework.wiring.FrameworkWiring;
+
 /**
  * A general event from the Framework.
  * 
  * <p>
- * <code>FrameworkEvent</code> objects are delivered to
- * <code>FrameworkListener</code>s when a general event occurs within the OSGi
+ * {@code FrameworkEvent} objects are delivered to
+ * {@code FrameworkListener}s when a general event occurs within the OSGi
  * environment. A type code is used to identify the event type for future
  * extendability.
  * 
@@ -32,7 +35,7 @@
  * 
  * @Immutable
  * @see FrameworkListener
- * @version $Revision: 6542 $
+ * @version $Id: e05c6ffd542fa432835961882bf6b15b0620ffb6 $
  */
 
 public class FrameworkEvent extends EventObject {
@@ -61,7 +64,7 @@
 	 * has reached the initial start level. The source of this event is the
 	 * System Bundle.
 	 * 
-	 * @see "The Start Level Service"
+	 * @see "The Start Level Specification"
 	 */
 	public final static int	STARTED							= 0x00000001;
 
@@ -74,20 +77,21 @@
 	public final static int	ERROR							= 0x00000002;
 
 	/**
-	 * A PackageAdmin.refreshPackage operation has completed.
+	 * A FrameworkWiring.refreshBundles operation has completed.
 	 * 
 	 * <p>
-	 * This event is fired when the Framework has completed the refresh packages
-	 * operation initiated by a call to the PackageAdmin.refreshPackages method.
-	 * The source of this event is the System Bundle.
+	 * This event is fired when the Framework has completed the refresh bundles
+	 * operation initiated by a call to the FrameworkWiring.refreshBundles
+	 * method. The source of this event is the System Bundle.
 	 * 
 	 * @since 1.2
-	 * @see "<code>PackageAdmin.refreshPackages</code>"
+	 * @see FrameworkWiring#refreshBundles(java.util.Collection,
+	 *      FrameworkListener...)
 	 */
 	public final static int	PACKAGES_REFRESHED				= 0x00000004;
 
 	/**
-	 * A StartLevel.setStartLevel operation has completed.
+	 * A FrameworkStartLevel.setStartLevel operation has completed.
 	 * 
 	 * <p>
 	 * This event is fired when the Framework has completed changing the active
@@ -95,7 +99,7 @@
 	 * The source of this event is the System Bundle.
 	 * 
 	 * @since 1.2
-	 * @see "The Start Level Service"
+	 * @see FrameworkStartLevel#setStartLevel(int, FrameworkListener...)
 	 */
 	public final static int	STARTLEVEL_CHANGED				= 0x00000008;
 
@@ -170,7 +174,7 @@
 	 * Creates a Framework event.
 	 * 
 	 * @param type The event type.
-	 * @param source The event source object. This may not be <code>null</code>.
+	 * @param source The event source object. This may not be {@code null}.
 	 * @deprecated As of 1.2. This constructor is deprecated in favor of using
 	 *             the other constructor with the System Bundle as the event
 	 *             source.
@@ -188,7 +192,7 @@
 	 * @param type The event type.
 	 * @param bundle The event source.
 	 * @param throwable The related exception. This argument may be
-	 *        <code>null</code> if there is no related exception.
+	 *        {@code null} if there is no related exception.
 	 */
 	public FrameworkEvent(int type, Bundle bundle, Throwable throwable) {
 		super(bundle);
@@ -200,7 +204,7 @@
 	/**
 	 * Returns the exception related to this event.
 	 * 
-	 * @return The related exception or <code>null</code> if none.
+	 * @return The related exception or {@code null} if none.
 	 */
 	public Throwable getThrowable() {
 		return throwable;
diff --git a/framework/src/main/java/org/osgi/framework/FrameworkListener.java b/framework/src/main/java/org/osgi/framework/FrameworkListener.java
index c96c490..5d73fb9 100644
--- a/framework/src/main/java/org/osgi/framework/FrameworkListener.java
+++ b/framework/src/main/java/org/osgi/framework/FrameworkListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,31 +19,31 @@
 import java.util.EventListener;
 
 /**
- * A <code>FrameworkEvent</code> listener. <code>FrameworkListener</code> is
+ * A {@code FrameworkEvent} listener. {@code FrameworkListener} is
  * a listener interface that may be implemented by a bundle developer. When a
- * <code>FrameworkEvent</code> is fired, it is asynchronously delivered to a
- * <code>FrameworkListener</code>. The Framework delivers
- * <code>FrameworkEvent</code> objects to a <code>FrameworkListener</code>
- * in order and must not concurrently call a <code>FrameworkListener</code>.
+ * {@code FrameworkEvent} is fired, it is asynchronously delivered to a
+ * {@code FrameworkListener}. The Framework delivers
+ * {@code FrameworkEvent} objects to a {@code FrameworkListener}
+ * in order and must not concurrently call a {@code FrameworkListener}.
  * 
  * <p>
- * A <code>FrameworkListener</code> object is registered with the Framework
+ * A {@code FrameworkListener} object is registered with the Framework
  * using the {@link BundleContext#addFrameworkListener} method.
- * <code>FrameworkListener</code> objects are called with a
- * <code>FrameworkEvent</code> objects when the Framework starts and when
+ * {@code FrameworkListener} objects are called with a
+ * {@code FrameworkEvent} objects when the Framework starts and when
  * asynchronous errors occur.
  * 
  * @see FrameworkEvent
  * @NotThreadSafe
- * @version $Revision: 5673 $
+ * @version $Id: a32e7599ea09d3510759d77e824cb8d9eff67f9d $
  */
 
 public interface FrameworkListener extends EventListener {
 
 	/**
-	 * Receives notification of a general <code>FrameworkEvent</code> object.
+	 * Receives notification of a general {@code FrameworkEvent} object.
 	 * 
-	 * @param event The <code>FrameworkEvent</code> object.
+	 * @param event The {@code FrameworkEvent} object.
 	 */
 	public void frameworkEvent(FrameworkEvent event);
 }
diff --git a/framework/src/main/java/org/osgi/framework/FrameworkUtil.java b/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
index 4a53bd3..0e89999 100644
--- a/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
+++ b/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2005, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,12 +21,15 @@
 import java.lang.reflect.InvocationTargetException;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import javax.security.auth.x500.X500Principal;
 
@@ -39,7 +42,7 @@
  * 
  * @since 1.3
  * @ThreadSafe
- * @version $Revision: 7761 $
+ * @version $Id: a902bc156ea997ed244831c7fab0f290a08ac0c1 $
  */
 public class FrameworkUtil {
 	/**
@@ -50,9 +53,9 @@
 	}
 
 	/**
-	 * Creates a <code>Filter</code> object. This <code>Filter</code> object may
-	 * be used to match a <code>ServiceReference</code> object or a
-	 * <code>Dictionary</code> object.
+	 * Creates a {@code Filter} object. This {@code Filter} object may
+	 * be used to match a {@code ServiceReference} object or a
+	 * {@code Dictionary} object.
 	 * 
 	 * <p>
 	 * If the filter cannot be parsed, an {@link InvalidSyntaxException} will be
@@ -64,16 +67,16 @@
 	 * by {@link BundleContext#createFilter(String)}.
 	 * 
 	 * @param filter The filter string.
-	 * @return A <code>Filter</code> object encapsulating the filter string.
-	 * @throws InvalidSyntaxException If <code>filter</code> contains an invalid
+	 * @return A {@code Filter} object encapsulating the filter string.
+	 * @throws InvalidSyntaxException If {@code filter} contains an invalid
 	 *         filter string that cannot be parsed.
-	 * @throws NullPointerException If <code>filter</code> is null.
+	 * @throws NullPointerException If {@code filter} is null.
 	 * 
 	 * @see Filter
 	 */
 	public static Filter createFilter(String filter)
 			throws InvalidSyntaxException {
-		return new org.apache.felix.framework.FilterImpl(filter);
+		return FilterImpl.newInstance(filter);
 	}
 
 	/**
@@ -102,8 +105,8 @@
 	 * wildcard can also replace the first list of RDNs of a DN. The first RDNs
 	 * are the least significant. Such lists of matched RDNs can be empty.
 	 * <p>
-	 * For example, a match pattern with a wildcard that matches all all DNs
-	 * that end with RDNs of o=ACME and c=US would look like this:
+	 * For example, a match pattern with a wildcard that matches all DNs that
+	 * end with RDNs of o=ACME and c=US would look like this:
 	 * 
 	 * <pre>
 	 * *, o=ACME, c=US
@@ -176,34 +179,36 @@
 	 * 
 	 * @param matchPattern The pattern against which to match the DN chain.
 	 * @param dnChain The DN chain to match against the specified pattern. Each
-	 *        element of the chain must be of type <code>String</code> and use
-	 *        the format defined in RFC 2253.
-	 * @return <code>true</code> If the pattern matches the DN chain; otherwise
-	 *         <code>false</code> is returned.
+	 *        element of the chain must be of type {@code String} and use the
+	 *        format defined in <a
+	 *        href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
+	 * @return {@code true} If the pattern matches the DN chain; otherwise
+	 *         {@code false} is returned.
 	 * @throws IllegalArgumentException If the specified match pattern or DN
 	 *         chain is invalid.
 	 * @since 1.5
 	 */
 	public static boolean matchDistinguishedNameChain(String matchPattern,
-			List /* <String> */dnChain) {
+			List<String> dnChain) {
 		return DNChainMatching.match(matchPattern, dnChain);
 	}
 
 	/**
-	 * Return a <code>Bundle</code> for the specified bundle class. The returned
-	 * <code>Bundle</code> is the bundle associated with the bundle class loader
+	 * Return a {@code Bundle} for the specified bundle class. The returned
+	 * {@code Bundle} is the bundle associated with the bundle class loader
 	 * which defined the specified class.
 	 * 
 	 * @param classFromBundle A class defined by a bundle class loader.
-	 * @return A <code>Bundle</code> for the specified bundle class or
-	 *         <code>null</code> if the specified class was not defined by a
+	 * @return A {@code Bundle} for the specified bundle class or
+	 *         {@code null} if the specified class was not defined by a
 	 *         bundle class loader.
 	 * @since 1.5
 	 */
-	public static Bundle getBundle(final Class classFromBundle) {
+	public static Bundle getBundle(final Class< ? > classFromBundle) {
 		// We use doPriv since the caller may not have permission
 		// to call getClassLoader.
-		Object cl = AccessController.doPrivileged(new PrivilegedAction() {
+		Object cl = AccessController
+				.doPrivileged(new PrivilegedAction<Object>() {
 			public Object run() {
 				return classFromBundle.getClassLoader();
 			}
@@ -216,6 +221,1518 @@
 	}
 
 	/**
+	 * RFC 1960-based Filter. Filter objects can be created by calling the
+	 * constructor with the desired filter string. A Filter object can be called
+	 * numerous times to determine if the match argument matches the filter
+	 * string that was used to create the Filter object.
+	 * 
+	 * <p>
+	 * The syntax of a filter string is the string representation of LDAP search
+	 * filters as defined in RFC 1960: <i>A String Representation of LDAP Search
+	 * Filters</i> (available at http://www.ietf.org/rfc/rfc1960.txt). It should
+	 * be noted that RFC 2254: <i>A String Representation of LDAP Search
+	 * Filters</i> (available at http://www.ietf.org/rfc/rfc2254.txt) supersedes
+	 * RFC 1960 but only adds extensible matching and is not applicable for this
+	 * API.
+	 * 
+	 * <p>
+	 * The string representation of an LDAP search filter is defined by the
+	 * following grammar. It uses a prefix format.
+	 * 
+	 * <pre>
+	 *   &lt;filter&gt; ::= '(' &lt;filtercomp&gt; ')'
+	 *   &lt;filtercomp&gt; ::= &lt;and&gt; | &lt;or&gt; | &lt;not&gt; | &lt;item&gt;
+	 *   &lt;and&gt; ::= '&amp;' &lt;filterlist&gt;
+	 *   &lt;or&gt; ::= '|' &lt;filterlist&gt;
+	 *   &lt;not&gt; ::= '!' &lt;filter&gt;
+	 *   &lt;filterlist&gt; ::= &lt;filter&gt; | &lt;filter&gt; &lt;filterlist&gt;
+	 *   &lt;item&gt; ::= &lt;simple&gt; | &lt;present&gt; | &lt;substring&gt;
+	 *   &lt;simple&gt; ::= &lt;attr&gt; &lt;filtertype&gt; &lt;value&gt;
+	 *   &lt;filtertype&gt; ::= &lt;equal&gt; | &lt;approx&gt; | &lt;greater&gt; | &lt;less&gt;
+	 *   &lt;equal&gt; ::= '='
+	 *   &lt;approx&gt; ::= '&tilde;='
+	 *   &lt;greater&gt; ::= '&gt;='
+	 *   &lt;less&gt; ::= '&lt;='
+	 *   &lt;present&gt; ::= &lt;attr&gt; '=*'
+	 *   &lt;substring&gt; ::= &lt;attr&gt; '=' &lt;initial&gt; &lt;any&gt; &lt;final&gt;
+	 *   &lt;initial&gt; ::= NULL | &lt;value&gt;
+	 *   &lt;any&gt; ::= '*' &lt;starval&gt;
+	 *   &lt;starval&gt; ::= NULL | &lt;value&gt; '*' &lt;starval&gt;
+	 *   &lt;final&gt; ::= NULL | &lt;value&gt;
+	 * </pre>
+	 * 
+	 * {@code &lt;attr&gt;} is a string representing an attribute, or key,
+	 * in the properties objects of the registered services. Attribute names are
+	 * not case sensitive; that is cn and CN both refer to the same attribute.
+	 * {@code &lt;value&gt;} is a string representing the value, or part of
+	 * one, of a key in the properties objects of the registered services. If a
+	 * {@code &lt;value&gt;} must contain one of the characters '
+	 * {@code *}' or '{@code (}' or '{@code )}', these characters
+	 * should be escaped by preceding them with the backslash '{@code \}'
+	 * character. Note that although both the {@code &lt;substring&gt;} and
+	 * {@code &lt;present&gt;} productions can produce the {@code 'attr=*'}
+	 * construct, this construct is used only to denote a presence filter.
+	 * 
+	 * <p>
+	 * Examples of LDAP filters are:
+	 * 
+	 * <pre>
+	 *   &quot;(cn=Babs Jensen)&quot;
+	 *   &quot;(!(cn=Tim Howes))&quot;
+	 *   &quot;(&amp;(&quot; + Constants.OBJECTCLASS + &quot;=Person)(|(sn=Jensen)(cn=Babs J*)))&quot;
+	 *   &quot;(o=univ*of*mich*)&quot;
+	 * </pre>
+	 * 
+	 * <p>
+	 * The approximate match ({@code ~=}) is implementation specific but
+	 * should at least ignore case and white space differences. Optional are
+	 * codes like soundex or other smart "closeness" comparisons.
+	 * 
+	 * <p>
+	 * Comparison of values is not straightforward. Strings are compared
+	 * differently than numbers and it is possible for a key to have multiple
+	 * values. Note that that keys in the match argument must always be strings.
+	 * The comparison is defined by the object type of the key's value. The
+	 * following rules apply for comparison:
+	 * 
+	 * <blockquote>
+	 * <TABLE BORDER=0>
+	 * <TR>
+	 * <TD><b>Property Value Type </b></TD>
+	 * <TD><b>Comparison Type</b></TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>String</TD>
+	 * <TD>String comparison</TD>
+	 * </TR>
+	 * <TR valign=top>
+	 * <TD>Integer, Long, Float, Double, Byte, Short, BigInteger, BigDecimal</TD>
+	 * <TD>numerical comparison</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>Character</TD>
+	 * <TD>character comparison</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>Boolean</TD>
+	 * <TD>equality comparisons only</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>[] (array)</TD>
+	 * <TD>recursively applied to values</TD>
+	 * </TR>
+	 * <TR>
+	 * <TD>Collection</TD>
+	 * <TD>recursively applied to values</TD>
+	 * </TR>
+	 * </TABLE>
+	 * Note: arrays of primitives are also supported. </blockquote>
+	 * 
+	 * A filter matches a key that has multiple values if it matches at least
+	 * one of those values. For example,
+	 * 
+	 * <pre>
+	 * Dictionary d = new Hashtable();
+	 * d.put(&quot;cn&quot;, new String[] {&quot;a&quot;, &quot;b&quot;, &quot;c&quot;});
+	 * </pre>
+	 * 
+	 * d will match {@code (cn=a)} and also {@code (cn=b)}
+	 * 
+	 * <p>
+	 * A filter component that references a key having an unrecognizable data
+	 * type will evaluate to {@code false} .
+	 */
+	static private final class FilterImpl implements Filter {
+		/* filter operators */
+		private static final int	EQUAL		= 1;
+		private static final int	APPROX		= 2;
+		private static final int	GREATER		= 3;
+		private static final int	LESS		= 4;
+		private static final int	PRESENT		= 5;
+		private static final int	SUBSTRING	= 6;
+		private static final int	AND			= 7;
+		private static final int	OR			= 8;
+		private static final int	NOT			= 9;
+
+		/** filter operation */
+		private final int			op;
+		/** filter attribute or null if operation AND, OR or NOT */
+		private final String		attr;
+		/** filter operands */
+		private final Object		value;
+
+		/* normalized filter string for Filter object */
+		private transient String	filterString;
+
+		/**
+		 * Constructs a {@link FilterImpl} object. This filter object may be
+		 * used to match a {@link ServiceReference} or a Dictionary.
+		 * 
+		 * <p>
+		 * If the filter cannot be parsed, an {@link InvalidSyntaxException}
+		 * will be thrown with a human readable message where the filter became
+		 * unparsable.
+		 * 
+		 * @param filterString the filter string.
+		 * @throws InvalidSyntaxException If the filter parameter contains an
+		 *            invalid filter string that cannot be parsed.
+		 */
+		static FilterImpl newInstance(String filterString)
+				throws InvalidSyntaxException {
+			return new Parser(filterString).parse();
+		}
+
+		FilterImpl(int operation, String attr, Object value) {
+			this.op = operation;
+			this.attr = attr;
+			this.value = value;
+			filterString = null;
+		}
+
+		/**
+		 * Filter using a service's properties.
+		 * <p>
+		 * This {@code Filter} is executed using the keys and values of the
+		 * referenced service's properties. The keys are looked up in a case
+		 * insensitive manner.
+		 * 
+		 * @param reference The reference to the service whose properties are
+		 *        used in the match.
+		 * @return {@code true} if the service's properties match this
+		 *         {@code Filter}; {@code false} otherwise.
+		 */
+		public boolean match(ServiceReference< ? > reference) {
+			return matches(new ServiceReferenceMap(reference));
+		}
+
+		/**
+		 * Filter using a {@code Dictionary} with case insensitive key lookup.
+		 * This {@code Filter} is executed using the specified
+		 * {@code Dictionary}'s keys and values. The keys are looked up in a
+		 * case insensitive manner.
+		 * 
+		 * @param dictionary The {@code Dictionary} whose key/value pairs are
+		 *        used in the match.
+		 * @return {@code true} if the {@code Dictionary}'s values match this
+		 *         filter; {@code false} otherwise.
+		 * @throws IllegalArgumentException If {@code dictionary} contains case
+		 *         variants of the same key name.
+		 */
+		public boolean match(Dictionary<String, ? > dictionary) {
+			return matches(new CaseInsensitiveMap(dictionary));
+		}
+
+		/**
+		 * Filter using a {@code Dictionary}. This {@code Filter} is executed
+		 * using the specified {@code Dictionary}'s keys and values. The keys
+		 * are looked up in a normal manner respecting case.
+		 * 
+		 * @param dictionary The {@code Dictionary} whose key/value pairs are
+		 *        used in the match.
+		 * @return {@code true} if the {@code Dictionary}'s values match this
+		 *         filter; {@code false} otherwise.
+		 * @since 1.3
+		 */
+		public boolean matchCase(Dictionary<String, ? > dictionary) {
+			switch (op) {
+				case AND : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (!f.matchCase(dictionary)) {
+							return false;
+						}
+					}
+					return true;
+				}
+
+				case OR : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (f.matchCase(dictionary)) {
+							return true;
+						}
+					}
+					return false;
+				}
+
+				case NOT : {
+					FilterImpl filter = (FilterImpl) value;
+					return !filter.matchCase(dictionary);
+				}
+
+				case SUBSTRING :
+				case EQUAL :
+				case GREATER :
+				case LESS :
+				case APPROX : {
+					Object prop = (dictionary == null) ? null : dictionary
+							.get(attr);
+					return compare(op, prop, value);
+				}
+
+				case PRESENT : {
+					Object prop = (dictionary == null) ? null : dictionary
+							.get(attr);
+					return prop != null;
+				}
+			}
+
+			return false;
+		}
+
+		/**
+		 * Filter using a {@code Map}. This {@code Filter} is executed using the
+		 * specified {@code Map}'s keys and values. The keys are looked up in a
+		 * normal manner respecting case.
+		 * 
+		 * @param map The {@code Map} whose key/value pairs are used in the
+		 *        match. Maps with {@code null} key or values are not supported.
+		 *        A {@code null} value is considered not present to the filter.
+		 * @return {@code true} if the {@code Map}'s values match this filter;
+		 *         {@code false} otherwise.
+		 * @since 1.6
+		 */
+		public boolean matches(Map<String, ? > map) {
+			switch (op) {
+				case AND : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (!f.matches(map)) {
+							return false;
+						}
+					}
+					return true;
+				}
+		
+				case OR : {
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						if (f.matches(map)) {
+							return true;
+						}
+					}
+					return false;
+				}
+		
+				case NOT : {
+					FilterImpl filter = (FilterImpl) value;
+					return !filter.matches(map);
+				}
+		
+				case SUBSTRING :
+				case EQUAL :
+				case GREATER :
+				case LESS :
+				case APPROX : {
+					Object prop = (map == null) ? null : map.get(attr);
+					return compare(op, prop, value);
+				}
+		
+				case PRESENT : {
+					Object prop = (map == null) ? null : map.get(attr);
+					return prop != null;
+				}
+			}
+		
+			return false;
+		}
+
+		/**
+		 * Returns this {@code Filter}'s filter string.
+		 * <p>
+		 * The filter string is normalized by removing whitespace which does not
+		 * affect the meaning of the filter.
+		 * 
+		 * @return This {@code Filter}'s filter string.
+		 */
+		public String toString() {
+			String result = filterString;
+			if (result == null) {
+				filterString = result = normalize().toString();
+			}
+			return result;
+		}
+
+		/**
+		 * Returns this {@code Filter}'s normalized filter string.
+		 * <p>
+		 * The filter string is normalized by removing whitespace which does not
+		 * affect the meaning of the filter.
+		 * 
+		 * @return This {@code Filter}'s filter string.
+		 */
+		private StringBuffer normalize() {
+			StringBuffer sb = new StringBuffer();
+			sb.append('(');
+
+			switch (op) {
+				case AND : {
+					sb.append('&');
+
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						sb.append(f.normalize());
+					}
+
+					break;
+				}
+
+				case OR : {
+					sb.append('|');
+
+					FilterImpl[] filters = (FilterImpl[]) value;
+					for (FilterImpl f : filters) {
+						sb.append(f.normalize());
+					}
+
+					break;
+				}
+
+				case NOT : {
+					sb.append('!');
+					FilterImpl filter = (FilterImpl) value;
+					sb.append(filter.normalize());
+
+					break;
+				}
+
+				case SUBSTRING : {
+					sb.append(attr);
+					sb.append('=');
+
+					String[] substrings = (String[]) value;
+
+					for (String substr : substrings) {
+						if (substr == null) /* * */{
+							sb.append('*');
+						}
+						else /* xxx */{
+							sb.append(encodeValue(substr));
+						}
+					}
+
+					break;
+				}
+				case EQUAL : {
+					sb.append(attr);
+					sb.append('=');
+					sb.append(encodeValue((String) value));
+
+					break;
+				}
+				case GREATER : {
+					sb.append(attr);
+					sb.append(">=");
+					sb.append(encodeValue((String) value));
+
+					break;
+				}
+				case LESS : {
+					sb.append(attr);
+					sb.append("<=");
+					sb.append(encodeValue((String) value));
+
+					break;
+				}
+				case APPROX : {
+					sb.append(attr);
+					sb.append("~=");
+					sb.append(encodeValue(approxString((String) value)));
+
+					break;
+				}
+
+				case PRESENT : {
+					sb.append(attr);
+					sb.append("=*");
+
+					break;
+				}
+			}
+
+			sb.append(')');
+
+			return sb;
+		}
+
+		/**
+		 * Compares this {@code Filter} to another {@code Filter}.
+		 * 
+		 * <p>
+		 * This implementation returns the result of calling
+		 * {@code this.toString().equals(obj.toString()}.
+		 * 
+		 * @param obj The object to compare against this {@code Filter}.
+		 * @return If the other object is a {@code Filter} object, then
+		 *         returns the result of calling
+		 *         {@code this.toString().equals(obj.toString()};
+		 *         {@code false} otherwise.
+		 */
+		public boolean equals(Object obj) {
+			if (obj == this) {
+				return true;
+			}
+
+			if (!(obj instanceof Filter)) {
+				return false;
+			}
+
+			return this.toString().equals(obj.toString());
+		}
+
+		/**
+		 * Returns the hashCode for this {@code Filter}.
+		 * 
+		 * <p>
+		 * This implementation returns the result of calling
+		 * {@code this.toString().hashCode()}.
+		 * 
+		 * @return The hashCode of this {@code Filter}.
+		 */
+		public int hashCode() {
+			return this.toString().hashCode();
+		}
+
+		/**
+		 * Encode the value string such that '(', '*', ')' and '\' are escaped.
+		 * 
+		 * @param value unencoded value string.
+		 * @return encoded value string.
+		 */
+		private static String encodeValue(String value) {
+			boolean encoded = false;
+			int inlen = value.length();
+			int outlen = inlen << 1; /* inlen 2 */
+
+			char[] output = new char[outlen];
+			value.getChars(0, inlen, output, inlen);
+
+			int cursor = 0;
+			for (int i = inlen; i < outlen; i++) {
+				char c = output[i];
+
+				switch (c) {
+					case '(' :
+					case '*' :
+					case ')' :
+					case '\\' : {
+						output[cursor] = '\\';
+						cursor++;
+						encoded = true;
+
+						break;
+					}
+				}
+
+				output[cursor] = c;
+				cursor++;
+			}
+
+			return encoded ? new String(output, 0, cursor) : value;
+		}
+
+		private boolean compare(int operation, Object value1, Object value2) {
+			if (value1 == null) {
+				return false;
+			}
+			if (value1 instanceof String) {
+				return compare_String(operation, (String) value1, value2);
+			}
+
+			Class< ? > clazz = value1.getClass();
+			if (clazz.isArray()) {
+				Class< ? > type = clazz.getComponentType();
+				if (type.isPrimitive()) {
+					return compare_PrimitiveArray(operation, type, value1,
+							value2);
+				}
+				return compare_ObjectArray(operation, (Object[]) value1, value2);
+			}
+			if (value1 instanceof Collection< ? >) {
+				return compare_Collection(operation, (Collection< ? >) value1,
+						value2);
+			}
+			if (value1 instanceof Integer) {
+				return compare_Integer(operation,
+						((Integer) value1).intValue(), value2);
+			}
+			if (value1 instanceof Long) {
+				return compare_Long(operation, ((Long) value1).longValue(),
+						value2);
+			}
+			if (value1 instanceof Byte) {
+				return compare_Byte(operation, ((Byte) value1).byteValue(),
+						value2);
+			}
+			if (value1 instanceof Short) {
+				return compare_Short(operation, ((Short) value1).shortValue(),
+						value2);
+			}
+			if (value1 instanceof Character) {
+				return compare_Character(operation, ((Character) value1)
+						.charValue(), value2);
+			}
+			if (value1 instanceof Float) {
+				return compare_Float(operation, ((Float) value1).floatValue(),
+						value2);
+			}
+			if (value1 instanceof Double) {
+				return compare_Double(operation, ((Double) value1)
+						.doubleValue(), value2);
+			}
+			if (value1 instanceof Boolean) {
+				return compare_Boolean(operation, ((Boolean) value1)
+						.booleanValue(), value2);
+			}
+			if (value1 instanceof Comparable< ? >) {
+				Comparable<Object> comparable = (Comparable<Object>) value1;
+				return compare_Comparable(operation, comparable, value2);
+			}
+			return compare_Unknown(operation, value1, value2);
+		}
+
+		private boolean compare_Collection(int operation,
+				Collection< ? > collection, Object value2) {
+			for (Object value1 : collection) {
+				if (compare(operation, value1, value2)) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_ObjectArray(int operation, Object[] array,
+				Object value2) {
+			for (Object value1 : array) {
+				if (compare(operation, value1, value2)) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_PrimitiveArray(int operation, Class< ? > type,
+				Object primarray, Object value2) {
+			if (Integer.TYPE.isAssignableFrom(type)) {
+				int[] array = (int[]) primarray;
+				for (int value1 : array) {
+					if (compare_Integer(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Long.TYPE.isAssignableFrom(type)) {
+				long[] array = (long[]) primarray;
+				for (long value1 : array) {
+					if (compare_Long(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Byte.TYPE.isAssignableFrom(type)) {
+				byte[] array = (byte[]) primarray;
+				for (byte value1 : array) {
+					if (compare_Byte(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Short.TYPE.isAssignableFrom(type)) {
+				short[] array = (short[]) primarray;
+				for (short value1 : array) {
+					if (compare_Short(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Character.TYPE.isAssignableFrom(type)) {
+				char[] array = (char[]) primarray;
+				for (char value1 : array) {
+					if (compare_Character(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Float.TYPE.isAssignableFrom(type)) {
+				float[] array = (float[]) primarray;
+				for (float value1 : array) {
+					if (compare_Float(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Double.TYPE.isAssignableFrom(type)) {
+				double[] array = (double[]) primarray;
+				for (double value1 : array) {
+					if (compare_Double(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			if (Boolean.TYPE.isAssignableFrom(type)) {
+				boolean[] array = (boolean[]) primarray;
+				for (boolean value1 : array) {
+					if (compare_Boolean(operation, value1, value2)) {
+						return true;
+					}
+				}
+				return false;
+			}
+			return false;
+		}
+
+		private boolean compare_String(int operation, String string,
+				Object value2) {
+			switch (operation) {
+				case SUBSTRING : {
+					String[] substrings = (String[]) value2;
+					int pos = 0;
+					for (int i = 0, size = substrings.length; i < size; i++) {
+						String substr = substrings[i];
+
+						if (i + 1 < size) /* if this is not that last substr */{
+							if (substr == null) /* * */{
+								String substr2 = substrings[i + 1];
+
+								if (substr2 == null) /* ** */
+									continue; /* ignore first star */
+								/* xxx */
+								int index = string.indexOf(substr2, pos);
+								if (index == -1) {
+									return false;
+								}
+
+								pos = index + substr2.length();
+								if (i + 2 < size) // if there are more
+									// substrings, increment
+									// over the string we just
+									// matched; otherwise need
+									// to do the last substr
+									// check
+									i++;
+							}
+							else /* xxx */{
+								int len = substr.length();
+								if (string.regionMatches(pos, substr, 0, len)) {
+									pos += len;
+								}
+								else {
+									return false;
+								}
+							}
+						}
+						else /* last substr */{
+							if (substr == null) /* * */{
+								return true;
+							}
+							/* xxx */
+							return string.endsWith(substr);
+						}
+					}
+
+					return true;
+				}
+				case EQUAL : {
+					return string.equals(value2);
+				}
+				case APPROX : {
+					string = approxString(string);
+					String string2 = approxString((String) value2);
+
+					return string.equalsIgnoreCase(string2);
+				}
+				case GREATER : {
+					return string.compareTo((String) value2) >= 0;
+				}
+				case LESS : {
+					return string.compareTo((String) value2) <= 0;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Integer(int operation, int intval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			int intval2;
+			try {
+				intval2 = Integer.parseInt(((String) value2).trim());
+			}
+			catch (IllegalArgumentException e) {
+				return false;
+			}
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return intval == intval2;
+				}
+				case GREATER : {
+					return intval >= intval2;
+				}
+				case LESS : {
+					return intval <= intval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Long(int operation, long longval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			long longval2;
+			try {
+				longval2 = Long.parseLong(((String) value2).trim());
+			}
+			catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return longval == longval2;
+				}
+				case GREATER : {
+					return longval >= longval2;
+				}
+				case LESS : {
+					return longval <= longval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Byte(int operation, byte byteval, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			byte byteval2;
+			try {
+				byteval2 = Byte.parseByte(((String) value2).trim());
+			}
+			catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return byteval == byteval2;
+				}
+				case GREATER : {
+					return byteval >= byteval2;
+				}
+				case LESS : {
+					return byteval <= byteval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Short(int operation, short shortval,
+				Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			short shortval2;
+			try {
+				shortval2 = Short.parseShort(((String) value2).trim());
+			}
+			catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return shortval == shortval2;
+				}
+				case GREATER : {
+					return shortval >= shortval2;
+				}
+				case LESS : {
+					return shortval <= shortval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Character(int operation, char charval,
+				Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			char charval2;
+			try {
+				charval2 = ((String) value2).charAt(0);
+			}
+			catch (IndexOutOfBoundsException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case EQUAL : {
+					return charval == charval2;
+				}
+				case APPROX : {
+					return (charval == charval2)
+							|| (Character.toUpperCase(charval) == Character
+									.toUpperCase(charval2))
+							|| (Character.toLowerCase(charval) == Character
+									.toLowerCase(charval2));
+				}
+				case GREATER : {
+					return charval >= charval2;
+				}
+				case LESS : {
+					return charval <= charval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Boolean(int operation, boolean boolval,
+				Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			boolean boolval2 = Boolean.valueOf(((String) value2).trim())
+					.booleanValue();
+			switch (operation) {
+				case APPROX :
+				case EQUAL :
+				case GREATER :
+				case LESS : {
+					return boolval == boolval2;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Float(int operation, float floatval,
+				Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			float floatval2;
+			try {
+				floatval2 = Float.parseFloat(((String) value2).trim());
+			}
+			catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return Float.compare(floatval, floatval2) == 0;
+				}
+				case GREATER : {
+					return Float.compare(floatval, floatval2) >= 0;
+				}
+				case LESS : {
+					return Float.compare(floatval, floatval2) <= 0;
+				}
+			}
+			return false;
+		}
+
+		private boolean compare_Double(int operation, double doubleval,
+				Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			double doubleval2;
+			try {
+				doubleval2 = Double.parseDouble(((String) value2).trim());
+			}
+			catch (IllegalArgumentException e) {
+				return false;
+			}
+
+			switch (operation) {
+				case APPROX :
+				case EQUAL : {
+					return Double.compare(doubleval, doubleval2) == 0;
+				}
+				case GREATER : {
+					return Double.compare(doubleval, doubleval2) >= 0;
+				}
+				case LESS : {
+					return Double.compare(doubleval, doubleval2) <= 0;
+				}
+			}
+			return false;
+		}
+
+		private static final Class< ? >[]	constructorType	= new Class[] {String.class};
+
+		private boolean compare_Comparable(int operation,
+				Comparable<Object> value1, Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			Constructor< ? > constructor;
+			try {
+				constructor = value1.getClass().getConstructor(constructorType);
+			}
+			catch (NoSuchMethodException e) {
+				return false;
+			}
+			try {
+				if (!constructor.isAccessible())
+					AccessController.doPrivileged(new SetAccessibleAction(
+							constructor));
+				value2 = constructor
+						.newInstance(new Object[] {((String) value2).trim()});
+			}
+			catch (IllegalAccessException e) {
+				return false;
+			}
+			catch (InvocationTargetException e) {
+				return false;
+			}
+			catch (InstantiationException e) {
+				return false;
+			}
+
+			try {
+				switch (operation) {
+					case APPROX :
+					case EQUAL : {
+						return value1.compareTo(value2) == 0;
+					}
+					case GREATER : {
+						return value1.compareTo(value2) >= 0;
+					}
+					case LESS : {
+						return value1.compareTo(value2) <= 0;
+					}
+				}
+			}
+			catch (Exception e) {
+				// if the compareTo method throws an exception; return false
+				return false;
+			}
+			return false;
+		}
+
+		private boolean compare_Unknown(int operation, Object value1,
+				Object value2) {
+			if (operation == SUBSTRING) {
+				return false;
+			}
+			Constructor< ? > constructor;
+			try {
+				constructor = value1.getClass().getConstructor(constructorType);
+			}
+			catch (NoSuchMethodException e) {
+				return false;
+			}
+			try {
+				if (!constructor.isAccessible())
+					AccessController.doPrivileged(new SetAccessibleAction(
+							constructor));
+				value2 = constructor
+						.newInstance(new Object[] {((String) value2).trim()});
+			}
+			catch (IllegalAccessException e) {
+				return false;
+			}
+			catch (InvocationTargetException e) {
+				return false;
+			}
+			catch (InstantiationException e) {
+				return false;
+			}
+
+			try {
+				switch (operation) {
+					case APPROX :
+					case EQUAL :
+					case GREATER :
+					case LESS : {
+						return value1.equals(value2);
+					}
+				}
+			}
+			catch (Exception e) {
+				// if the equals method throws an exception; return false
+				return false;
+			}
+			return false;
+		}
+
+		/**
+		 * Map a string for an APPROX (~=) comparison.
+		 * 
+		 * This implementation removes white spaces. This is the minimum
+		 * implementation allowed by the OSGi spec.
+		 * 
+		 * @param input Input string.
+		 * @return String ready for APPROX comparison.
+		 */
+		private static String approxString(String input) {
+			boolean changed = false;
+			char[] output = input.toCharArray();
+			int cursor = 0;
+			for (char c : output) {
+				if (Character.isWhitespace(c)) {
+					changed = true;
+					continue;
+				}
+
+				output[cursor] = c;
+				cursor++;
+			}
+
+			return changed ? new String(output, 0, cursor) : input;
+		}
+
+		/**
+		 * Parser class for OSGi filter strings. This class parses the complete
+		 * filter string and builds a tree of Filter objects rooted at the
+		 * parent.
+		 */
+		static private final class Parser {
+			private final String	filterstring;
+			private final char[]	filterChars;
+			private int				pos;
+
+			Parser(String filterstring) {
+				this.filterstring = filterstring;
+				filterChars = filterstring.toCharArray();
+				pos = 0;
+			}
+
+			FilterImpl parse() throws InvalidSyntaxException {
+				FilterImpl filter;
+				try {
+					filter = parse_filter();
+				}
+				catch (ArrayIndexOutOfBoundsException e) {
+					throw new InvalidSyntaxException("Filter ended abruptly",
+							filterstring, e);
+				}
+
+				if (pos != filterChars.length) {
+					throw new InvalidSyntaxException(
+							"Extraneous trailing characters: "
+									+ filterstring.substring(pos), filterstring);
+				}
+				return filter;
+			}
+
+			private FilterImpl parse_filter() throws InvalidSyntaxException {
+				FilterImpl filter;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					throw new InvalidSyntaxException("Missing '(': "
+							+ filterstring.substring(pos), filterstring);
+				}
+
+				pos++;
+
+				filter = parse_filtercomp();
+
+				skipWhiteSpace();
+
+				if (filterChars[pos] != ')') {
+					throw new InvalidSyntaxException("Missing ')': "
+							+ filterstring.substring(pos), filterstring);
+				}
+
+				pos++;
+
+				skipWhiteSpace();
+
+				return filter;
+			}
+
+			private FilterImpl parse_filtercomp() throws InvalidSyntaxException {
+				skipWhiteSpace();
+
+				char c = filterChars[pos];
+
+				switch (c) {
+					case '&' : {
+						pos++;
+						return parse_and();
+					}
+					case '|' : {
+						pos++;
+						return parse_or();
+					}
+					case '!' : {
+						pos++;
+						return parse_not();
+					}
+				}
+				return parse_item();
+			}
+
+			private FilterImpl parse_and() throws InvalidSyntaxException {
+				int lookahead = pos;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					pos = lookahead - 1;
+					return parse_item();
+				}
+
+				List<FilterImpl> operands = new ArrayList<FilterImpl>(10);
+
+				while (filterChars[pos] == '(') {
+					FilterImpl child = parse_filter();
+					operands.add(child);
+				}
+
+				return new FilterImpl(FilterImpl.AND, null, operands
+						.toArray(new FilterImpl[operands.size()]));
+			}
+
+			private FilterImpl parse_or() throws InvalidSyntaxException {
+				int lookahead = pos;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					pos = lookahead - 1;
+					return parse_item();
+				}
+
+				List<FilterImpl> operands = new ArrayList<FilterImpl>(10);
+
+				while (filterChars[pos] == '(') {
+					FilterImpl child = parse_filter();
+					operands.add(child);
+				}
+
+				return new FilterImpl(FilterImpl.OR, null, operands
+						.toArray(new FilterImpl[operands.size()]));
+			}
+
+			private FilterImpl parse_not() throws InvalidSyntaxException {
+				int lookahead = pos;
+				skipWhiteSpace();
+
+				if (filterChars[pos] != '(') {
+					pos = lookahead - 1;
+					return parse_item();
+				}
+
+				FilterImpl child = parse_filter();
+
+				return new FilterImpl(FilterImpl.NOT, null, child);
+			}
+
+			private FilterImpl parse_item() throws InvalidSyntaxException {
+				String attr = parse_attr();
+
+				skipWhiteSpace();
+
+				switch (filterChars[pos]) {
+					case '~' : {
+						if (filterChars[pos + 1] == '=') {
+							pos += 2;
+							return new FilterImpl(FilterImpl.APPROX, attr,
+									parse_value());
+						}
+						break;
+					}
+					case '>' : {
+						if (filterChars[pos + 1] == '=') {
+							pos += 2;
+							return new FilterImpl(FilterImpl.GREATER, attr,
+									parse_value());
+						}
+						break;
+					}
+					case '<' : {
+						if (filterChars[pos + 1] == '=') {
+							pos += 2;
+							return new FilterImpl(FilterImpl.LESS, attr,
+									parse_value());
+						}
+						break;
+					}
+					case '=' : {
+						if (filterChars[pos + 1] == '*') {
+							int oldpos = pos;
+							pos += 2;
+							skipWhiteSpace();
+							if (filterChars[pos] == ')') {
+								return new FilterImpl(FilterImpl.PRESENT, attr,
+										null);
+							}
+							pos = oldpos;
+						}
+
+						pos++;
+						Object string = parse_substring();
+
+						if (string instanceof String) {
+							return new FilterImpl(FilterImpl.EQUAL, attr,
+									string);
+						}
+						return new FilterImpl(FilterImpl.SUBSTRING, attr,
+								string);
+					}
+				}
+
+				throw new InvalidSyntaxException("Invalid operator: "
+						+ filterstring.substring(pos), filterstring);
+			}
+
+			private String parse_attr() throws InvalidSyntaxException {
+				skipWhiteSpace();
+
+				int begin = pos;
+				int end = pos;
+
+				char c = filterChars[pos];
+
+				while (c != '~' && c != '<' && c != '>' && c != '=' && c != '('
+						&& c != ')') {
+					pos++;
+
+					if (!Character.isWhitespace(c)) {
+						end = pos;
+					}
+
+					c = filterChars[pos];
+				}
+
+				int length = end - begin;
+
+				if (length == 0) {
+					throw new InvalidSyntaxException("Missing attr: "
+							+ filterstring.substring(pos), filterstring);
+				}
+
+				return new String(filterChars, begin, length);
+			}
+
+			private String parse_value() throws InvalidSyntaxException {
+				StringBuffer sb = new StringBuffer(filterChars.length - pos);
+
+				parseloop: while (true) {
+					char c = filterChars[pos];
+
+					switch (c) {
+						case ')' : {
+							break parseloop;
+						}
+
+						case '(' : {
+							throw new InvalidSyntaxException("Invalid value: "
+									+ filterstring.substring(pos), filterstring);
+						}
+
+						case '\\' : {
+							pos++;
+							c = filterChars[pos];
+							/* fall through into default */
+						}
+
+						default : {
+							sb.append(c);
+							pos++;
+							break;
+						}
+					}
+				}
+
+				if (sb.length() == 0) {
+					throw new InvalidSyntaxException("Missing value: "
+							+ filterstring.substring(pos), filterstring);
+				}
+
+				return sb.toString();
+			}
+
+			private Object parse_substring() throws InvalidSyntaxException {
+				StringBuffer sb = new StringBuffer(filterChars.length - pos);
+
+				List<String> operands = new ArrayList<String>(10);
+
+				parseloop: while (true) {
+					char c = filterChars[pos];
+
+					switch (c) {
+						case ')' : {
+							if (sb.length() > 0) {
+								operands.add(sb.toString());
+							}
+
+							break parseloop;
+						}
+
+						case '(' : {
+							throw new InvalidSyntaxException("Invalid value: "
+									+ filterstring.substring(pos), filterstring);
+						}
+
+						case '*' : {
+							if (sb.length() > 0) {
+								operands.add(sb.toString());
+							}
+
+							sb.setLength(0);
+
+							operands.add(null);
+							pos++;
+
+							break;
+						}
+
+						case '\\' : {
+							pos++;
+							c = filterChars[pos];
+							/* fall through into default */
+						}
+
+						default : {
+							sb.append(c);
+							pos++;
+							break;
+						}
+					}
+				}
+
+				int size = operands.size();
+
+				if (size == 0) {
+					return "";
+				}
+
+				if (size == 1) {
+					Object single = operands.get(0);
+
+					if (single != null) {
+						return single;
+					}
+				}
+
+				return operands.toArray(new String[size]);
+			}
+
+			private void skipWhiteSpace() {
+				for (int length = filterChars.length; (pos < length)
+						&& Character.isWhitespace(filterChars[pos]);) {
+					pos++;
+				}
+			}
+		}
+	}
+
+	/**
+	 * This Map is used for case-insensitive key lookup during filter
+	 * evaluation. This Map implementation only supports the get operation using
+	 * a String key as no other operations are used by the Filter
+	 * implementation.
+	 */
+	static private final class CaseInsensitiveMap extends
+			AbstractMap<String, Object>
+			implements Map<String, Object> {
+		private final Dictionary<String, ? >	dictionary;
+		private final String[]		keys;
+
+		/**
+		 * Create a case insensitive map from the specified dictionary.
+		 * 
+		 * @param dictionary
+		 * @throws IllegalArgumentException If {@code dictionary} contains case
+		 *         variants of the same key name.
+		 */
+		CaseInsensitiveMap(Dictionary<String, ? > dictionary) {
+			if (dictionary == null) {
+				this.dictionary = null;
+				this.keys = new String[0];
+				return;
+			}
+			this.dictionary = dictionary;
+			List<String> keyList = new ArrayList<String>(dictionary.size());
+			for (Enumeration<?> e = dictionary.keys(); e.hasMoreElements();) {
+				Object k = e.nextElement();
+				if (k instanceof String) {
+					String key = (String) k;
+					for (String i : keyList) {
+						if (key.equalsIgnoreCase(i)) {
+							throw new IllegalArgumentException();
+						}
+					}
+					keyList.add(key);
+				}
+			}
+			this.keys = keyList.toArray(new String[keyList.size()]);
+		}
+
+		public Object get(Object o) {
+			String k = (String) o;
+			for (String key : keys) {
+				if (key.equalsIgnoreCase(k)) {
+					return dictionary.get(key);
+				}
+			}
+			return null;
+		}
+
+		public Set<java.util.Map.Entry<String, Object>> entrySet() {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	/**
+	 * This Map is used for key lookup from a ServiceReference during filter
+	 * evaluation. This Map implementation only supports the get operation using
+	 * a String key as no other operations are used by the Filter
+	 * implementation.
+	 */
+	static private final class ServiceReferenceMap extends
+			AbstractMap<String, Object> implements Map<String, Object> {
+		private final ServiceReference< ? >	reference;
+
+		ServiceReferenceMap(ServiceReference< ? > reference) {
+			this.reference = reference;
+		}
+
+		public Object get(Object key) {
+			if (reference == null) {
+				return null;
+			}
+			return reference.getProperty((String) key);
+		}
+
+		public Set<java.util.Map.Entry<String, Object>> entrySet() {
+			throw new UnsupportedOperationException();
+		}
+	}
+
+	static private final class SetAccessibleAction implements
+			PrivilegedAction<Object> {
+		private final AccessibleObject	accessible;
+
+		SetAccessibleAction(AccessibleObject accessible) {
+			this.accessible = accessible;
+		}
+
+		public Object run() {
+			accessible.setAccessible(true);
+			return null;
+		}
+	}
+
+	/**
 	 * This class contains a method to match a distinguished name (DN) chain
 	 * against and DN chain pattern.
 	 * <p>
@@ -229,12 +1746,12 @@
 	 *   cn=ben+ou=research,o=ACME,c=us;ou=Super CA,c=CA
 	 * </pre>
 	 * 
-	 * is made up of two DNs: "<code>cn=ben+ou=research,o=ACME,c=us</code>
-	 * " and " <code>ou=Super CA,c=CA</code>
+	 * is made up of two DNs: "{@code cn=ben+ou=research,o=ACME,c=us}
+	 * " and " {@code ou=Super CA,c=CA}
 	 * ". The first DN is made of of three RDNs: "
-	 * <code>cn=ben+ou=research</code>" and "<code>o=ACME</code>" and "
-	 * <code>c=us</code>". The first RDN has two name value pairs: "
-	 * <code>cn=ben</code>" and "<code>ou=research</code>".
+	 * {@code cn=ben+ou=research}" and "{@code o=ACME}" and "
+	 * {@code c=us}". The first RDN has two name value pairs: "
+	 * {@code cn=ben}" and "{@code ou=research}".
 	 * <p>
 	 * A chain pattern makes use of wildcards ('*' or '-') to match against DNs,
 	 * and wildcards ('*') to match againts DN prefixes, and value. If a DN in a
@@ -246,7 +1763,7 @@
 	 * removed). If a value of a name/value pair is a wildcard ("*"), the value
 	 * will match any value for that name.
 	 */
-	private static class DNChainMatching {
+	static private final class DNChainMatching {
 		private static final String	MINUS_WILDCARD	= "-";
 		private static final String	STAR_WILDCARD	= "*";
 
@@ -257,7 +1774,7 @@
 		 * @param rdnPattern List of name value pattern pairs.
 		 * @return true if the list of name value pairs match the pattern.
 		 */
-		private static boolean rdnmatch(List rdn, List rdnPattern) {
+		private static boolean rdnmatch(List< ? > rdn, List< ? > rdnPattern) {
 			if (rdn.size() != rdnPattern.size()) {
 				return false;
 			}
@@ -281,7 +1798,7 @@
 			return true;
 		}
 
-		private static boolean dnmatch(List dn, List dnPattern) {
+		private static boolean dnmatch(List< ? > dn, List< ? > dnPattern) {
 			int dnStart = 0;
 			int patStart = 0;
 			int patLen = dnPattern.size();
@@ -308,7 +1825,8 @@
 				}
 			}
 			for (int i = 0; i < patLen; i++) {
-				if (!rdnmatch((List) dn.get(i + dnStart), (List) dnPattern
+				if (!rdnmatch((List< ? >) dn.get(i + dnStart),
+						(List< ? >) dnPattern
 						.get(i + patStart))) {
 					return false;
 				}
@@ -329,12 +1847,12 @@
 		 * @return a list of DNs.
 		 * @throws IllegalArgumentException
 		 */
-		private static List parseDNchainPattern(String dnChain) {
+		private static List<Object> parseDNchainPattern(String dnChain) {
 			if (dnChain == null) {
 				throw new IllegalArgumentException(
 						"The DN chain must not be null.");
 			}
-			List parsed = new ArrayList();
+			List<Object> parsed = new ArrayList<Object>();
 			int startIndex = 0;
 			startIndex = skipSpaces(dnChain, startIndex);
 			while (startIndex < dnChain.length()) {
@@ -362,22 +1880,15 @@
 				startIndex = endIndex + 1;
 				startIndex = skipSpaces(dnChain, startIndex);
 			}
-			return parseDNchain(parsed);
-		}
 
-		private static List parseDNchain(List chain) {
-			if (chain == null) {
-				throw new IllegalArgumentException("DN chain must not be null.");
-			}
-			chain = new ArrayList(chain);
 			// Now we parse is a list of strings, lets make List of rdn out
 			// of them
-			for (int i = 0; i < chain.size(); i++) {
-				String dn = (String) chain.get(i);
+			for (int i = 0; i < parsed.size(); i++) {
+				String dn = (String) parsed.get(i);
 				if (dn.equals(STAR_WILDCARD) || dn.equals(MINUS_WILDCARD)) {
 					continue;
 				}
-				List rdns = new ArrayList();
+				List<Object> rdns = new ArrayList<Object>();
 				if (dn.charAt(0) == '*') {
 					if (dn.charAt(1) != ',') {
 						throw new IllegalArgumentException(
@@ -392,12 +1903,32 @@
 				}
 				// Now dn is a nice CANONICAL DN
 				parseDN(dn, rdns);
-				chain.set(i, rdns);
+				parsed.set(i, rdns);
 			}
-			if (chain.size() == 0) {
+			if (parsed.size() == 0) {
 				throw new IllegalArgumentException("empty DN chain");
 			}
-			return chain;
+			return parsed;
+		}
+
+		private static List<Object> parseDNchain(List<String> chain) {
+			if (chain == null) {
+				throw new IllegalArgumentException("DN chain must not be null.");
+			}
+			List<Object> result = new ArrayList<Object>(chain.size());
+			// Now we parse is a list of strings, lets make List of rdn out
+			// of them
+			for (String dn : chain) {
+				dn = new X500Principal(dn).getName(X500Principal.CANONICAL);
+				// Now dn is a nice CANONICAL DN
+				List<Object> rdns = new ArrayList<Object>();
+				parseDN(dn, rdns);
+				result.add(rdns);
+			}
+			if (result.size() == 0) {
+				throw new IllegalArgumentException("empty DN chain");
+			}
+			return result;
 		}
 
 		/**
@@ -420,10 +1951,10 @@
 		 * @param rdn the list to fill in with RDNs extracted from the dn
 		 * @throws IllegalArgumentException if a formatting error is found.
 		 */
-		private static void parseDN(String dn, List rdn) {
+		private static void parseDN(String dn, List<Object> rdn) {
 			int startIndex = 0;
 			char c = '\0';
-			List nameValues = new ArrayList();
+			List<String> nameValues = new ArrayList<String>();
 			while (startIndex < dn.length()) {
 				int endIndex;
 				for (endIndex = startIndex; endIndex < dn.length(); endIndex++) {
@@ -443,7 +1974,7 @@
 				if (c != '+') {
 					rdn.add(nameValues);
 					if (endIndex != dn.length()) {
-						nameValues = new ArrayList();
+						nameValues = new ArrayList<String>();
 					}
 					else {
 						nameValues = null;
@@ -461,7 +1992,7 @@
 		 * This method will return an 'index' which points to a non-wildcard DN
 		 * or the end-of-list.
 		 */
-		private static int skipWildCards(List dnChainPattern,
+		private static int skipWildCards(List<Object> dnChainPattern,
 				int dnChainPatternIndex) {
 			int i;
 			for (i = dnChainPatternIndex; i < dnChainPattern.size(); i++) {
@@ -475,7 +2006,7 @@
 					// otherwise continue skipping over wild cards
 				}
 				else {
-					if (dnPattern instanceof List) {
+					if (dnPattern instanceof List< ? >) {
 						// if its a list then we have our 'non-wildcard' DN
 						break;
 					}
@@ -496,8 +2027,9 @@
 		 * where DNChain is of the format: "DN;DN;DN;" and DNChainPattern is of
 		 * the format: "DNPattern;*;DNPattern" (or combinations of this)
 		 */
-		private static boolean dnChainMatch(List dnChain, int dnChainIndex,
-				List dnChainPattern, int dnChainPatternIndex)
+		private static boolean dnChainMatch(List<Object> dnChain,
+				int dnChainIndex, List<Object> dnChainPattern,
+				int dnChainPatternIndex)
 				throws IllegalArgumentException {
 			if (dnChainIndex >= dnChain.size()) {
 				return false;
@@ -551,12 +2083,12 @@
 				// failure
 			}
 			else {
-				if (dnPattern instanceof List) {
+				if (dnPattern instanceof List< ? >) {
 					// here we have to do a deeper check for each DN in the
 					// pattern until we hit a wild card
 					do {
-						if (!dnmatch((List) dnChain.get(dnChainIndex),
-								(List) dnPattern)) {
+						if (!dnmatch((List< ? >) dnChain.get(dnChainIndex),
+								(List< ? >) dnPattern)) {
 							return false;
 						}
 						// go to the next set of DN's in both chains
@@ -598,7 +2130,7 @@
 									dnChainPattern, dnChainPatternIndex);
 						}
 						else {
-							if (!(dnPattern instanceof List)) {
+							if (!(dnPattern instanceof List< ? >)) {
 								throw new IllegalArgumentException(
 										"expected String or List in DN Pattern");
 							}
@@ -651,9 +2183,9 @@
 		 * @return true if dnChain matches the pattern.
 		 * @throws IllegalArgumentException
 		 */
-		static boolean match(String pattern, List/* <String> */dnChain) {
-			List parsedDNChain;
-			List parsedDNPattern;
+		static boolean match(String pattern, List<String> dnChain) {
+			List<Object> parsedDNChain;
+			List<Object> parsedDNPattern;
 			try {
 				parsedDNChain = parseDNchain(dnChain);
 			}
@@ -675,12 +2207,12 @@
 			return dnChainMatch(parsedDNChain, 0, parsedDNPattern, 0);
 		}
 
-		private static String toString(List dnChain) {
+		private static String toString(List< ? > dnChain) {
 			if (dnChain == null) {
 				return null;
 			}
 			StringBuffer sb = new StringBuffer();
-			for (Iterator iChain = dnChain.iterator(); iChain.hasNext();) {
+			for (Iterator< ? > iChain = dnChain.iterator(); iChain.hasNext();) {
 				sb.append(iChain.next());
 				if (iChain.hasNext()) {
 					sb.append("; ");
diff --git a/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java b/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java
index f67fd43..46d6d20 100644
--- a/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java
+++ b/framework/src/main/java/org/osgi/framework/InvalidSyntaxException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,14 +21,14 @@
  * syntax.
  * 
  * <p>
- * An <code>InvalidSyntaxException</code> object indicates that a filter
+ * An {@code InvalidSyntaxException} object indicates that a filter
  * string parameter has an invalid syntax and cannot be parsed. See
  * {@link Filter} for a description of the filter string syntax.
  * 
  * <p>
  * This exception conforms to the general purpose exception chaining mechanism.
  * 
- * @version $Revision: 6083 $
+ * @version $Id: adb84e3bc0b82b842e4da84542057fdf53e2ca6a $
  */
 
 public class InvalidSyntaxException extends Exception {
@@ -39,10 +39,10 @@
 	private final String	filter;
 
 	/**
-	 * Creates an exception of type <code>InvalidSyntaxException</code>.
+	 * Creates an exception of type {@code InvalidSyntaxException}.
 	 * 
 	 * <p>
-	 * This method creates an <code>InvalidSyntaxException</code> object with
+	 * This method creates an {@code InvalidSyntaxException} object with
 	 * the specified message and the filter string which generated the
 	 * exception.
 	 * 
@@ -55,10 +55,10 @@
 	}
 
 	/**
-	 * Creates an exception of type <code>InvalidSyntaxException</code>.
+	 * Creates an exception of type {@code InvalidSyntaxException}.
 	 * 
 	 * <p>
-	 * This method creates an <code>InvalidSyntaxException</code> object with
+	 * This method creates an {@code InvalidSyntaxException} object with
 	 * the specified message and the filter string which generated the
 	 * exception.
 	 * 
@@ -74,7 +74,7 @@
 
 	/**
 	 * Returns the filter string that generated the
-	 * <code>InvalidSyntaxException</code> object.
+	 * {@code InvalidSyntaxException} object.
 	 * 
 	 * @return The invalid filter string.
 	 * @see BundleContext#getServiceReferences
@@ -85,10 +85,10 @@
 	}
 
 	/**
-	 * Returns the cause of this exception or <code>null</code> if no cause was
+	 * Returns the cause of this exception or {@code null} if no cause was
 	 * set.
 	 * 
-	 * @return The cause of this exception or <code>null</code> if no cause was
+	 * @return The cause of this exception or {@code null} if no cause was
 	 *         set.
 	 * @since 1.3
 	 */
diff --git a/framework/src/main/java/org/osgi/framework/PackagePermission.java b/framework/src/main/java/org/osgi/framework/PackagePermission.java
index da2f540..b6697a5 100644
--- a/framework/src/main/java/org/osgi/framework/PackagePermission.java
+++ b/framework/src/main/java/org/osgi/framework/PackagePermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,11 +29,9 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -51,35 +49,35 @@
  * </pre>
  * 
  * <p>
- * <code>PackagePermission</code> has three actions: <code>exportonly</code>,
- * <code>import</code> and <code>export</code>. The <code>export</code> action,
- * which is deprecated, implies the <code>import</code> action.
+ * {@code PackagePermission} has three actions: {@code exportonly},
+ * {@code import} and {@code export}. The {@code export} action,
+ * which is deprecated, implies the {@code import} action.
  * 
  * @ThreadSafe
- * @version $Revision: 7189 $
+ * @version $Id: a286af94405e583f8bedc2ff5d7c818198f8caaf $
  */
 
 public final class PackagePermission extends BasicPermission {
 	static final long						serialVersionUID	= -5107705877071099135L;
 
 	/**
-	 * The action string <code>export</code>. The <code>export</code> action
-	 * implies the <code>import</code> action.
+	 * The action string {@code export}. The {@code export} action
+	 * implies the {@code import} action.
 	 * 
-	 * @deprecated Since 1.5. Use <code>exportonly</code> instead.
+	 * @deprecated Since 1.5. Use {@code exportonly} instead.
 	 */
 	public final static String				EXPORT				= "export";
 
 	/**
-	 * The action string <code>exportonly</code>. The <code>exportonly</code>
-	 * action does not imply the <code>import</code> action.
+	 * The action string {@code exportonly}. The {@code exportonly}
+	 * action does not imply the {@code import} action.
 	 * 
 	 * @since 1.5
 	 */
 	public final static String				EXPORTONLY			= "exportonly";
 
 	/**
-	 * The action string <code>import</code>.
+	 * The action string {@code import}.
 	 */
 	public final static String				IMPORT				= "import";
 
@@ -113,14 +111,14 @@
 	transient Filter						filter;
 
 	/**
-	 * This dictionary holds the properties of the permission, used to match a
-	 * filter in implies. This is not initialized until necessary, and then
-	 * cached in this object.
+	 * This map holds the properties of the permission, used to match a filter
+	 * in implies. This is not initialized until necessary, and then cached in
+	 * this object.
 	 */
-	private transient volatile Dictionary	properties;
+	private transient volatile Map<String, Object>	properties;
 
 	/**
-	 * Creates a new <code>PackagePermission</code> object.
+	 * Creates a new {@code PackagePermission} object.
 	 * 
 	 * <p>
 	 * The name is specified as a normal Java package name: a dot-separated
@@ -138,7 +136,7 @@
 	 * *
 	 * </pre>
 	 * 
-	 * For the <code>import</code> action, the name can also be a filter
+	 * For the {@code import} action, the name can also be a filter
 	 * expression. The filter gives access to the following attributes:
 	 * <ul>
 	 * <li>signer - A Distinguished Name chain used to sign the exporting
@@ -155,19 +153,19 @@
 	 * Package Permissions are granted over all possible versions of a package.
 	 * 
 	 * A bundle that needs to export a package must have the appropriate
-	 * <code>PackagePermission</code> for that package; similarly, a bundle that
+	 * {@code PackagePermission} for that package; similarly, a bundle that
 	 * needs to import a package must have the appropriate
-	 * <code>PackagePermssion</code> for that package.
+	 * {@code PackagePermssion} for that package.
 	 * <p>
 	 * Permission is granted for both classes and resources.
 	 * 
 	 * @param name Package name or filter expression. A filter expression can
-	 *        only be specified if the specified action is <code>import</code>.
-	 * @param actions <code>exportonly</code>,<code>import</code> (canonical
+	 *        only be specified if the specified action is {@code import}.
+	 * @param actions {@code exportonly},{@code import} (canonical
 	 *        order).
 	 * @throws IllegalArgumentException If the specified name is a filter
 	 *         expression and either the specified action is not
-	 *         <code>import</code> or the filter has an invalid syntax.
+	 *         {@code import} or the filter has an invalid syntax.
 	 */
 	public PackagePermission(String name, String actions) {
 		this(name, parseActions(actions));
@@ -179,17 +177,17 @@
 	}
 
 	/**
-	 * Creates a new requested <code>PackagePermission</code> object to be used
-	 * by code that must perform <code>checkPermission</code> for the
-	 * <code>import</code> action. <code>PackagePermission</code> objects
+	 * Creates a new requested {@code PackagePermission} object to be used
+	 * by code that must perform {@code checkPermission} for the
+	 * {@code import} action. {@code PackagePermission} objects
 	 * created with this constructor cannot be added to a
-	 * <code>PackagePermission</code> permission collection.
+	 * {@code PackagePermission} permission collection.
 	 * 
 	 * @param name The name of the requested package to import.
 	 * @param exportingBundle The bundle exporting the requested package.
-	 * @param actions The action <code>import</code>.
+	 * @param actions The action {@code import}.
 	 * @throws IllegalArgumentException If the specified action is not
-	 *         <code>import</code> or the name is a filter expression.
+	 *         {@code import} or the name is a filter expression.
 	 * @since 1.5
 	 */
 	public PackagePermission(String name, Bundle exportingBundle, String actions) {
@@ -345,7 +343,7 @@
 	 * 
 	 * @param filterString The filter string to parse.
 	 * @return a Filter for this bundle. If the specified filterString is not a
-	 *         filter expression, then <code>null</code> is returned.
+	 *         filter expression, then {@code null} is returned.
 	 * @throws IllegalArgumentException If the filter syntax is invalid.
 	 */
 	private static Filter parseFilter(String filterString) {
@@ -370,9 +368,9 @@
 	 * 
 	 * <p>
 	 * This method checks that the package name of the target is implied by the
-	 * package name of this object. The list of <code>PackagePermission</code>
+	 * package name of this object. The list of {@code PackagePermission}
 	 * actions must either match or allow for the list of the target object to
-	 * imply the target <code>PackagePermission</code> action.
+	 * imply the target {@code PackagePermission} action.
 	 * <p>
 	 * The permission to export a package implies the permission to import the
 	 * named package.
@@ -385,8 +383,8 @@
 	 * </pre>
 	 * 
 	 * @param p The requested permission.
-	 * @return <code>true</code> if the specified permission is implied by this
-	 *         object; <code>false</code> otherwise.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
 	 */
 	public boolean implies(Permission p) {
 		if (!(p instanceof PackagePermission)) {
@@ -411,8 +409,8 @@
 	 *        validated as a proper argument. The requested PackagePermission
 	 *        must not have a filter expression.
 	 * @param effective The effective actions with which to start.
-	 * @return <code>true</code> if the specified permission is implied by this
-	 *         object; <code>false</code> otherwise.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
 	 */
 	boolean implies0(PackagePermission requested, int effective) {
 		/* check actions first - much faster */
@@ -426,19 +424,19 @@
 		if (f == null) {
 			return super.implies(requested);
 		}
-		return f.matchCase(requested.getProperties());
+		return f.matches(requested.getProperties());
 	}
 
 	/**
 	 * Returns the canonical string representation of the
-	 * <code>PackagePermission</code> actions.
+	 * {@code PackagePermission} actions.
 	 * 
 	 * <p>
-	 * Always returns present <code>PackagePermission</code> actions in the
-	 * following order: <code>EXPORTONLY</code>,<code>IMPORT</code>.
+	 * Always returns present {@code PackagePermission} actions in the
+	 * following order: {@code EXPORTONLY},{@code IMPORT}.
 	 * 
 	 * @return Canonical string representation of the
-	 *         <code>PackagePermission</code> actions.
+	 *         {@code PackagePermission} actions.
 	 */
 	public String getActions() {
 		String result = actions;
@@ -464,28 +462,28 @@
 	}
 
 	/**
-	 * Returns a new <code>PermissionCollection</code> object suitable for
-	 * storing <code>PackagePermission</code> objects.
+	 * Returns a new {@code PermissionCollection} object suitable for
+	 * storing {@code PackagePermission} objects.
 	 * 
-	 * @return A new <code>PermissionCollection</code> object.
+	 * @return A new {@code PermissionCollection} object.
 	 */
 	public PermissionCollection newPermissionCollection() {
 		return new PackagePermissionCollection();
 	}
 
 	/**
-	 * Determines the equality of two <code>PackagePermission</code> objects.
+	 * Determines the equality of two {@code PackagePermission} objects.
 	 * 
 	 * This method checks that specified package has the same package name and
-	 * <code>PackagePermission</code> actions as this
-	 * <code>PackagePermission</code> object.
+	 * {@code PackagePermission} actions as this
+	 * {@code PackagePermission} object.
 	 * 
 	 * @param obj The object to test for equality with this
-	 *        <code>PackagePermission</code> object.
-	 * @return <code>true</code> if <code>obj</code> is a
-	 *         <code>PackagePermission</code>, and has the same package name and
-	 *         actions as this <code>PackagePermission</code> object;
-	 *         <code>false</code> otherwise.
+	 *        {@code PackagePermission} object.
+	 * @return {@code true} if {@code obj} is a
+	 *         {@code PackagePermission}, and has the same package name and
+	 *         actions as this {@code PackagePermission} object;
+	 *         {@code false} otherwise.
 	 */
 	public boolean equals(Object obj) {
 		if (obj == this) {
@@ -547,42 +545,42 @@
 	}
 
 	/**
-	 * Called by <code><@link PackagePermission#implies(Permission)></code>.
+	 * Called by {@code <@link PackagePermission#implies(Permission)>}. This
+	 * method is only called on a requested permission which cannot have a
+	 * filter set.
 	 * 
-	 * @return a dictionary of properties for this permission.
+	 * @return a map of properties for this permission.
 	 */
-	private Dictionary getProperties() {
-		Dictionary result = properties;
+	private Map<String, Object> getProperties() {
+		Map<String, Object> result = properties;
 		if (result != null) {
 			return result;
 		}
-		final Dictionary dict = new Hashtable(5);
-		if (filter == null) {
-			dict.put("package.name", getName());
-		}
+		final Map<String, Object> map = new HashMap<String, Object>(5);
+		map.put("package.name", getName());
 		if (bundle != null) {
-			AccessController.doPrivileged(new PrivilegedAction() {
+			AccessController.doPrivileged(new PrivilegedAction<Object>() {
 				public Object run() {
-					dict.put("id", new Long(bundle.getBundleId()));
-					dict.put("location", bundle.getLocation());
+					map.put("id", new Long(bundle.getBundleId()));
+					map.put("location", bundle.getLocation());
 					String name = bundle.getSymbolicName();
 					if (name != null) {
-						dict.put("name", name);
+						map.put("name", name);
 					}
 					SignerProperty signer = new SignerProperty(bundle);
 					if (signer.isBundleSigned()) {
-						dict.put("signer", signer);
+						map.put("signer", signer);
 					}
 					return null;
 				}
 			});
 		}
-		return properties = dict;
+		return properties = map;
 	}
 }
 
 /**
- * Stores a set of <code>PackagePermission</code> permissions.
+ * Stores a set of {@code PackagePermission} permissions.
  * 
  * @see java.security.Permission
  * @see java.security.Permissions
@@ -596,7 +594,7 @@
 	 * 
 	 * @GuardedBy this
 	 */
-	private transient Map	permissions;
+	private transient Map<String, PackagePermission>	permissions;
 
 	/**
 	 * Boolean saying if "*" is in the collection.
@@ -612,25 +610,25 @@
 	 * @serial
 	 * @GuardedBy this
 	 */
-	private Map				filterPermissions;
+	private Map<String, PackagePermission>				filterPermissions;
 
 	/**
 	 * Create an empty PackagePermissions object.
 	 */
 	public PackagePermissionCollection() {
-		permissions = new HashMap();
+		permissions = new HashMap<String, PackagePermission>();
 		all_allowed = false;
 	}
 
 	/**
 	 * Adds a permission to this permission collection.
 	 * 
-	 * @param permission The <code>PackagePermission</code> object to add.
+	 * @param permission The {@code PackagePermission} object to add.
 	 * @throws IllegalArgumentException If the specified permission is not a
-	 *         <code>PackagePermission</code> instance or was constructed with a
+	 *         {@code PackagePermission} instance or was constructed with a
 	 *         Bundle object.
 	 * @throws SecurityException If this
-	 *         <code>PackagePermissionCollection</code> object has been marked
+	 *         {@code PackagePermissionCollection} object has been marked
 	 *         read-only.
 	 */
 	public void add(final Permission permission) {
@@ -653,18 +651,18 @@
 		final Filter f = pp.filter;
 		synchronized (this) {
 			/* select the bucket for the permission */
-			Map pc;
+			Map<String, PackagePermission> pc;
 			if (f != null) {
 				pc = filterPermissions;
 				if (pc == null) {
-					filterPermissions = pc = new HashMap();
+					filterPermissions = pc = new HashMap<String, PackagePermission>();
 				}
 			}
 			else {
 				pc = permissions;
 			}
 			
-			final PackagePermission existing = (PackagePermission) pc.get(name);
+			final PackagePermission existing = pc.get(name);
 			if (existing != null) {
 				final int oldMask = existing.action_mask;
 				final int newMask = pp.action_mask;
@@ -689,12 +687,12 @@
 
 	/**
 	 * Determines if the specified permissions implies the permissions expressed
-	 * in <code>permission</code>.
+	 * in {@code permission}.
 	 * 
 	 * @param permission The Permission object to compare with this
-	 *        <code>PackagePermission</code> object.
-	 * @return <code>true</code> if <code>permission</code> is a proper subset
-	 *         of a permission in the set; <code>false</code> otherwise.
+	 *        {@code PackagePermission} object.
+	 * @return {@code true} if {@code permission} is a proper subset
+	 *         of a permission in the set; {@code false} otherwise.
 	 */
 	public boolean implies(final Permission permission) {
 		if (!(permission instanceof PackagePermission)) {
@@ -709,13 +707,13 @@
 		final int desired = requested.action_mask;
 		int effective = PackagePermission.ACTION_NONE;
 
-		Collection perms;
+		Collection<PackagePermission> perms;
 		synchronized (this) {
-			Map pc = permissions;
+			Map<String, PackagePermission> pc = permissions;
 			PackagePermission pp;
 			/* short circuit if the "*" Permission was added */
 			if (all_allowed) {
-				pp = (PackagePermission) pc.get("*");
+				pp = pc.get("*");
 				if (pp != null) {
 					effective |= pp.action_mask;
 					if ((effective & desired) == desired) {
@@ -727,7 +725,7 @@
 			 * strategy: Check for full match first. Then work our way up the
 			 * name looking for matches on a.b.*
 			 */
-			pp = (PackagePermission) pc.get(requestedName);
+			pp = pc.get(requestedName);
 			if (pp != null) {
 				/* we have a direct hit! */
 				effective |= pp.action_mask;
@@ -740,7 +738,7 @@
 			int offset = requestedName.length() - 1;
 			while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
 				requestedName = requestedName.substring(0, last + 1) + "*";
-				pp = (PackagePermission) pc.get(requestedName);
+				pp = pc.get(requestedName);
 				if (pp != null) {
 					effective |= pp.action_mask;
 					if ((effective & desired) == desired) {
@@ -760,9 +758,8 @@
 			perms = pc.values();
 		}
 		/* iterate one by one over filteredPermissions */
-		for (Iterator iter = perms.iterator(); iter.hasNext();) {
-			if (((PackagePermission) iter.next())
-					.implies0(requested, effective)) {
+		for (PackagePermission perm : perms) {
+			if (perm.implies0(requested, effective)) {
 				return true;
 			}
 		}
@@ -770,14 +767,14 @@
 	}
 
 	/**
-	 * Returns an enumeration of all <code>PackagePermission</code> objects in
+	 * Returns an enumeration of all {@code PackagePermission} objects in
 	 * the container.
 	 * 
-	 * @return Enumeration of all <code>PackagePermission</code> objects.
+	 * @return Enumeration of all {@code PackagePermission} objects.
 	 */
-	public synchronized Enumeration elements() {
-		List all = new ArrayList(permissions.values());
-		Map pc = filterPermissions;
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		Map<String, PackagePermission> pc = filterPermissions;
 		if (pc != null) {
 			all.addAll(pc.values());
 		}
@@ -792,7 +789,8 @@
 
 	private synchronized void writeObject(ObjectOutputStream out)
 			throws IOException {
-		Hashtable hashtable = new Hashtable(permissions);
+		Hashtable<String, PackagePermission> hashtable = new Hashtable<String, PackagePermission>(
+				permissions);
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", hashtable);
 		pfields.put("all_allowed", all_allowed);
@@ -803,9 +801,12 @@
 	private synchronized void readObject(java.io.ObjectInputStream in)
 			throws IOException, ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		Hashtable hashtable = (Hashtable) gfields.get("permissions", null);
-		permissions = new HashMap(hashtable);
+		Hashtable<String, PackagePermission> hashtable = (Hashtable<String, PackagePermission>) gfields
+				.get("permissions", null);
+		permissions = new HashMap<String, PackagePermission>(hashtable);
 		all_allowed = gfields.get("all_allowed", false);
-		filterPermissions = (HashMap) gfields.get("filterPermissions", null);
+		HashMap<String, PackagePermission> fp = (HashMap<String, PackagePermission>) gfields
+				.get("filterPermissions", null);
+		filterPermissions = fp;
 	}
 }
diff --git a/framework/src/main/java/org/osgi/framework/ServiceEvent.java b/framework/src/main/java/org/osgi/framework/ServiceEvent.java
index b7c9928..82ec899 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceEvent.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceEvent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,8 +22,8 @@
 /**
  * An event from the Framework describing a service lifecycle change.
  * <p>
- * <code>ServiceEvent</code> objects are delivered to
- * <code>ServiceListener</code>s and <code>AllServiceListener</code>s when a
+ * {@code ServiceEvent} objects are delivered to
+ * {@code ServiceListener}s and {@code AllServiceListener}s when a
  * change occurs in this service's lifecycle. A type code is used to identify
  * the event type for future extendability.
  * 
@@ -33,7 +33,7 @@
  * @Immutable
  * @see ServiceListener
  * @see AllServiceListener
- * @version $Revision: 6542 $
+ * @version $Id: 2b9458d90004411b6ca0cb4b361bc282b04c85eb $
  */
 
 public class ServiceEvent extends EventObject {
@@ -41,7 +41,7 @@
 	/**
 	 * Reference to the service that had a change occur in its lifecycle.
 	 */
-	private final ServiceReference	reference;
+	private final ServiceReference< ? >	reference;
 
 	/**
 	 * Type of service lifecycle change.
@@ -75,7 +75,7 @@
 	 * has completed unregistering.
 	 * 
 	 * <p>
-	 * If a bundle is using a service that is <code>UNREGISTERING</code>, the
+	 * If a bundle is using a service that is {@code UNREGISTERING}, the
 	 * bundle should release its use of the service when it receives this event.
 	 * If the bundle does not release its use of the service when it receives
 	 * this event, the Framework will automatically release the bundle's use of
@@ -92,7 +92,7 @@
 	 * <p>
 	 * This event is synchronously delivered <strong>after</strong> the service
 	 * properties have been modified. This event is only delivered to listeners
-	 * which were added with a non-<code>null</code> filter where the filter
+	 * which were added with a non-{@code null} filter where the filter
 	 * matched the service properties prior to the modification but the filter
 	 * does not match the modified service properties.
 	 * 
@@ -105,10 +105,10 @@
 	 * Creates a new service event object.
 	 * 
 	 * @param type The event type.
-	 * @param reference A <code>ServiceReference</code> object to the service
+	 * @param reference A {@code ServiceReference} object to the service
 	 * 	that had a lifecycle change.
 	 */
-	public ServiceEvent(int type, ServiceReference reference) {
+	public ServiceEvent(int type, ServiceReference< ? > reference) {
 		super(reference);
 		this.reference = reference;
 		this.type = type;
@@ -122,7 +122,7 @@
 	 * 
 	 * @return Reference to the service that had a lifecycle change.
 	 */
-	public ServiceReference getServiceReference() {
+	public ServiceReference< ? > getServiceReference() {
 		return reference;
 	}
 
diff --git a/framework/src/main/java/org/osgi/framework/ServiceException.java b/framework/src/main/java/org/osgi/framework/ServiceException.java
index 4cf04a0..d8ed3bd 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceException.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2007, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2007, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,18 +20,18 @@
  * A service exception used to indicate that a service problem occurred.
  * 
  * <p>
- * A <code>ServiceException</code> object is created by the Framework or
+ * A {@code ServiceException} object is created by the Framework or
  * service implementation to denote an exception condition in the service. A
  * type code is used to identify the exception type for future extendability.
  * Service implementations may also create subclasses of
- * <code>ServiceException</code>. When subclassing, the subclass should set
+ * {@code ServiceException}. When subclassing, the subclass should set
  * the type to {@link #SUBCLASSED} to indicate that
- * <code>ServiceException</code> has been subclassed.
+ * {@code ServiceException} has been subclassed.
  * 
  * <p>
  * This exception conforms to the general purpose exception chaining mechanism.
  * 
- * @version $Revision: 6518 $
+ * @version $Id: 453b6021eed4543f754e20696b9f8b33a7e121ee $
  * @since 1.5
  */
 
@@ -68,9 +68,16 @@
 	 * An error occurred invoking a remote service.
 	 */
 	public static final int REMOTE 				= 5;
+	/**
+	 * The service factory resulted in a recursive call to itself for the
+	 * requesting bundle.
+	 * 
+	 * @since 1.6
+	 */
+	public static final int	FACTORY_RECURSION	= 6;
 
 	/**
-	 * Creates a <code>ServiceException</code> with the specified message and
+	 * Creates a {@code ServiceException} with the specified message and
 	 * exception cause.
 	 * 
 	 * @param msg The associated message.
@@ -81,7 +88,7 @@
 	}
 
 	/**
-	 * Creates a <code>ServiceException</code> with the specified message.
+	 * Creates a {@code ServiceException} with the specified message.
 	 * 
 	 * @param msg The message.
 	 */
@@ -90,7 +97,7 @@
 	}
 
 	/**
-	 * Creates a <code>ServiceException</code> with the specified message,
+	 * Creates a {@code ServiceException} with the specified message,
 	 * type and exception cause.
 	 * 
 	 * @param msg The associated message.
@@ -103,7 +110,7 @@
 	}
 
 	/**
-	 * Creates a <code>ServiceException</code> with the specified message and
+	 * Creates a {@code ServiceException} with the specified message and
 	 * type.
 	 * 
 	 * @param msg The message.
@@ -115,7 +122,7 @@
 	}
 
 	/**
-	 * Returns the type for this exception or <code>UNSPECIFIED</code> if the
+	 * Returns the type for this exception or {@code UNSPECIFIED} if the
 	 * type was unspecified or unknown.
 	 * 
 	 * @return The type of this exception.
diff --git a/framework/src/main/java/org/osgi/framework/ServiceFactory.java b/framework/src/main/java/org/osgi/framework/ServiceFactory.java
index c8f6bf3..6383b22 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceFactory.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,65 +21,73 @@
  * environment.
  * 
  * <p>
- * When registering a service, a <code>ServiceFactory</code> object can be
- * used instead of a service object, so that the bundle developer can gain
- * control of the specific service object granted to a bundle that is using the
- * service.
+ * When registering a service, a {@code ServiceFactory} object can be used
+ * instead of a service object, so that the bundle developer can gain control of
+ * the specific service object granted to a bundle that is using the service.
  * 
  * <p>
- * When this happens, the
- * <code>BundleContext.getService(ServiceReference)</code> method calls the
- * <code>ServiceFactory.getService</code> method to create a service object
- * specifically for the requesting bundle. The service object returned by the
- * <code>ServiceFactory</code> is cached by the Framework until the bundle
+ * When this happens, the {@code BundleContext.getService(ServiceReference)}
+ * method calls the {@code ServiceFactory.getService} method to create a service
+ * object specifically for the requesting bundle. The service object returned by
+ * the {@code ServiceFactory} is cached by the Framework until the bundle
  * releases its use of the service.
  * 
  * <p>
- * When the bundle's use count for the service equals zero (including the bundle
- * stopping or the service being unregistered), the
- * <code>ServiceFactory.ungetService</code> method is called.
+ * When the bundle's use count for the service is decremented to zero (including
+ * the bundle stopping or the service being unregistered), the
+ * {@code ServiceFactory.ungetService} method is called.
  * 
  * <p>
- * <code>ServiceFactory</code> objects are only used by the Framework and are
- * not made available to other bundles in the OSGi environment. The Framework
- * may concurrently call a <code>ServiceFactory</code>.
+ * {@code ServiceFactory} objects are only used by the Framework and are not
+ * made available to other bundles in the OSGi environment. The Framework may
+ * concurrently call a {@code ServiceFactory}.
  * 
+ * @param <S> Type of Service
  * @see BundleContext#getService
  * @ThreadSafe
- * @version $Revision: 5967 $
+ * @version $Id: 94cd1a0127aaad9beb484f557342a8fbd0be2322 $
  */
 
-public interface ServiceFactory {
+public interface ServiceFactory<S> {
 	/**
 	 * Creates a new service object.
 	 * 
 	 * <p>
 	 * The Framework invokes this method the first time the specified
-	 * <code>bundle</code> requests a service object using the
-	 * <code>BundleContext.getService(ServiceReference)</code> method. The
-	 * service factory can then return a specific service object for each
-	 * bundle.
+	 * {@code bundle} requests a service object using the
+	 * {@code BundleContext.getService(ServiceReference)} method. The service
+	 * factory can then return a specific service object for each bundle.
 	 * 
 	 * <p>
-	 * The Framework caches the value returned (unless it is <code>null</code>),
-	 * and will return the same service object on any future call to
-	 * <code>BundleContext.getService</code> for the same bundle. This means the
-	 * Framework must not allow this method to be concurrently called for the
-	 * same bundle.
+	 * The Framework must check that the returned service object is valid. If
+	 * the returned service object is {@code null} or is not an
+	 * {@code instanceof} all the classes named when the service was registered,
+	 * a framework event of type {@link FrameworkEvent#ERROR} is fired
+	 * containing a service exception of type
+	 * {@link ServiceException#FACTORY_ERROR} and {@code null} is returned to
+	 * the bundle. If this method throws an exception, a framework event of type
+	 * {@link FrameworkEvent#ERROR} is fired containing a service exception of
+	 * type {@link ServiceException#FACTORY_EXCEPTION} with the thrown exception
+	 * as the cause and {@code null} is returned to the bundle. If this method
+	 * is recursively called for the specified bundle, a framework event of type
+	 * {@link FrameworkEvent#ERROR} is fired containing a service exception of
+	 * type {@link ServiceException#FACTORY_RECURSION} and {@code null} is
+	 * returned to the bundle.
 	 * 
 	 * <p>
-	 * The Framework will check if the returned service object is an instance of
-	 * all the classes named when the service was registered. If not, then
-	 * <code>null</code> is returned to the bundle.
+	 * The Framework caches the valid service object and will return the same
+	 * service object on any future call to {@code BundleContext.getService} for
+	 * the specified bundle. This means the Framework must not allow this method
+	 * to be concurrently called for the specified bundle.
 	 * 
-	 * @param bundle The bundle using the service.
-	 * @param registration The <code>ServiceRegistration</code> object for the
-	 *        service.
+	 * @param bundle The bundle requesting the service.
+	 * @param registration The {@code ServiceRegistration} object for the
+	 *        requested service.
 	 * @return A service object that <strong>must</strong> be an instance of all
 	 *         the classes named when the service was registered.
 	 * @see BundleContext#getService
 	 */
-	public Object getService(Bundle bundle, ServiceRegistration registration);
+	public S getService(Bundle bundle, ServiceRegistration<S> registration);
 
 	/**
 	 * Releases a service object.
@@ -88,13 +96,20 @@
 	 * The Framework invokes this method when a service has been released by a
 	 * bundle. The service object may then be destroyed.
 	 * 
+	 * <p>
+	 * If this method throws an exception, a framework event of type
+	 * {@link FrameworkEvent#ERROR} is fired containing a service exception of
+	 * type {@link ServiceException#FACTORY_EXCEPTION} with the thrown exception
+	 * as the cause.
+	 * 
 	 * @param bundle The bundle releasing the service.
-	 * @param registration The <code>ServiceRegistration</code> object for the
-	 *        service.
+	 * @param registration The {@code ServiceRegistration} object for the
+	 *        service being released.
 	 * @param service The service object returned by a previous call to the
-	 *        <code>ServiceFactory.getService</code> method.
+	 *        {@link #getService(Bundle, ServiceRegistration) getService}
+	 *        method.
 	 * @see BundleContext#ungetService
 	 */
-	public void ungetService(Bundle bundle, ServiceRegistration registration,
-			Object service);
+	public void ungetService(Bundle bundle, ServiceRegistration<S> registration,
+			S service);
 }
diff --git a/framework/src/main/java/org/osgi/framework/ServiceListener.java b/framework/src/main/java/org/osgi/framework/ServiceListener.java
index ec08560..dc6a159 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceListener.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,46 +19,46 @@
 import java.util.EventListener;
 
 /**
- * A <code>ServiceEvent</code> listener. <code>ServiceListener</code> is a
+ * A {@code ServiceEvent} listener. {@code ServiceListener} is a
  * listener interface that may be implemented by a bundle developer. When a
- * <code>ServiceEvent</code> is fired, it is synchronously delivered to a
- * <code>ServiceListener</code>. The Framework may deliver
- * <code>ServiceEvent</code> objects to a <code>ServiceListener</code> out
+ * {@code ServiceEvent} is fired, it is synchronously delivered to a
+ * {@code ServiceListener}. The Framework may deliver
+ * {@code ServiceEvent} objects to a {@code ServiceListener} out
  * of order and may concurrently call and/or reenter a
- * <code>ServiceListener</code>.
+ * {@code ServiceListener}.
  * 
  * <p>
- * A <code>ServiceListener</code> object is registered with the Framework
- * using the <code>BundleContext.addServiceListener</code> method.
- * <code>ServiceListener</code> objects are called with a
- * <code>ServiceEvent</code> object when a service is registered, modified, or
+ * A {@code ServiceListener} object is registered with the Framework
+ * using the {@code BundleContext.addServiceListener} method.
+ * {@code ServiceListener} objects are called with a
+ * {@code ServiceEvent} object when a service is registered, modified, or
  * is in the process of unregistering.
  * 
  * <p>
- * <code>ServiceEvent</code> object delivery to <code>ServiceListener</code>
+ * {@code ServiceEvent} object delivery to {@code ServiceListener}
  * objects is filtered by the filter specified when the listener was registered.
  * If the Java Runtime Environment supports permissions, then additional
- * filtering is done. <code>ServiceEvent</code> objects are only delivered to
+ * filtering is done. {@code ServiceEvent} objects are only delivered to
  * the listener if the bundle which defines the listener object's class has the
- * appropriate <code>ServicePermission</code> to get the service using at
+ * appropriate {@code ServicePermission} to get the service using at
  * least one of the named classes under which the service was registered.
  * 
  * <p>
- * <code>ServiceEvent</code> object delivery to <code>ServiceListener</code>
+ * {@code ServiceEvent} object delivery to {@code ServiceListener}
  * objects is further filtered according to package sources as defined in
  * {@link ServiceReference#isAssignableTo(Bundle, String)}.
  * 
  * @see ServiceEvent
  * @see ServicePermission
  * @ThreadSafe
- * @version $Revision: 5673 $
+ * @version $Id: d73f8e9b4babc8b53b5d1cbe7b17b732f54bb2a3 $
  */
 
 public interface ServiceListener extends EventListener {
 	/**
 	 * Receives notification that a service has had a lifecycle change.
 	 * 
-	 * @param event The <code>ServiceEvent</code> object.
+	 * @param event The {@code ServiceEvent} object.
 	 */
 	public void serviceChanged(ServiceEvent event);
 }
diff --git a/framework/src/main/java/org/osgi/framework/ServicePermission.java b/framework/src/main/java/org/osgi/framework/ServicePermission.java
index d2f3c31..b7a9956 100644
--- a/framework/src/main/java/org/osgi/framework/ServicePermission.java
+++ b/framework/src/main/java/org/osgi/framework/ServicePermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,42 +26,43 @@
 import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.PrivilegedAction;
+import java.util.AbstractMap;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * A bundle's authority to register or get a service.
  * <ul>
- * <li>The <code>register</code> action allows a bundle to register a service on
+ * <li>The {@code register} action allows a bundle to register a service on
  * the specified names.
- * <li>The <code>get</code> action allows a bundle to detect a service and get
+ * <li>The {@code get} action allows a bundle to detect a service and get
  * it.
  * </ul>
  * Permission to get a service is required in order to detect events regarding
  * the service. Untrusted bundles should not be able to detect the presence of
  * certain services unless they have the appropriate
- * <code>ServicePermission</code> to get the specific service.
+ * {@code ServicePermission} to get the specific service.
  * 
  * @ThreadSafe
- * @version $Revision: 7189 $
+ * @version $Id: 1b6ee9543f4cbc16add8dc8c40dfa9a6dfee7aa2 $
  */
 
 public final class ServicePermission extends BasicPermission {
 	static final long			serialVersionUID	= -7662148639076511574L;
 	/**
-	 * The action string <code>get</code>.
+	 * The action string {@code get}.
 	 */
 	public final static String	GET					= "get";
 	/**
-	 * The action string <code>register</code>.
+	 * The action string {@code register}.
 	 */
 	public final static String	REGISTER			= "register";
 
@@ -87,7 +88,7 @@
 	 * The service used by this ServicePermission. Must be null if not
 	 * constructed with a service.
 	 */
-	transient final ServiceReference		service;
+	transient final ServiceReference< ? >					service;
 
 	/**
 	 * The object classes for this ServicePermission. Must be null if not
@@ -102,11 +103,11 @@
 	transient Filter						filter;
 
 	/**
-	 * This dictionary holds the properties of the permission, used to match a
-	 * filter in implies. This is not initialized until necessary, and then
-	 * cached in this object.
+	 * This map holds the properties of the permission, used to match a filter
+	 * in implies. This is not initialized until necessary, and then cached in
+	 * this object.
 	 */
-	private transient volatile Dictionary	properties;
+	private transient volatile Map<String, Object>	properties;
 
 	/**
 	 * True if constructed with a name and the name is "*" or ends with ".*".
@@ -138,7 +139,7 @@
 	 * *
 	 * </pre>
 	 * 
-	 * For the <code>get</code> action, the name can also be a filter
+	 * For the {@code get} action, the name can also be a filter
 	 * expression. The filter gives access to the service properties as well as
 	 * the following attributes:
 	 * <ul>
@@ -158,17 +159,17 @@
 	 * Service properties names are case insensitive.
 	 * 
 	 * <p>
-	 * There are two possible actions: <code>get</code> and
-	 * <code>register</code>. The <code>get</code> permission allows the owner
+	 * There are two possible actions: {@code get} and
+	 * {@code register}. The {@code get} permission allows the owner
 	 * of this permission to obtain a service with this name. The
-	 * <code>register</code> permission allows the bundle to register a service
+	 * {@code register} permission allows the bundle to register a service
 	 * under that name.
 	 * 
 	 * @param name The service class name
-	 * @param actions <code>get</code>,<code>register</code> (canonical order)
+	 * @param actions {@code get},{@code register} (canonical order)
 	 * @throws IllegalArgumentException If the specified name is a filter
 	 *         expression and either the specified action is not
-	 *         <code>get</code> or the filter has an invalid syntax.
+	 *         {@code get} or the filter has an invalid syntax.
 	 */
 	public ServicePermission(String name, String actions) {
 		this(name, parseActions(actions));
@@ -180,19 +181,19 @@
 	}
 
 	/**
-	 * Creates a new requested <code>ServicePermission</code> object to be used
-	 * by code that must perform <code>checkPermission</code> for the
-	 * <code>get</code> action. <code>ServicePermission</code> objects created
-	 * with this constructor cannot be added to a <code>ServicePermission</code>
+	 * Creates a new requested {@code ServicePermission} object to be used
+	 * by code that must perform {@code checkPermission} for the
+	 * {@code get} action. {@code ServicePermission} objects created
+	 * with this constructor cannot be added to a {@code ServicePermission}
 	 * permission collection.
 	 * 
 	 * @param reference The requested service.
-	 * @param actions The action <code>get</code>.
+	 * @param actions The action {@code get}.
 	 * @throws IllegalArgumentException If the specified action is not
-	 *         <code>get</code> or reference is <code>null</code>.
+	 *         {@code get} or reference is {@code null}.
 	 * @since 1.5
 	 */
-	public ServicePermission(ServiceReference reference, String actions) {
+	public ServicePermission(ServiceReference< ? > reference, String actions) {
 		super(createName(reference));
 		setTransients(null, parseActions(actions));
 		this.service = reference;
@@ -209,7 +210,7 @@
 	 * @param reference ServiceReference to use to create permission name.
 	 * @return permission name.
 	 */
-	private static String createName(ServiceReference reference) {
+	private static String createName(ServiceReference< ? > reference) {
 		if (reference == null) {
 			throw new IllegalArgumentException("reference must not be null");
 		}
@@ -351,7 +352,7 @@
 	 * 
 	 * @param filterString The filter string to parse.
 	 * @return a Filter for this bundle. If the specified filterString is not a
-	 *         filter expression, then <code>null</code> is returned.
+	 *         filter expression, then {@code null} is returned.
 	 * @throws IllegalArgumentException If the filter syntax is invalid.
 	 */
 	private static Filter parseFilter(String filterString) {
@@ -372,12 +373,12 @@
 	}
 
 	/**
-	 * Determines if a <code>ServicePermission</code> object "implies" the
+	 * Determines if a {@code ServicePermission} object "implies" the
 	 * specified permission.
 	 * 
 	 * @param p The target permission to check.
-	 * @return <code>true</code> if the specified permission is implied by this
-	 *         object; <code>false</code> otherwise.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
 	 */
 	public boolean implies(Permission p) {
 		if (!(p instanceof ServicePermission)) {
@@ -402,8 +403,8 @@
 	 *        validated as a proper argument. The requested ServicePermission
 	 *        must not have a filter expression.
 	 * @param effective The effective actions with which to start.
-	 * @return <code>true</code> if the specified permission is implied by this
-	 *         object; <code>false</code> otherwise.
+	 * @return {@code true} if the specified permission is implied by this
+	 *         object; {@code false} otherwise.
 	 */
 	boolean implies0(ServicePermission requested, int effective) {
 		/* check actions first - much faster */
@@ -419,7 +420,7 @@
 		/* if we have a filter */
 		Filter f = filter;
 		if (f != null) {
-			return f.matchCase(requested.getProperties());
+			return f.matches(requested.getProperties());
 		}
 		/* if requested permission not created with ServiceReference */
 		String[] requestedNames = requested.objectClass;
@@ -450,8 +451,8 @@
 
 	/**
 	 * Returns the canonical string representation of the actions. Always
-	 * returns present actions in the following order: <code>get</code>,
-	 * <code>register</code>.
+	 * returns present actions in the following order: {@code get},
+	 * {@code register}.
 	 * 
 	 * @return The canonical string representation of the actions.
 	 */
@@ -480,11 +481,11 @@
 	}
 
 	/**
-	 * Returns a new <code>PermissionCollection</code> object for storing
-	 * <code>ServicePermission<code> objects.
-	 *
-	 * @return A new <code>PermissionCollection</code> object suitable for storing
-	 * <code>ServicePermission</code> objects.
+	 * Returns a new {@code PermissionCollection} object for storing
+	 * {@code ServicePermission} objects.
+	 * 
+	 * @return A new {@code PermissionCollection} object suitable for storing
+	 *         {@code ServicePermission} objects.
 	 */
 	public PermissionCollection newPermissionCollection() {
 		return new ServicePermissionCollection();
@@ -494,12 +495,12 @@
 	 * Determines the equality of two ServicePermission objects.
 	 * 
 	 * Checks that specified object has the same class name and action as this
-	 * <code>ServicePermission</code>.
+	 * {@code ServicePermission}.
 	 * 
 	 * @param obj The object to test for equality.
-	 * @return true if obj is a <code>ServicePermission</code>, and has the same
-	 *         class name and actions as this <code>ServicePermission</code>
-	 *         object; <code>false</code> otherwise.
+	 * @return true if obj is a {@code ServicePermission}, and has the same
+	 *         class name and actions as this {@code ServicePermission}
+	 *         object; {@code false} otherwise.
 	 */
 	public boolean equals(Object obj) {
 		if (obj == this) {
@@ -558,27 +559,28 @@
 		s.defaultReadObject();
 		setTransients(parseFilter(getName()), parseActions(actions));
 	}
+
 	/**
-	 * Called by <code><@link ServicePermission#implies(Permission)></code>.
+	 * Called by {@code <@link ServicePermission#implies(Permission)>}. This
+	 * method is only called on a requested permission which cannot have a
+	 * filter set.
 	 * 
-	 * @return a dictionary of properties for this permission.
+	 * @return a map of properties for this permission.
 	 */
-	private Dictionary getProperties() {
-		Dictionary result = properties;
+	private Map<String, Object> getProperties() {
+		Map<String, Object> result = properties;
 		if (result != null) {
 			return result;
 		}
 		if (service == null) {
-			result = new Hashtable(1);
-			if (filter == null) {
-				result.put(Constants.OBJECTCLASS, new String[] {getName()});
-			}
+			result = new HashMap<String, Object>(1);
+			result.put(Constants.OBJECTCLASS, new String[] {getName()});
 			return properties = result;
 		}
-		final Map props = new HashMap(4);
+		final Map<String, Object> props = new HashMap<String, Object>(4);
 		final Bundle bundle = service.getBundle();
 		if (bundle != null) {
-			AccessController.doPrivileged(new PrivilegedAction() {
+			AccessController.doPrivileged(new PrivilegedAction<Object>() {
 				public Object run() {
 					props.put("id", new Long(bundle.getBundleId()));
 					props.put("location", bundle.getLocation());
@@ -597,13 +599,15 @@
 		return properties = new Properties(props, service);
 	}
 	
-	private static class Properties extends Dictionary {
-		private final Map				properties;
-		private final ServiceReference	service;
+	static private final class Properties extends AbstractMap<String, Object> {
+		private final Map<String, Object>	properties;
+		private final ServiceReference< ? >	service;
+		private transient volatile Set<Map.Entry<String, Object>>	entries;
 
-		Properties(Map properties, ServiceReference service) {
+		Properties(Map<String, Object> properties, ServiceReference< ? > service) {
 			this.properties = properties;
 			this.service = service;
+			entries = null;
 		}
 
 		public Object get(Object k) {
@@ -621,57 +625,64 @@
 			return service.getProperty(key);
 		}
 
-		public int size() {
-			return properties.size() + service.getPropertyKeys().length;
-		}
-
-		public boolean isEmpty() {
-			// we can return false because this must never be empty
-			return false;
-		}
-
-		public Enumeration keys() {
-			Collection pk = properties.keySet();
-			String spk[] = service.getPropertyKeys();
-			List all = new ArrayList(pk.size() + spk.length);
-			all.addAll(pk);
-			add:
-			for (int i = 0, length = spk.length; i < length; i++) {
-				String key = spk[i];
-				for (Iterator iter = pk.iterator(); iter.hasNext();) {
-					if (key.equalsIgnoreCase((String) iter.next())) {
+		public Set<Map.Entry<String, Object>> entrySet() {
+			if (entries != null) {
+				return entries;
+			}
+			Set<Map.Entry<String, Object>> all = new HashSet<Map.Entry<String, Object>>(
+					properties.entrySet());
+			add: for (String key : service.getPropertyKeys()) {
+				for (String k : properties.keySet()) {
+					if (key.equalsIgnoreCase(k)) {
 						continue add;
 					}
 				}
-				all.add(key);
+				all.add(new Entry(key, service.getProperty(key)));
 			}
-			return Collections.enumeration(all);
+			return entries = Collections.unmodifiableSet(all);
 		}
+		
+		static private final class Entry implements Map.Entry<String, Object> {
+			private final String	k;
+			private final Object	v;
 
-		public Enumeration elements() {
-			Collection pk = properties.keySet();
-			String spk[] = service.getPropertyKeys();
-			List all = new ArrayList(pk.size() + spk.length);
-			all.addAll(properties.values());
-			add:
-			for (int i = 0, length = spk.length; i < length; i++) {
-				String key = spk[i];
-				for (Iterator iter = pk.iterator(); iter.hasNext();) {
-					if (key.equalsIgnoreCase((String) iter.next())) {
-						continue add;
+			Entry(String key, Object value) {
+				this.k = key;
+				this.v = value;
+			}
+			public String getKey() {
+				return k;
+			}
+			public Object getValue() {
+				return v;
+			}
+			public Object setValue(Object value) {
+				throw new UnsupportedOperationException();
+			}
+			public String toString() {
+				return k + "=" + v;
+			}
+			public int hashCode() {
+				return ((k == null) ? 0 : k.hashCode())
+						^ ((v == null) ? 0 : v.hashCode());
+			}
+			public boolean equals(Object obj) {
+				if (obj == this) {
+					return true;
+				}
+				if (!(obj instanceof Map.Entry)) {
+					return false;
+				}
+				Map.Entry< ? , ? > e = (Map.Entry< ? , ? >) obj;
+				final Object key = e.getKey();
+				if ((k == key) || ((k != null) && k.equals(key))) {
+					final Object value = e.getValue();
+					if ((v == value) || ((v != null) && v.equals(value))) {
+						return true;
 					}
 				}
-				all.add(service.getProperty(key));
+				return false;
 			}
-			return Collections.enumeration(all);
-		}
-
-		public Object put(Object key, Object value) {
-			throw new UnsupportedOperationException();
-		}
-
-		public Object remove(Object key) {
-			throw new UnsupportedOperationException();
 		}
 	}
 }
@@ -690,7 +701,7 @@
 	 * 
 	 * @GuardedBy this
 	 */
-	private transient Map	permissions;
+	private transient Map<String, ServicePermission>	permissions;
 
 	/**
 	 * Boolean saying if "*" is in the collection.
@@ -706,13 +717,13 @@
 	 * @serial
 	 * @GuardedBy this
 	 */
-	private Map				filterPermissions;
+	private Map<String, ServicePermission>				filterPermissions;
 
 	/**
 	 * Creates an empty ServicePermissions object.
 	 */
 	public ServicePermissionCollection() {
-		permissions = new HashMap();
+		permissions = new HashMap<String, ServicePermission>();
 		all_allowed = false;
 	}
 
@@ -723,7 +734,7 @@
 	 * @throws IllegalArgumentException If the specified permission is not a
 	 *         ServicePermission object.
 	 * @throws SecurityException If this
-	 *         <code>ServicePermissionCollection</code> object has been marked
+	 *         {@code ServicePermissionCollection} object has been marked
 	 *         read-only.
 	 */
 	public void add(final Permission permission) {
@@ -746,17 +757,17 @@
 		final Filter f = sp.filter;
 		synchronized (this) {
 			/* select the bucket for the permission */
-			Map pc;
+			Map<String, ServicePermission> pc;
 			if (f != null) {
 				pc = filterPermissions;
 				if (pc == null) {
-					filterPermissions = pc = new HashMap();
+					filterPermissions = pc = new HashMap<String, ServicePermission>();
 				}
 			}
 			else {
 				pc = permissions;
 			}
-			final ServicePermission existing = (ServicePermission) pc.get(name);
+			final ServicePermission existing = pc.get(name);
 			
 			if (existing != null) {
 				final int oldMask = existing.action_mask;
@@ -781,11 +792,11 @@
 
 	/**
 	 * Determines if a set of permissions implies the permissions expressed in
-	 * <code>permission</code>.
+	 * {@code permission}.
 	 * 
 	 * @param permission The Permission object to compare.
-	 * @return <code>true</code> if <code>permission</code> is a proper
-	 *         subset of a permission in the set; <code>false</code>
+	 * @return {@code true} if {@code permission} is a proper
+	 *         subset of a permission in the set; {@code false}
 	 *         otherwise.
 	 */
 	public boolean implies(final Permission permission) {
@@ -799,12 +810,12 @@
 		}
 
 		int effective = ServicePermission.ACTION_NONE;
-		Collection perms;
+		Collection<ServicePermission> perms;
 		synchronized (this) {
 			final int desired = requested.action_mask;
 			/* short circuit if the "*" Permission was added */
 			if (all_allowed) {
-				ServicePermission sp = (ServicePermission) permissions.get("*");
+				ServicePermission sp = permissions.get("*");
 				if (sp != null) {
 					effective |= sp.action_mask;
 					if ((effective & desired) == desired) {
@@ -829,7 +840,7 @@
 					}
 				}
 			}
-			Map pc = filterPermissions;
+			Map<String, ServicePermission> pc = filterPermissions;
 			if (pc == null) {
 				return false;
 			}
@@ -837,9 +848,8 @@
 		}
 		
 		/* iterate one by one over filteredPermissions */
-		for (Iterator iter = perms.iterator(); iter.hasNext();) {
-			if (((ServicePermission) iter.next())
-					.implies0(requested, effective)) {
+		for (ServicePermission perm : perms) {
+			if (perm.implies0(requested, effective)) {
 				return true;
 			}
 		}
@@ -857,8 +867,8 @@
 	 */
 	private int effective(String requestedName, final int desired,
 			int effective) {
-		final Map pc = permissions;
-		ServicePermission sp = (ServicePermission) pc.get(requestedName);
+		final Map<String, ServicePermission> pc = permissions;
+		ServicePermission sp = pc.get(requestedName);
 		// strategy:
 		// Check for full match first. Then work our way up the
 		// name looking for matches on a.b.*
@@ -874,7 +884,7 @@
 		int offset = requestedName.length() - 1;
 		while ((last = requestedName.lastIndexOf(".", offset)) != -1) {
 			requestedName = requestedName.substring(0, last + 1) + "*";
-			sp = (ServicePermission) pc.get(requestedName);
+			sp = pc.get(requestedName);
 			if (sp != null) {
 				effective |= sp.action_mask;
 				if ((effective & desired) == desired) {
@@ -891,14 +901,14 @@
 	}
 	
 	/**
-	 * Returns an enumeration of all the <code>ServicePermission</code>
+	 * Returns an enumeration of all the {@code ServicePermission}
 	 * objects in the container.
 	 * 
 	 * @return Enumeration of all the ServicePermission objects.
 	 */
-	public synchronized Enumeration elements() {
-		List all = new ArrayList(permissions.values());
-		Map pc = filterPermissions;
+	public synchronized Enumeration<Permission> elements() {
+		List<Permission> all = new ArrayList<Permission>(permissions.values());
+		Map<String, ServicePermission> pc = filterPermissions;
 		if (pc != null) {
 			all.addAll(pc.values());
 		}
@@ -913,7 +923,8 @@
 
 	private synchronized void writeObject(ObjectOutputStream out)
 			throws IOException {
-		Hashtable hashtable = new Hashtable(permissions);
+		Hashtable<String, ServicePermission> hashtable = new Hashtable<String, ServicePermission>(
+				permissions);
 		ObjectOutputStream.PutField pfields = out.putFields();
 		pfields.put("permissions", hashtable);
 		pfields.put("all_allowed", all_allowed);
@@ -924,9 +935,12 @@
 	private synchronized void readObject(java.io.ObjectInputStream in)
 			throws IOException, ClassNotFoundException {
 		ObjectInputStream.GetField gfields = in.readFields();
-		Hashtable hashtable = (Hashtable) gfields.get("permissions", null);
-		permissions = new HashMap(hashtable);
+		Hashtable<String, ServicePermission> hashtable = (Hashtable<String, ServicePermission>) gfields
+				.get("permissions", null);
+		permissions = new HashMap<String, ServicePermission>(hashtable);
 		all_allowed = gfields.get("all_allowed", false);
-		filterPermissions = (HashMap) gfields.get("filterPermissions", null);
+		HashMap<String, ServicePermission> fp = (HashMap<String, ServicePermission>) gfields
+				.get("filterPermissions", null);
+		filterPermissions = fp;
 	}
 }
diff --git a/framework/src/main/java/org/osgi/framework/ServiceReference.java b/framework/src/main/java/org/osgi/framework/ServiceReference.java
index a6dd9bd..ad38df7 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceReference.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceReference.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,38 +22,40 @@
  * A reference to a service.
  * 
  * <p>
- * The Framework returns <code>ServiceReference</code> objects from the
- * <code>BundleContext.getServiceReference</code> and
- * <code>BundleContext.getServiceReferences</code> methods.
+ * The Framework returns {@code ServiceReference} objects from the
+ * {@code BundleContext.getServiceReference} and
+ * {@code BundleContext.getServiceReferences} methods.
  * <p>
- * A <code>ServiceReference</code> object may be shared between bundles and
- * can be used to examine the properties of the service and to get the service
+ * A {@code ServiceReference} object may be shared between bundles and can
+ * be used to examine the properties of the service and to get the service
  * object.
  * <p>
  * Every service registered in the Framework has a unique
- * <code>ServiceRegistration</code> object and may have multiple, distinct
- * <code>ServiceReference</code> objects referring to it.
- * <code>ServiceReference</code> objects associated with a
- * <code>ServiceRegistration</code> object have the same <code>hashCode</code>
- * and are considered equal (more specifically, their <code>equals()</code>
- * method will return <code>true</code> when compared).
+ * {@code ServiceRegistration} object and may have multiple, distinct
+ * {@code ServiceReference} objects referring to it.
+ * {@code ServiceReference} objects associated with a
+ * {@code ServiceRegistration} object have the same {@code hashCode}
+ * and are considered equal (more specifically, their {@code equals()}
+ * method will return {@code true} when compared).
  * <p>
  * If the same service object is registered multiple times,
- * <code>ServiceReference</code> objects associated with different
- * <code>ServiceRegistration</code> objects are not equal.
+ * {@code ServiceReference} objects associated with different
+ * {@code ServiceRegistration} objects are not equal.
  * 
+ * @param <S> Type of Service.
  * @see BundleContext#getServiceReference
  * @see BundleContext#getServiceReferences
  * @see BundleContext#getService
  * @ThreadSafe
- * @version $Revision: 6374 $
+ * @noimplement
+ * @version $Id: 771b9b4d4f65dbe593154d02912edba51a085b0c $
  */
 
-public interface ServiceReference extends Comparable {
+public interface ServiceReference<S> extends Comparable<Object> {
 	/**
 	 * Returns the property value to which the specified property key is mapped
-	 * in the properties <code>Dictionary</code> object of the service
-	 * referenced by this <code>ServiceReference</code> object.
+	 * in the properties {@code Dictionary} object of the service
+	 * referenced by this {@code ServiceReference} object.
 	 * 
 	 * <p>
 	 * Property keys are case-insensitive.
@@ -61,30 +63,30 @@
 	 * <p>
 	 * This method must continue to return property values after the service has
 	 * been unregistered. This is so references to unregistered services (for
-	 * example, <code>ServiceReference</code> objects stored in the log) can
+	 * example, {@code ServiceReference} objects stored in the log) can
 	 * still be interrogated.
 	 * 
 	 * @param key The property key.
-	 * @return The property value to which the key is mapped; <code>null</code>
+	 * @return The property value to which the key is mapped; {@code null}
 	 *         if there is no property named after the key.
 	 */
 	public Object getProperty(String key);
 
 	/**
-	 * Returns an array of the keys in the properties <code>Dictionary</code>
-	 * object of the service referenced by this <code>ServiceReference</code>
+	 * Returns an array of the keys in the properties {@code Dictionary}
+	 * object of the service referenced by this {@code ServiceReference}
 	 * object.
 	 * 
 	 * <p>
 	 * This method will continue to return the keys after the service has been
 	 * unregistered. This is so references to unregistered services (for
-	 * example, <code>ServiceReference</code> objects stored in the log) can
+	 * example, {@code ServiceReference} objects stored in the log) can
 	 * still be interrogated.
 	 * 
 	 * <p>
 	 * This method is <i>case-preserving </i>; this means that every key in the
 	 * returned array must have the same case as the corresponding key in the
-	 * properties <code>Dictionary</code> that was passed to the
+	 * properties {@code Dictionary} that was passed to the
 	 * {@link BundleContext#registerService(String[],Object,Dictionary)} or
 	 * {@link ServiceRegistration#setProperties} methods.
 	 * 
@@ -94,15 +96,15 @@
 
 	/**
 	 * Returns the bundle that registered the service referenced by this
-	 * <code>ServiceReference</code> object.
+	 * {@code ServiceReference} object.
 	 * 
 	 * <p>
-	 * This method must return <code>null</code> when the service has been
+	 * This method must return {@code null} when the service has been
 	 * unregistered. This can be used to determine if the service has been
 	 * unregistered.
 	 * 
 	 * @return The bundle that registered the service referenced by this
-	 *         <code>ServiceReference</code> object; <code>null</code> if that
+	 *         {@code ServiceReference} object; {@code null} if that
 	 *         service has already been unregistered.
 	 * @see BundleContext#registerService(String[],Object,Dictionary)
 	 */
@@ -110,12 +112,12 @@
 
 	/**
 	 * Returns the bundles that are using the service referenced by this
-	 * <code>ServiceReference</code> object. Specifically, this method returns
+	 * {@code ServiceReference} object. Specifically, this method returns
 	 * the bundles whose usage count for that service is greater than zero.
 	 * 
 	 * @return An array of bundles whose usage count for the service referenced
-	 *         by this <code>ServiceReference</code> object is greater than
-	 *         zero; <code>null</code> if no bundles are currently using that
+	 *         by this {@code ServiceReference} object is greater than
+	 *         zero; {@code null} if no bundles are currently using that
 	 *         service.
 	 * 
 	 * @since 1.1
@@ -124,60 +126,60 @@
 
 	/**
 	 * Tests if the bundle that registered the service referenced by this
-	 * <code>ServiceReference</code> and the specified bundle use the same
+	 * {@code ServiceReference} and the specified bundle use the same
 	 * source for the package of the specified class name.
 	 * <p>
 	 * This method performs the following checks:
 	 * <ol>
 	 * <li>Get the package name from the specified class name.</li>
 	 * <li>For the bundle that registered the service referenced by this
-	 * <code>ServiceReference</code> (registrant bundle); find the source for
-	 * the package. If no source is found then return <code>true</code> if the
+	 * {@code ServiceReference} (registrant bundle); find the source for
+	 * the package. If no source is found then return {@code true} if the
 	 * registrant bundle is equal to the specified bundle; otherwise return
-	 * <code>false</code>.</li>
+	 * {@code false}.</li>
 	 * <li>If the package source of the registrant bundle is equal to the
-	 * package source of the specified bundle then return <code>true</code>;
-	 * otherwise return <code>false</code>.</li>
+	 * package source of the specified bundle then return {@code true};
+	 * otherwise return {@code false}.</li>
 	 * </ol>
 	 * 
-	 * @param bundle The <code>Bundle</code> object to check.
+	 * @param bundle The {@code Bundle} object to check.
 	 * @param className The class name to check.
-	 * @return <code>true</code> if the bundle which registered the service
-	 *         referenced by this <code>ServiceReference</code> and the
+	 * @return {@code true} if the bundle which registered the service
+	 *         referenced by this {@code ServiceReference} and the
 	 *         specified bundle use the same source for the package of the
-	 *         specified class name. Otherwise <code>false</code> is returned.
-	 * @throws IllegalArgumentException If the specified <code>Bundle</code> was
+	 *         specified class name. Otherwise {@code false} is returned.
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was
 	 *         not created by the same framework instance as this
-	 *         <code>ServiceReference</code>.
+	 *         {@code ServiceReference}.
 	 * @since 1.3
 	 */
 	public boolean isAssignableTo(Bundle bundle, String className);
 
 	/**
-	 * Compares this <code>ServiceReference</code> with the specified
-	 * <code>ServiceReference</code> for order.
+	 * Compares this {@code ServiceReference} with the specified
+	 * {@code ServiceReference} for order.
 	 * 
 	 * <p>
-	 * If this <code>ServiceReference</code> and the specified
-	 * <code>ServiceReference</code> have the same {@link Constants#SERVICE_ID
-	 * service id} they are equal. This <code>ServiceReference</code> is less
-	 * than the specified <code>ServiceReference</code> if it has a lower
+	 * If this {@code ServiceReference} and the specified
+	 * {@code ServiceReference} have the same {@link Constants#SERVICE_ID
+	 * service id} they are equal. This {@code ServiceReference} is less
+	 * than the specified {@code ServiceReference} if it has a lower
 	 * {@link Constants#SERVICE_RANKING service ranking} and greater if it has a
-	 * higher service ranking. Otherwise, if this <code>ServiceReference</code>
-	 * and the specified <code>ServiceReference</code> have the same
+	 * higher service ranking. Otherwise, if this {@code ServiceReference}
+	 * and the specified {@code ServiceReference} have the same
 	 * {@link Constants#SERVICE_RANKING service ranking}, this
-	 * <code>ServiceReference</code> is less than the specified
-	 * <code>ServiceReference</code> if it has a higher
+	 * {@code ServiceReference} is less than the specified
+	 * {@code ServiceReference} if it has a higher
 	 * {@link Constants#SERVICE_ID service id} and greater if it has a lower
 	 * service id.
 	 * 
-	 * @param reference The <code>ServiceReference</code> to be compared.
+	 * @param reference The {@code ServiceReference} to be compared.
 	 * @return Returns a negative integer, zero, or a positive integer if this
-	 *         <code>ServiceReference</code> is less than, equal to, or greater
-	 *         than the specified <code>ServiceReference</code>.
+	 *         {@code ServiceReference} is less than, equal to, or greater
+	 *         than the specified {@code ServiceReference}.
 	 * @throws IllegalArgumentException If the specified
-	 *         <code>ServiceReference</code> was not created by the same
-	 *         framework instance as this <code>ServiceReference</code>.
+	 *         {@code ServiceReference} was not created by the same
+	 *         framework instance as this {@code ServiceReference}.
 	 * @since 1.4
 	 */
 	public int compareTo(Object reference);
diff --git a/framework/src/main/java/org/osgi/framework/ServiceRegistration.java b/framework/src/main/java/org/osgi/framework/ServiceRegistration.java
index 9186cf7..e4cfc0e 100644
--- a/framework/src/main/java/org/osgi/framework/ServiceRegistration.java
+++ b/framework/src/main/java/org/osgi/framework/ServiceRegistration.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2000, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,33 +22,35 @@
  * A registered service.
  * 
  * <p>
- * The Framework returns a <code>ServiceRegistration</code> object when a
- * <code>BundleContext.registerService</code> method invocation is successful.
- * The <code>ServiceRegistration</code> object is for the private use of the
+ * The Framework returns a {@code ServiceRegistration} object when a
+ * {@code BundleContext.registerService} method invocation is successful.
+ * The {@code ServiceRegistration} object is for the private use of the
  * registering bundle and should not be shared with other bundles.
  * <p>
- * The <code>ServiceRegistration</code> object may be used to update the
+ * The {@code ServiceRegistration} object may be used to update the
  * properties of the service or to unregister the service.
  * 
+ * @param <S> Type of Service.
  * @see BundleContext#registerService(String[],Object,Dictionary)
  * @ThreadSafe
- * @version $Revision: 6361 $
+ * @noimplement
+ * @version $Id: dc742ff3749821529f9ae62e05d9bd5d8eca00d7 $
  */
 
-public interface ServiceRegistration {
+public interface ServiceRegistration<S> {
 	/**
-	 * Returns a <code>ServiceReference</code> object for a service being
+	 * Returns a {@code ServiceReference} object for a service being
 	 * registered.
 	 * <p>
-	 * The <code>ServiceReference</code> object may be shared with other
+	 * The {@code ServiceReference} object may be shared with other
 	 * bundles.
 	 * 
 	 * @throws IllegalStateException If this
-	 *         <code>ServiceRegistration</code> object has already been
+	 *         {@code ServiceRegistration} object has already been
 	 *         unregistered.
-	 * @return <code>ServiceReference</code> object.
+	 * @return {@code ServiceReference} object.
 	 */
-	public ServiceReference getReference();
+	public ServiceReference<S> getReference();
 
 	/**
 	 * Updates the properties associated with a service.
@@ -70,17 +72,17 @@
 	 *        be made to this object after calling this method. To update the
 	 *        service's properties this method should be called again.
 	 * 
-	 * @throws IllegalStateException If this <code>ServiceRegistration</code>
+	 * @throws IllegalStateException If this {@code ServiceRegistration}
 	 *         object has already been unregistered.
-	 * @throws IllegalArgumentException If <code>properties</code> contains
+	 * @throws IllegalArgumentException If {@code properties} contains
 	 *         case variants of the same key name.
 	 */
-	public void setProperties(Dictionary properties);
+	public void setProperties(Dictionary<String, ? > properties);
 
 	/**
-	 * Unregisters a service. Remove a <code>ServiceRegistration</code> object
-	 * from the Framework service registry. All <code>ServiceReference</code>
-	 * objects associated with this <code>ServiceRegistration</code> object
+	 * Unregisters a service. Remove a {@code ServiceRegistration} object
+	 * from the Framework service registry. All {@code ServiceReference}
+	 * objects associated with this {@code ServiceRegistration} object
 	 * can no longer be used to interact with the service once unregistration is
 	 * complete.
 	 * 
@@ -92,18 +94,18 @@
 	 * <li>A service event of type {@link ServiceEvent#UNREGISTERING} is fired
 	 * so that bundles using this service can release their use of the service.
 	 * Once delivery of the service event is complete, the
-	 * <code>ServiceReference</code> objects for the service may no longer be
+	 * {@code ServiceReference} objects for the service may no longer be
 	 * used to get a service object for the service.
 	 * <li>For each bundle whose use count for this service is greater than
 	 * zero: <br>
 	 * The bundle's use count for this service is set to zero. <br>
 	 * If the service was registered with a {@link ServiceFactory} object, the
-	 * <code>ServiceFactory.ungetService</code> method is called to release
+	 * {@code ServiceFactory.ungetService} method is called to release
 	 * the service object for the bundle.
 	 * </ol>
 	 * 
 	 * @throws IllegalStateException If this
-	 *         <code>ServiceRegistration</code> object has already been
+	 *         {@code ServiceRegistration} object has already been
 	 *         unregistered.
 	 * @see BundleContext#ungetService
 	 * @see ServiceFactory#ungetService
diff --git a/framework/src/main/java/org/osgi/framework/SignerProperty.java b/framework/src/main/java/org/osgi/framework/SignerProperty.java
index 2ba0389..8b357c1 100644
--- a/framework/src/main/java/org/osgi/framework/SignerProperty.java
+++ b/framework/src/main/java/org/osgi/framework/SignerProperty.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2009, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@
 
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
@@ -27,9 +26,9 @@
  * during filter expression evaluation in the permission implies method.
  * 
  * @Immutable
- * @version $Revision: 6479 $
+ * @version $Id: 3589831a7594cf36e645a51ab9b9ae5ebfd80beb $
  */
-class SignerProperty {
+final class SignerProperty {
 	private final Bundle	bundle;
 	private final String	pattern;
 
@@ -71,19 +70,21 @@
 		SignerProperty other = (SignerProperty) o;
 		Bundle matchBundle = bundle != null ? bundle : other.bundle;
 		String matchPattern = bundle != null ? other.pattern : pattern;
-		Map/* <X509Certificate, List<X509Certificate>> */signers = matchBundle
+		Map<X509Certificate, List<X509Certificate>> signers = matchBundle
 				.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
-		for (Iterator iSigners = signers.values().iterator(); iSigners
-				.hasNext();) {
-			List/* <X509Certificate> */signerCerts = (List) iSigners.next();
-			List/* <String> */dnChain = new ArrayList(signerCerts.size());
-			for (Iterator iCerts = signerCerts.iterator(); iCerts.hasNext();) {
-				dnChain.add(((X509Certificate) iCerts.next()).getSubjectDN()
-						.getName());
+		for (List<X509Certificate> signerCerts : signers.values()) {
+			List<String> dnChain = new ArrayList<String>(signerCerts.size());
+			for (X509Certificate signerCert : signerCerts) {
+				dnChain.add(signerCert.getSubjectDN().getName());
 			}
-			if (FrameworkUtil
-					.matchDistinguishedNameChain(matchPattern, dnChain)) {
-				return true;
+			try {
+				if (FrameworkUtil.matchDistinguishedNameChain(matchPattern,
+						dnChain)) {
+					return true;
+				}
+			}
+			catch (IllegalArgumentException e) {
+				continue; // bad pattern
 			}
 		}
 		return false;
@@ -106,7 +107,7 @@
 		if (bundle == null) {
 			return false;
 		}
-		Map/* <X509Certificate, List<X509Certificate>> */signers = bundle
+		Map<X509Certificate, List<X509Certificate>> signers = bundle
 				.getSignerCertificates(Bundle.SIGNERS_TRUSTED);
 		return !signers.isEmpty();
 	}
diff --git a/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java b/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java
index 9104f04..227dc59 100644
--- a/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java
+++ b/framework/src/main/java/org/osgi/framework/SynchronousBundleListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,35 +17,48 @@
 package org.osgi.framework;
 
 /**
- * A synchronous <code>BundleEvent</code> listener.
- * <code>SynchronousBundleListener</code> is a listener interface that may be
- * implemented by a bundle developer. When a <code>BundleEvent</code> is
- * fired, it is synchronously delivered to a
- * <code>SynchronousBundleListener</code>. The Framework may deliver
- * <code>BundleEvent</code> objects to a
- * <code>SynchronousBundleListener</code> out of order and may concurrently
- * call and/or reenter a <code>SynchronousBundleListener</code>.
+ * A synchronous {@code BundleEvent} listener.
+ * {@code SynchronousBundleListener} is a listener interface that may be
+ * implemented by a bundle developer. When a {@code BundleEvent} is fired,
+ * it is synchronously delivered to a {@code SynchronousBundleListener}.
+ * The Framework may deliver {@code BundleEvent} objects to a
+ * {@code SynchronousBundleListener} out of order and may concurrently call
+ * and/or reenter a {@code SynchronousBundleListener}.
+ * 
  * <p>
- * A <code>SynchronousBundleListener</code> object is registered with the
+ * For {@code BundleEvent} types {@link BundleEvent#STARTED STARTED} and
+ * {@link BundleEvent#LAZY_ACTIVATION LAZY_ACTIVATION}, the Framework must not
+ * hold the referenced bundle's &quot;state change&quot; lock when the
+ * {@code BundleEvent} is delivered to a
+ * {@code SynchronousBundleListener}. For the other
+ * {@code BundleEvent} types, the Framework must hold the referenced
+ * bundle's &quot;state change&quot; lock when the {@code BundleEvent} is
+ * delivered to a {@code SynchronousBundleListener}. A
+ * {@code SynchronousBundleListener} cannot directly call life cycle
+ * methods on the referenced bundle when the Framework is holding the referenced
+ * bundle's &quot;state change&quot; lock.
+ * 
+ * <p>
+ * A {@code SynchronousBundleListener} object is registered with the
  * Framework using the {@link BundleContext#addBundleListener} method.
- * <code>SynchronousBundleListener</code> objects are called with a
- * <code>BundleEvent</code> object when a bundle has been installed, resolved,
+ * {@code SynchronousBundleListener} objects are called with a
+ * {@code BundleEvent} object when a bundle has been installed, resolved,
  * starting, started, stopping, stopped, updated, unresolved, or uninstalled.
  * <p>
- * Unlike normal <code>BundleListener</code> objects,
- * <code>SynchronousBundleListener</code>s are synchronously called during
+ * Unlike normal {@code BundleListener} objects,
+ * {@code SynchronousBundleListener}s are synchronously called during
  * bundle lifecycle processing. The bundle lifecycle processing will not proceed
- * until all <code>SynchronousBundleListener</code>s have completed.
- * <code>SynchronousBundleListener</code> objects will be called prior to
- * <code>BundleListener</code> objects.
+ * until all {@code SynchronousBundleListener}s have completed.
+ * {@code SynchronousBundleListener} objects will be called prior to
+ * {@code BundleListener} objects.
  * <p>
- * <code>AdminPermission[bundle,LISTENER]</code> is required to add or remove
- * a <code>SynchronousBundleListener</code> object.
+ * {@code AdminPermission[bundle,LISTENER]} is required to add or remove a
+ * {@code SynchronousBundleListener} object.
  * 
  * @since 1.1
  * @see BundleEvent
  * @ThreadSafe
- * @version $Revision: 5673 $
+ * @version $Id: b22484f48ebdcb2141da9bba9eb65f5c40e0f520 $
  */
 
 public interface SynchronousBundleListener extends BundleListener {
diff --git a/framework/src/main/java/org/osgi/framework/Version.java b/framework/src/main/java/org/osgi/framework/Version.java
index 7317495..fd2484e 100644
--- a/framework/src/main/java/org/osgi/framework/Version.java
+++ b/framework/src/main/java/org/osgi/framework/Version.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2010). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,24 +28,25 @@
  * <li>Major version. A non-negative integer.</li>
  * <li>Minor version. A non-negative integer.</li>
  * <li>Micro version. A non-negative integer.</li>
- * <li>Qualifier. A text string. See <code>Version(String)</code> for the
+ * <li>Qualifier. A text string. See {@code Version(String)} for the
  * format of the qualifier string.</li>
  * </ol>
  * 
  * <p>
- * <code>Version</code> objects are immutable.
+ * {@code Version} objects are immutable.
  * 
  * @since 1.3
  * @Immutable
- * @version $Revision: 6860 $
+ * @version $Id: a71e2e2d7685e65b5bbe375efdf97fda16eff0a5 $
  */
 
-public class Version implements Comparable {
+public class Version implements Comparable<Version> {
 	private final int			major;
 	private final int			minor;
 	private final int			micro;
 	private final String		qualifier;
-	private static final String	SEPARATOR		= ".";					//$NON-NLS-1$
+	private static final String	SEPARATOR		= ".";
+	private transient String	versionString;
 
 	/**
 	 * The empty version "0.0.0".
@@ -75,20 +76,21 @@
 	 * @param minor Minor component of the version identifier.
 	 * @param micro Micro component of the version identifier.
 	 * @param qualifier Qualifier component of the version identifier. If
-	 *        <code>null</code> is specified, then the qualifier will be set to
+	 *        {@code null} is specified, then the qualifier will be set to
 	 *        the empty string.
 	 * @throws IllegalArgumentException If the numerical components are negative
 	 *         or the qualifier string is invalid.
 	 */
 	public Version(int major, int minor, int micro, String qualifier) {
 		if (qualifier == null) {
-			qualifier = ""; //$NON-NLS-1$
+			qualifier = "";
 		}
 
 		this.major = major;
 		this.minor = minor;
 		this.micro = micro;
 		this.qualifier = qualifier;
+		versionString = null;
 		validate();
 	}
 
@@ -111,46 +113,51 @@
 	 * There must be no whitespace in version.
 	 * 
 	 * @param version String representation of the version identifier.
-	 * @throws IllegalArgumentException If <code>version</code> is improperly
+	 * @throws IllegalArgumentException If {@code version} is improperly
 	 *         formatted.
 	 */
 	public Version(String version) {
 		int maj = 0;
 		int min = 0;
 		int mic = 0;
-		String qual = ""; //$NON-NLS-1$
+		String qual = "";
 
 		try {
 			StringTokenizer st = new StringTokenizer(version, SEPARATOR, true);
 			maj = Integer.parseInt(st.nextToken());
 
-			if (st.hasMoreTokens()) {
+			if (st.hasMoreTokens()) { // minor
 				st.nextToken(); // consume delimiter
 				min = Integer.parseInt(st.nextToken());
 
-				if (st.hasMoreTokens()) {
+				if (st.hasMoreTokens()) { // micro
 					st.nextToken(); // consume delimiter
 					mic = Integer.parseInt(st.nextToken());
 
-					if (st.hasMoreTokens()) {
+					if (st.hasMoreTokens()) { // qualifier
 						st.nextToken(); // consume delimiter
-						qual = st.nextToken();
+						qual = st.nextToken(""); // remaining string
 
-						if (st.hasMoreTokens()) {
-							throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
+						if (st.hasMoreTokens()) { // fail safe
+							throw new IllegalArgumentException(
+									"invalid format: " + version);
 						}
 					}
 				}
 			}
 		}
 		catch (NoSuchElementException e) {
-			throw new IllegalArgumentException("invalid format"); //$NON-NLS-1$
+			IllegalArgumentException iae = new IllegalArgumentException(
+					"invalid format: " + version);
+			iae.initCause(e);
+			throw iae;
 		}
 
 		major = maj;
 		minor = min;
 		micro = mic;
 		qualifier = qual;
+		versionString = null;
 		validate();
 	}
 
@@ -162,13 +169,13 @@
 	 */
 	private void validate() {
 		if (major < 0) {
-			throw new IllegalArgumentException("negative major"); //$NON-NLS-1$
+			throw new IllegalArgumentException("negative major");
 		}
 		if (minor < 0) {
-			throw new IllegalArgumentException("negative minor"); //$NON-NLS-1$
+			throw new IllegalArgumentException("negative minor");
 		}
 		if (micro < 0) {
-			throw new IllegalArgumentException("negative micro"); //$NON-NLS-1$
+			throw new IllegalArgumentException("negative micro");
 		}
 		char[] chars = qualifier.toCharArray();
 		for (int i = 0, length = chars.length; i < length; i++) {
@@ -185,8 +192,8 @@
 			if ((ch == '_') || (ch == '-')) {
 				continue;
 			}
-			throw new IllegalArgumentException(
-					"invalid qualifier: " + qualifier); //$NON-NLS-1$
+			throw new IllegalArgumentException("invalid qualifier: "
+					+ qualifier);
 		}
 	}
 
@@ -194,15 +201,15 @@
 	 * Parses a version identifier from the specified string.
 	 * 
 	 * <p>
-	 * See <code>Version(String)</code> for the format of the version string.
+	 * See {@code Version(String)} for the format of the version string.
 	 * 
 	 * @param version String representation of the version identifier. Leading
 	 *        and trailing whitespace will be ignored.
-	 * @return A <code>Version</code> object representing the version
-	 *         identifier. If <code>version</code> is <code>null</code> or
-	 *         the empty string then <code>emptyVersion</code> will be
+	 * @return A {@code Version} object representing the version
+	 *         identifier. If {@code version} is {@code null} or
+	 *         the empty string then {@code emptyVersion} will be
 	 *         returned.
-	 * @throws IllegalArgumentException If <code>version</code> is improperly
+	 * @throws IllegalArgumentException If {@code version} is improperly
 	 *         formatted.
 	 */
 	public static Version parseVersion(String version) {
@@ -258,13 +265,16 @@
 	 * Returns the string representation of this version identifier.
 	 * 
 	 * <p>
-	 * The format of the version string will be <code>major.minor.micro</code>
+	 * The format of the version string will be {@code major.minor.micro}
 	 * if qualifier is the empty string or
-	 * <code>major.minor.micro.qualifier</code> otherwise.
+	 * {@code major.minor.micro.qualifier} otherwise.
 	 * 
 	 * @return The string representation of this version identifier.
 	 */
 	public String toString() {
+		if (versionString != null) {
+			return versionString;
+		}
 		int q = qualifier.length();
 		StringBuffer result = new StringBuffer(20 + q);
 		result.append(major);
@@ -276,7 +286,7 @@
 			result.append(SEPARATOR);
 			result.append(qualifier);
 		}
-		return result.toString();
+		return versionString = result.toString();
 	}
 
 	/**
@@ -290,17 +300,17 @@
 	}
 
 	/**
-	 * Compares this <code>Version</code> object to another object.
+	 * Compares this {@code Version} object to another object.
 	 * 
 	 * <p>
 	 * A version is considered to be <b>equal to </b> another version if the
 	 * major, minor and micro components are equal and the qualifier component
-	 * is equal (using <code>String.equals</code>).
+	 * is equal (using {@code String.equals}).
 	 * 
-	 * @param object The <code>Version</code> object to be compared.
-	 * @return <code>true</code> if <code>object</code> is a
-	 *         <code>Version</code> and is equal to this object;
-	 *         <code>false</code> otherwise.
+	 * @param object The {@code Version} object to be compared.
+	 * @return {@code true} if {@code object} is a
+	 *         {@code Version} and is equal to this object;
+	 *         {@code false} otherwise.
 	 */
 	public boolean equals(Object object) {
 		if (object == this) { // quicktest
@@ -317,7 +327,7 @@
 	}
 
 	/**
-	 * Compares this <code>Version</code> object to another object.
+	 * Compares this {@code Version} object to another {@code Version}.
 	 * 
 	 * <p>
 	 * A version is considered to be <b>less than </b> another version if its
@@ -327,27 +337,25 @@
 	 * and its micro component is less than the other version's micro component,
 	 * or the major, minor and micro components are equal and it's qualifier
 	 * component is less than the other version's qualifier component (using
-	 * <code>String.compareTo</code>).
+	 * {@code String.compareTo}).
 	 * 
 	 * <p>
 	 * A version is considered to be <b>equal to</b> another version if the
 	 * major, minor and micro components are equal and the qualifier component
-	 * is equal (using <code>String.compareTo</code>).
+	 * is equal (using {@code String.compareTo}).
 	 * 
-	 * @param object The <code>Version</code> object to be compared.
-	 * @return A negative integer, zero, or a positive integer if this object is
-	 *         less than, equal to, or greater than the specified
-	 *         <code>Version</code> object.
+	 * @param other The {@code Version} object to be compared.
+	 * @return A negative integer, zero, or a positive integer if this version
+	 *         is less than, equal to, or greater than the specified
+	 *         {@code Version} object.
 	 * @throws ClassCastException If the specified object is not a
-	 *         <code>Version</code>.
+	 *         {@code Version} object.
 	 */
-	public int compareTo(Object object) {
-		if (object == this) { // quicktest
+	public int compareTo(Version other) {
+		if (other == this) { // quicktest
 			return 0;
 		}
 
-		Version other = (Version) object;
-
 		int result = major - other.major;
 		if (result != 0) {
 			return result;
diff --git a/framework/src/main/java/org/osgi/framework/startlevel/BundleStartLevel.java b/framework/src/main/java/org/osgi/framework/startlevel/BundleStartLevel.java
new file mode 100644
index 0000000..d22d3ef
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/startlevel/BundleStartLevel.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) OSGi Alliance (2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.startlevel;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+
+/**
+ * Query and modify the start level information for a bundle. The start level
+ * object for a bundle can be obtained by calling {@link Bundle#adapt(Class)
+ * bundle.adapt(BundleStartLevel.class)} on the bundle.
+ * 
+ * <p>
+ * The bundle associated with this BundleStartLevel object can be obtained by
+ * calling {@link BundleReference#getBundle()}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 9a000be191fe3cb4ae82535a30940db0340d5356 $
+ */
+public interface BundleStartLevel extends BundleReference {
+	/**
+	 * Return the assigned start level value for the bundle.
+	 * 
+	 * @return The start level value of the bundle.
+	 * @see #setStartLevel(int)
+	 * @throws IllegalStateException If the bundle has been uninstalled.
+	 */
+	int getStartLevel();
+
+	/**
+	 * Assign a start level value to the bundle.
+	 * 
+	 * <p>
+	 * The bundle will be assigned the specified start level. The start level
+	 * value assigned to the bundle will be persistently recorded by the
+	 * Framework.
+	 * <p>
+	 * If the new start level for the bundle is lower than or equal to the
+	 * active start level of the Framework and the bundle's autostart setting
+	 * indicates this bundle must be started, the Framework will start the
+	 * bundle as described in the {@link Bundle#start(int)} method using the
+	 * {@link Bundle#START_TRANSIENT} option. The
+	 * {@link Bundle#START_ACTIVATION_POLICY} option must also be used if
+	 * {@link #isActivationPolicyUsed()} returns {@code true}. The actual
+	 * starting of the bundle must occur asynchronously.
+	 * <p>
+	 * If the new start level for the bundle is higher than the active start
+	 * level of the Framework, the Framework will stop the bundle as described
+	 * in the {@link Bundle#stop(int)} method using the
+	 * {@link Bundle#STOP_TRANSIENT} option. The actual stopping of the bundle
+	 * must occur asynchronously.
+	 * 
+	 * @param startlevel The new start level for the bundle.
+	 * @throws IllegalArgumentException If the specified start level is less
+	 *         than or equal to zero, or if the bundle is the system bundle.
+	 * @throws IllegalStateException If the bundle has been uninstalled.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[bundle,EXECUTE]} and the Java runtime
+	 *         environment supports permissions.
+	 */
+	void setStartLevel(int startlevel);
+
+	/**
+	 * Returns whether the bundle's autostart setting indicates it must be
+	 * started.
+	 * <p>
+	 * The autostart setting of a bundle indicates whether the bundle is to be
+	 * started when its start level is reached.
+	 * 
+	 * @return {@code true} if the autostart setting of the bundle indicates it
+	 *         is to be started. {@code false} otherwise.
+	 * @throws IllegalStateException If this bundle has been uninstalled.
+	 * @see Bundle#START_TRANSIENT
+	 */
+	boolean isPersistentlyStarted();
+
+	/**
+	 * Returns whether the bundle's autostart setting indicates that the
+	 * activation policy declared in the bundle manifest must be used.
+	 * <p>
+	 * The autostart setting of a bundle indicates whether the bundle's declared
+	 * activation policy is to be used when the bundle is started.
+	 * 
+	 * @return {@code true} if the bundle's autostart setting indicates the
+	 *         activation policy declared in the manifest must be used.
+	 *         {@code false} if the bundle must be eagerly activated.
+	 * @throws IllegalStateException If the bundle has been uninstalled.
+	 * @see Bundle#START_ACTIVATION_POLICY
+	 */
+	boolean isActivationPolicyUsed();
+}
diff --git a/framework/src/main/java/org/osgi/framework/startlevel/FrameworkStartLevel.java b/framework/src/main/java/org/osgi/framework/startlevel/FrameworkStartLevel.java
new file mode 100644
index 0000000..adb51ec
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/startlevel/FrameworkStartLevel.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) OSGi Alliance (2002, 2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.startlevel;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+import org.osgi.framework.FrameworkListener;
+
+/**
+ * Query and modify the start level information for the framework. The start
+ * level object for the framework can be obtained by calling
+ * {@link Bundle#adapt(Class) bundle.adapt(FrameworkStartLevel.class)} on the
+ * system bundle. Only the system bundle can be adapted to a FrameworkStartLevel
+ * object.
+ * 
+ * <p>
+ * The system bundle associated with this FrameworkStartLevel object can be
+ * obtained by calling {@link BundleReference#getBundle()}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 2bca22671674ba50b8c6801d5d1df8e291fe2a9d $
+ */
+public interface FrameworkStartLevel extends BundleReference {
+	/**
+	 * Return the active start level value of the Framework.
+	 * 
+	 * If the Framework is in the process of changing the start level this
+	 * method must return the active start level if this differs from the
+	 * requested start level.
+	 * 
+	 * @return The active start level value of the Framework.
+	 */
+	int getStartLevel();
+
+	/**
+	 * Modify the active start level of the Framework and notify when complete.
+	 * 
+	 * <p>
+	 * The Framework will move to the requested start level. This method will
+	 * return immediately to the caller and the start level change will occur
+	 * asynchronously on another thread. The specified {@code FrameworkListener}
+	 * s are notified, in the order specified, when the start level change is
+	 * complete. When the start level change completes normally, each specified
+	 * {@code FrameworkListener} will be called with a Framework event of type
+	 * {@code FrameworkEvent.STARTLEVEL_CHANGED}. If the start level change does
+	 * not complete normally, each specified {@code FrameworkListener} will be
+	 * called with a Framework event of type {@code FrameworkEvent.ERROR}.
+	 * 
+	 * <p>
+	 * If the specified start level is higher than the active start level, the
+	 * Framework will continue to increase the start level until the Framework
+	 * has reached the specified start level.
+	 * 
+	 * At each intermediate start level value on the way to and including the
+	 * target start level, the Framework must:
+	 * <ol>
+	 * <li>Change the active start level to the intermediate start level value.
+	 * <li>Start bundles at the intermediate start level whose autostart setting
+	 * indicate they must be started. They are started as described in the
+	 * {@link Bundle#start(int)} method using the {@link Bundle#START_TRANSIENT}
+	 * option. The {@link Bundle#START_ACTIVATION_POLICY} option must also be
+	 * used if {@link BundleStartLevel#isActivationPolicyUsed()} returns
+	 * {@code true} for the bundle.
+	 * </ol>
+	 * When this process completes after the specified start level is reached,
+	 * the Framework will fire a Framework event of type
+	 * {@code FrameworkEvent.STARTLEVEL_CHANGED} to announce it has moved to the
+	 * specified start level.
+	 * 
+	 * <p>
+	 * If the specified start level is lower than the active start level, the
+	 * Framework will continue to decrease the start level until the Framework
+	 * has reached the specified start level.
+	 * 
+	 * At each intermediate start level value on the way to and including the
+	 * specified start level, the framework must:
+	 * <ol>
+	 * <li>Stop bundles at the intermediate start level as described in the
+	 * {@link Bundle#stop(int)} method using the {@link Bundle#STOP_TRANSIENT}
+	 * option.
+	 * <li>Change the active start level to the intermediate start level value.
+	 * </ol>
+	 * When this process completes after the specified start level is reached,
+	 * the Framework will fire a Framework event of type
+	 * {@code FrameworkEvent.STARTLEVEL_CHANGED} to announce it has moved to the
+	 * specified start level.
+	 * 
+	 * <p>
+	 * If the specified start level is equal to the active start level, then no
+	 * bundles are started or stopped, however, the Framework must fire a
+	 * Framework event of type {@code FrameworkEvent.STARTLEVEL_CHANGED} to
+	 * announce it has finished moving to the specified start level. This event
+	 * may arrive before this method returns.
+	 * 
+	 * @param startlevel The requested start level for the Framework.
+	 * @param listeners Zero or more listeners to be notified when the start
+	 *        level change has been completed. The specified listeners do not
+	 *        need to be otherwise registered with the framework. If a specified
+	 *        listener is already registered with the framework, it will be
+	 *        notified twice.
+	 * @throws IllegalArgumentException If the specified start level is less
+	 *         than or equal to zero.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,STARTLEVEL]} and the Java
+	 *         runtime environment supports permissions.
+	 */
+	void setStartLevel(int startlevel, FrameworkListener... listeners);
+
+	/**
+	 * Return the initial start level value that is assigned to a Bundle when it
+	 * is first installed.
+	 * 
+	 * @return The initial start level value for Bundles.
+	 * @see #setInitialBundleStartLevel
+	 */
+	int getInitialBundleStartLevel();
+
+	/**
+	 * Set the initial start level value that is assigned to a Bundle when it is
+	 * first installed.
+	 * 
+	 * <p>
+	 * The initial bundle start level will be set to the specified start level.
+	 * The initial bundle start level value will be persistently recorded by the
+	 * Framework.
+	 * 
+	 * <p>
+	 * When a Bundle is installed via {@code BundleContext.installBundle}, it is
+	 * assigned the initial bundle start level value.
+	 * 
+	 * <p>
+	 * The default initial bundle start level value is 1 unless this method has
+	 * been called to assign a different initial bundle start level value.
+	 * 
+	 * <p>
+	 * This method does not change the start level values of installed bundles.
+	 * 
+	 * @param startlevel The initial start level for newly installed bundles.
+	 * @throws IllegalArgumentException If the specified start level is less
+	 *         than or equal to zero.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,STARTLEVEL]} and the Java
+	 *         runtime environment supports permissions.
+	 */
+	void setInitialBundleStartLevel(int startlevel);
+}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/BundleRevisions.java b/framework/src/main/java/org/osgi/framework/wiring/BundleRevisions.java
new file mode 100644
index 0000000..a619dbb
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/wiring/BundleRevisions.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) OSGi Alliance (2011). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.util.List;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+
+/**
+ * The {@link BundleRevision bundle revisions} of a bundle. When a bundle is
+ * installed and each time a bundle is updated, a new bundle revision of the
+ * bundle is created. For a bundle that has not been uninstalled, the most
+ * recent bundle revision is defined to be the current bundle revision. A bundle
+ * in the UNINSTALLED state does not have a current revision. An in use bundle
+ * revision is associated with an {@link BundleWiring#isInUse() in use}
+ * {@link BundleWiring}. The current bundle revision, if there is one, and all
+ * in use bundle revisions are returned.
+ * 
+ * <p>
+ * The bundle revisions for a bundle can be obtained by calling
+ * {@link Bundle#adapt(Class) bundle.adapt}({@link BundleRevisions}.class).
+ * {@link #getRevisions()} on the bundle.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: 1d95ad10f0f08b100f8ee2485bdd34120032c7af $
+ */
+public interface BundleRevisions extends BundleReference {
+	/**
+	 * Return the bundle revisions for the {@link BundleReference#getBundle()
+	 * referenced} bundle.
+	 * 
+	 * <p>
+	 * The result is a list containing the current bundle revision, if there is
+	 * one, and all in use bundle revisions. The list may also contain
+	 * intermediate bundle revisions which are not in use.
+	 * 
+	 * <p>
+	 * The list is ordered in reverse chronological order such that the first
+	 * item is the most recent bundle revision and last item is the oldest
+	 * bundle revision.
+	 * 
+	 * <p>
+	 * Generally the list will have at least one bundle revision for the bundle:
+	 * the current bundle revision. However, for an uninstalled bundle with no
+	 * in use bundle revisions, the list may be empty.
+	 * 
+	 * @return A list containing a snapshot of the {@link BundleRevision}s for
+	 *         the referenced bundle.
+	 */
+	List<BundleRevision> getRevisions();
+}
diff --git a/framework/src/main/java/org/osgi/framework/wiring/FrameworkWiring.java b/framework/src/main/java/org/osgi/framework/wiring/FrameworkWiring.java
new file mode 100644
index 0000000..046a6c2
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/wiring/FrameworkWiring.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) OSGi Alliance (2001, 2010). All Rights Reserved.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.osgi.framework.wiring;
+
+import java.util.Collection;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleReference;
+import org.osgi.framework.FrameworkListener;
+
+/**
+ * Query and modify wiring information for the framework. The framework wiring
+ * object for the framework can be obtained by calling
+ * {@link Bundle#adapt(Class) bundle.adapt(FrameworkWiring.class)} on the system
+ * bundle. Only the system bundle can be adapted to a FrameworkWiring object.
+ * 
+ * <p>
+ * The system bundle associated with this FrameworkWiring object can be obtained
+ * by calling {@link BundleReference#getBundle()}.
+ * 
+ * @ThreadSafe
+ * @noimplement
+ * @version $Id: f9f3f89b5b8d369453d645a52a482a385a2bd520 $
+ */
+public interface FrameworkWiring extends BundleReference {
+	/**
+	 * Refreshes the specified bundles. This forces the update (replacement) or
+	 * removal of packages exported by the specified bundles.
+	 * 
+	 * <p>
+	 * The technique by which the framework refreshes bundles may vary among
+	 * different framework implementations. A permissible implementation is to
+	 * stop and restart the framework.
+	 * 
+	 * <p>
+	 * This method returns to the caller immediately and then performs the
+	 * following steps on a separate thread:
+	 * 
+	 * <ol>
+	 * <li>Compute the {@link #getDependencyClosure(Collection) dependency
+	 * closure} of the specified bundles. If no bundles are specified, compute
+	 * the dependency closure of the {@link #getRemovalPendingBundles() removal
+	 * pending} bundles.
+	 * 
+	 * <li>Each bundle in the dependency closure that is in the {@code ACTIVE}
+	 * state will be stopped as described in the {@code Bundle.stop} method.
+	 * 
+	 * <li>Each bundle in the dependency closure that is in the {@code RESOLVED}
+	 * state is unresolved and thus moved to the {@code INSTALLED} state. The
+	 * effect of this step is that bundles in the dependency closure are no
+	 * longer {@code RESOLVED}.
+	 * 
+	 * <li>Each bundle in the dependency closure that is in the
+	 * {@code UNINSTALLED} state is removed from the dependency closure and is
+	 * now completely removed from the Framework.
+	 * 
+	 * <li>Each bundle in the dependency closure that was in the {@code ACTIVE}
+	 * state prior to Step 2 is started as described in the {@code Bundle.start}
+	 * method, causing all bundles required for the restart to be resolved. It
+	 * is possible that, as a result of the previous steps, packages that were
+	 * previously exported no longer are. Therefore, some bundles may be
+	 * unresolvable until bundles satisfying the dependencies have been
+	 * installed in the Framework.
+	 * </ol>
+	 * 
+	 * <p>
+	 * For any exceptions that are thrown during any of these steps, a framework
+	 * event of type {@code FrameworkEvent.ERROR} is fired containing the
+	 * exception. The source bundle for these events should be the specific
+	 * bundle to which the exception is related. If no specific bundle can be
+	 * associated with the exception then the System Bundle must be used as the
+	 * source bundle for the event. All framework events fired by this method
+	 * are also delivered to the specified {@code FrameworkListener}s in the
+	 * order they are specified.
+	 * 
+	 * <p>
+	 * When this process completes after the bundles are refreshed, the
+	 * Framework will fire a Framework event of type
+	 * {@code FrameworkEvent.PACKAGES_REFRESHED} to announce it has completed
+	 * the bundle refresh. The specified {@code FrameworkListener}s are notified
+	 * in the order specified. Each specified {@code FrameworkListener} will be
+	 * called with a Framework event of type
+	 * {@code FrameworkEvent.PACKAGES_REFRESHED}.
+	 * 
+	 * @param bundles The bundles to be refreshed, or {@code null} to refresh
+	 *        the {@link #getRemovalPendingBundles() removal pending} bundles.
+	 * @param listeners Zero or more listeners to be notified when the bundle
+	 *        refresh has been completed. The specified listeners do not need to
+	 *        be otherwise registered with the framework. If a specified
+	 *        listener is already registered with the framework, it will be
+	 *        notified twice.
+	 * @throws IllegalArgumentException If the specified {@code Bundle}s were
+	 *         not created by the same framework instance associated with this
+	 *         FrameworkWiring.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,RESOLVE]} and the Java
+	 *         runtime environment supports permissions.
+	 */
+	void refreshBundles(Collection<Bundle> bundles,
+			FrameworkListener... listeners);
+
+	/**
+	 * Resolves the specified bundles. The Framework must attempt to resolve the
+	 * specified bundles that are unresolved. Additional bundles that are not
+	 * included in the specified bundles may be resolved as a result of calling
+	 * this method. A permissible implementation of this method is to attempt to
+	 * resolve all unresolved bundles installed in the framework.
+	 * 
+	 * <p>
+	 * If no bundles are specified, then the Framework will attempt to resolve
+	 * all unresolved bundles. This method must not cause any bundle to be
+	 * refreshed, stopped, or started. This method will not return until the
+	 * operation has completed.
+	 * 
+	 * @param bundles The bundles to resolve or {@code null} to resolve all
+	 *        unresolved bundles installed in the Framework.
+	 * @return {@code true} if all specified bundles are resolved; {@code false}
+	 *         otherwise.
+	 * @throws IllegalArgumentException If the specified {@code Bundle}s were
+	 *         not created by the same framework instance associated with this
+	 *         FrameworkWiring.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[System Bundle,RESOLVE]} and the Java
+	 *         runtime environment supports permissions.
+	 */
+	boolean resolveBundles(Collection<Bundle> bundles);
+
+	/**
+	 * Returns the bundles that have {@link BundleWiring#isCurrent()
+	 * non-current}, {@link BundleWiring#isInUse() in use} bundle wirings. This
+	 * is typically the bundles which have been updated or uninstalled since the
+	 * last call to {@link #refreshBundles(Collection, FrameworkListener...)}.
+	 * 
+	 * @return A collection containing a snapshot of the {@code Bundle}s which
+	 *         have non-current, in use {@code BundleWiring}s, or an empty
+	 *         collection if there are no such bundles.
+	 */
+	Collection<Bundle> getRemovalPendingBundles();
+
+	/**
+	 * Returns the dependency closure for the specified bundles.
+	 * 
+	 * <p>
+	 * A graph of bundles is computed starting with the specified bundles. The
+	 * graph is expanded by adding any bundle that is either wired to a package
+	 * that is currently exported by a bundle in the graph or requires a bundle
+	 * in the graph. The graph is fully constructed when there is no bundle
+	 * outside the graph that is wired to a bundle in the graph. The graph may
+	 * contain {@code UNINSTALLED} bundles that are
+	 * {@link #getRemovalPendingBundles() removal pending}.
+	 * 
+	 * @param bundles The initial bundles for which to generate the dependency
+	 *        closure.
+	 * @return A collection containing a snapshot of the dependency closure of
+	 *         the specified bundles, or an empty collection if there were no
+	 *         specified bundles.
+	 * @throws IllegalArgumentException If the specified {@code Bundle}s were
+	 *         not created by the same framework instance associated with this
+	 *         FrameworkWiring.
+	 */
+	Collection<Bundle> getDependencyClosure(Collection<Bundle> bundles);
+}