Update OSGi R4.3 API. Fix a few bugs. (FELIX-2950)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1124290 13f79535-47bb-0310-9956-ffa450edef68
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 a64ba1f..b25121f 100644
--- a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
@@ -54,7 +54,14 @@
 
     public boolean match(ServiceReference sr)
     {
-        return CapabilitySet.matches((ServiceReferenceImpl) sr, m_filter);
+        if (sr instanceof ServiceReferenceImpl)
+        {
+            return CapabilitySet.matches((ServiceReferenceImpl) sr, m_filter);
+        }
+        else
+        {
+            return CapabilitySet.matches(new ServiceReferenceCapability(sr), m_filter);
+        }
     }
 
     public boolean match(Dictionary<String, ? > dctnr)
@@ -69,7 +76,7 @@
 
     public boolean matches(Map<String, ?> map)
     {
-        throw new UnsupportedOperationException("Not supported yet.");
+        return CapabilitySet.matches(new DictionaryCapability(map), m_filter);
     }
 
     public boolean equals(Object o)
@@ -91,6 +98,12 @@
     {
         private final Map m_map;
 
+        public DictionaryCapability(Map map)
+        {
+            super(null, null, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
+            m_map = map;
+        }
+
         public DictionaryCapability(Dictionary dict, boolean caseSensitive)
         {
             super(null, null, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
@@ -128,6 +141,53 @@
         }
     }
 
+    static class ServiceReferenceCapability extends BundleCapabilityImpl
+    {
+        private final ServiceReference m_sr;
+        private final Map<String, Object> m_attrs;
+
+        public ServiceReferenceCapability(ServiceReference sr)
+        {
+            super(null, null, Collections.EMPTY_MAP, Collections.EMPTY_MAP);
+            m_sr = sr;
+            m_attrs = new StringMap(false);
+            for (String key : m_sr.getPropertyKeys())
+            {
+                m_attrs.put(key, m_sr.getProperty(key));
+            }
+        }
+
+        @Override
+        public BundleRevision getRevision()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public String getNamespace()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public Map<String, String> getDirectives()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        @Override
+        public Map<String, Object> getAttributes()
+        {
+            return m_attrs;
+        }
+
+        @Override
+        public List<String> getUses()
+        {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+    }
+
     private static class DictionaryMap implements Map
     {
         private final StringMap m_map;
diff --git a/framework/src/main/java/org/osgi/framework/FrameworkUtil.java b/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
index 0e89999..ec0af1e 100644
--- a/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
+++ b/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
@@ -16,20 +16,11 @@
 
 package org.osgi.framework;
 
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Constructor;
-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;
 
@@ -76,7 +67,7 @@
 	 */
 	public static Filter createFilter(String filter)
 			throws InvalidSyntaxException {
-		return FilterImpl.newInstance(filter);
+		return new org.apache.felix.framework.FilterImpl(filter);
 	}
 
 	/**
@@ -221,1518 +212,6 @@
 	}
 
 	/**
-	 * 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>
diff --git a/framework/src/main/java/org/osgi/framework/hooks/bundle/EventHook.java b/framework/src/main/java/org/osgi/framework/hooks/bundle/EventHook.java
new file mode 100644
index 0000000..4b50ab3
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/hooks/bundle/EventHook.java
@@ -0,0 +1,60 @@
+/*
+ * 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.hooks.bundle;
+
+import java.util.Collection;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+
+/** 
+ * OSGi Framework Bundle Event Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during framework lifecycle
+ * (install, start, stop, update, and uninstall bundle) operations.
+ * 
+ * @ThreadSafe
+ * @version $Id: 18ea1ec1f14f47410a43e99be4da3b2583149722 $
+ */
+public interface EventHook {
+
+	/**
+	 * Bundle event hook method.  This method is called prior to bundle event
+	 * delivery when a bundle is installed, resolved, started, stopped, unresolved, or
+	 * uninstalled.  This method can filter the bundles which receive the event.
+	 * <p>
+	 * This method must be called by the framework one and only one time for each bundle 
+	 * event generated, this included bundle events which are generated when there are no 
+	 * bundle listeners registered.  This method must be called on the same thread that is 
+	 * performing the action which generated the specified event.  The specified 
+	 * collection includes bundle contexts with synchronous and asynchronous bundle 
+	 * listeners registered with them.
+	 * 
+	 * @param event The bundle event to be delivered
+	 * @param contexts A collection of Bundle Contexts for bundles which have
+	 *        listeners to which the specified event will be delivered. The
+	 *        implementation of this method may remove bundle contexts from the
+	 *        collection to prevent the event from being delivered to the
+	 *        associated bundles. The collection supports all the optional
+	 *        {@code Collection} operations except {@code add} and
+	 *        {@code addAll}. Attempting to add to the collection will
+	 *        result in an {@code UnsupportedOperationException}. The
+	 *        collection is not synchronized.
+	 */
+	void event(BundleEvent event, Collection<BundleContext> contexts);
+}
diff --git a/framework/src/main/java/org/osgi/framework/hooks/bundle/FindHook.java b/framework/src/main/java/org/osgi/framework/hooks/bundle/FindHook.java
new file mode 100644
index 0000000..e55ee3b
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/hooks/bundle/FindHook.java
@@ -0,0 +1,66 @@
+/*
+ * 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.hooks.bundle;
+
+import java.util.Collection;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+
+/**
+ * OSGi Framework Bundle Context Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during framework bundle find
+ * (get bundles) operations.
+ * 
+ * @ThreadSafe
+ * @version $Id: 4492a677df650072fe6acaea9ea35571f31eb5a9 $
+ */
+public interface FindHook {
+	/**
+	 * Find hook method. This method is called for the following:
+	 * <ul>
+	 * <li>Bundle find operations using {@link BundleContext#getBundle(long)}
+	 * and {@link BundleContext#getBundles()} methods. The find method can
+	 * filter the result of the find operation. Note that a find operation using
+	 * the {@link BundleContext#getBundle(String)} method does not cause the
+	 * find method to be called.</li>
+	 * <li>Bundle install operations when an existing bundle is already
+	 * installed at a given location. In this case, the find method is called to
+	 * determine if the context performing the install operation is able to find
+	 * the bundle. If the context cannot find the existing bundle then the
+	 * install operation must fail with a
+	 * {@link BundleException#REJECTED_BY_HOOK} exception.</li>
+	 * </ul>
+	 * 
+	 * @param context
+	 *            The bundle context of the bundle performing the find
+	 *            operation.
+	 * @param bundles
+	 *            A collection of Bundles to be returned as a result of the find
+	 *            operation. The implementation of this method may remove
+	 *            bundles from the collection to prevent the bundles from being
+	 *            returned to the bundle performing the find operation. The
+	 *            collection supports all the optional {@code Collection}
+	 *            operations except {@code add} and {@code addAll}. Attempting
+	 *            to add to the collection will result in an
+	 *            {@code UnsupportedOperationException}. The collection is not
+	 *            synchronized.
+	 */
+	void find(BundleContext context, Collection<Bundle> bundles);
+}
diff --git a/framework/src/main/java/org/osgi/framework/hooks/resolver/ResolverHook.java b/framework/src/main/java/org/osgi/framework/hooks/resolver/ResolverHook.java
new file mode 100644
index 0000000..bbde7ff
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/hooks/resolver/ResolverHook.java
@@ -0,0 +1,198 @@
+/*
+ * 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.hooks.resolver;
+
+import java.util.Collection;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleCapability;
+import org.osgi.framework.wiring.BundleRequirement;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+/**
+ * OSGi Framework Resolver Hook instances are obtained from the OSGi
+ * {@link ResolverHookFactory Framework Resolver Hook Factory} service.
+ * 
+ * <p>
+ * A Resolver Hook instance is called by the framework during a resolve process.
+ * A resolver hook may influence the outcome of a resolve process by removing
+ * entries from shrinkable collections that are passed to the hook during a
+ * resolve process. A shrinkable collection is a {@code Collection} that
+ * supports all remove operations. Any other attempts to modify a shrinkable
+ * collection will result in an {@code UnsupportedOperationException} being
+ * thrown.
+ * 
+ * <p>
+ * The following steps outline the way a framework uses the resolver hooks
+ * during a resolve process.
+ * <ol>
+ * <li>Collect a snapshot of registered resolver hook factories that will be
+ * called during the current resolve process. Any hook factories registered
+ * after the snapshot is taken must not be called during the current resolve
+ * process. A resolver hook factory contained in the snapshot may become
+ * unregistered during the resolve process. The framework should handle this and
+ * stop calling the resolver hook instance provided by the unregistered hook
+ * factory and the current resolve process must fail. If possible, an exception
+ * must be thrown to the caller of the API which triggered the resolve process.
+ * In cases where the the caller is not available a framework event of type
+ * error should be fired.</li>
+ * <li>For each registered hook factory call the
+ * {@link ResolverHookFactory#begin(Collection)} method to inform the hooks
+ * about a resolve process beginning and to obtain a Resolver Hook instance that
+ * will be used for the duration of the resolve process.</li>
+ * <li>Determine the collection of unresolved bundle revisions that may be
+ * considered for resolution during the current resolution process and place
+ * each of the bundle revisions in a shrinkable collection {@code R}. For each
+ * resolver hook call the {@link #filterResolvable(Collection)} method with the
+ * shrinkable collection {@code R}.</li>
+ * <li>The shrinkable collection {@code R} now contains all the unresolved
+ * bundle revisions that may end up as resolved at the end of the current
+ * resolve process. Any other bundle revisions that got removed from the
+ * shrinkable collection {@code R} must not end up as resolved at the end of the
+ * current resolve process.</li>
+ * <li>For each bundle revision {@code B} left in the shrinkable collection
+ * {@code R} that represents a singleton bundle do the following:<br/>
+ * Determine the collection of available capabilities that have a name space of
+ * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}, are singletons,
+ * and have the same symbolic name as the singleton bundle revision {@code B}
+ * and place each of the matching capabilities into a shrinkable collection
+ * {@code S}.
+ * 
+ * Remove the {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}
+ * capability provided by bundle revision {@code B} from shrinkable collection
+ * {@code S}. A singleton bundle cannot collide with itself.
+ * 
+ * For each resolver hook call the
+ * {@link #filterSingletonCollisions(BundleCapability, Collection)} with the
+ * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle} capability
+ * provided by bundle revision {@code B} and the shrinkable collection {@code S}
+ * 
+ * The shrinkable collection {@code S} now contains all singleton
+ * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle} capabilities that
+ * can influence the ability of bundle revision {@code B} to resolve.</li>
+ * <li>During a resolve process a framework is free to attempt to resolve any or
+ * all bundles contained in shrinkable collection {@code R}. For each bundle
+ * revision {@code B} left in the shrinkable collection {@code R} which the
+ * framework attempts to resolve the following steps must be followed:
+ * <p/>
+ * For each requirement {@code T} specified by bundle revision {@code B}
+ * determine the collection of capabilities that satisfy (or match) the
+ * requirement and place each matching capability into a shrinkable collection
+ * {@code C}. A capability is considered to match a particular requirement if
+ * its attributes satisfy a specified requirement and the requirer bundle has
+ * permission to access the capability.
+ * 
+ * <p/>
+ * For each resolver hook call the
+ * {@link #filterMatches(BundleRequirement, Collection)} with the requirement
+ * {@code T} and the shrinkable collection {@code C}.
+ * 
+ * <p/>
+ * The shrinkable collection {@code C} now contains all the capabilities that
+ * may be used to satisfy the requirement {@code T}. Any other capabilities that
+ * got removed from the shrinkable collection {@code C} must not be used to
+ * satisfy requirement {@code T}.</li>
+ * <li>For each resolver hook call the {@link #end()} method to inform the hooks
+ * about a resolve process ending.</li>
+ * </ol>
+ * In all cases, the order in which the resolver hooks are called is the reverse
+ * compareTo ordering of their Service References. That is, the service with the
+ * highest ranking number must be called first. In cases where a shrinkable
+ * collection becomes empty the framework is required to call the remaining
+ * registered hooks.
+ * <p>
+ * Resolver hooks are low level. Implementations of the resolver hook must be
+ * careful not to create an unresolvable state which is very hard for a
+ * developer or a provisioner to diagnose. Resolver hooks also must not be
+ * allowed to start another synchronous resolve process (e.g. by calling
+ * {@link Bundle#start()} or {@link FrameworkWiring#resolveBundles(Collection)}
+ * ). The framework must detect this and throw an {@link IllegalStateException}.
+ * 
+ * @see ResolverHookFactory
+ * @NotThreadSafe
+ * @version $Id: ea23400257d780706250f8825ec886aaebb0e5d8 $
+ */
+public interface ResolverHook {
+	/**
+	 * Filter resolvable candidates hook method.  This method may be called
+	 * multiple times during a single resolve process.
+	 * This method can filter the collection of candidates by removing 
+	 * potential candidates.  Removing a candidate will prevent the candidate
+	 * from resolving during the current resolve process. 
+	 * 
+	 * @param candidates the collection of resolvable candidates available during
+	 * a resolve process. 
+	 */
+	void filterResolvable(Collection<BundleRevision> candidates);
+
+	/**
+	 * Filter singleton collisions hook method. This method is called during the
+	 * resolve process for the specified singleton. The specified singleton
+	 * represents a singleton capability and the specified collection represent
+	 * a collection of singleton capabilities which are considered collision
+	 * candidates. The singleton capability and the collection of collision
+	 * candidates must all use the same name space.
+	 * <p>
+	 * Currently only capabilities with the name space of
+	 * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle} can be
+	 * singletons. In that case all the collision candidates have the name space
+	 * of {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}, are
+	 * singletons, and have the same symbolic name as the specified singleton
+	 * capability.
+	 * <p>
+	 * In the future, capabilities in other name spaces may support the
+	 * singleton concept. Hook implementations should be prepared to receive
+	 * calls to this method for capabilities in name spaces other than
+	 * {@link BundleRevision#BUNDLE_NAMESPACE osgi.wiring.bundle}.
+	 * <p>
+	 * This method can filter the list of collision candidates by removing
+	 * potential collisions. Removing a collision candidate will allow the
+	 * specified singleton to resolve regardless of the resolution state of the
+	 * removed collision candidate.
+	 * 
+	 * @param singleton the singleton involved in a resolve process
+	 * @param collisionCandidates a collection of singleton collision candidates
+	 */
+	void filterSingletonCollisions(BundleCapability singleton, Collection<BundleCapability> collisionCandidates);
+
+	/**
+	 * Filter matches hook method. This method is called during the resolve process for the 
+	 * specified requirement.  The collection of candidates match the specified requirement.
+	 * This method can filter the collection of matching candidates by removing candidates from 
+	 * the collection.  Removing a candidate will prevent the resolve process from choosing the 
+	 * removed candidate to satisfy the requirement.
+	 * <p>
+	 * All of the candidates will have the same name space and will 
+	 * match the specified requirement.
+	 * <p>
+	 * If the Java Runtime Environment supports permissions then the collection of 
+	 * candidates will only contain candidates for which the requirer has permission to
+	 * access.
+	 * @param requirement the requirement to filter candidates for
+	 * @param candidates a collection of candidates that match the requirement
+	 */
+	void filterMatches(BundleRequirement requirement, Collection<BundleCapability> candidates);
+
+	/**
+	 * This method is called once at the end of the resolve process.
+	 * After the end method is called the resolve process has ended.
+	 * The framework must not hold onto this resolver hook instance
+	 * after end has been called.
+	 */
+	void end();
+}
diff --git a/framework/src/main/java/org/osgi/framework/hooks/resolver/ResolverHookFactory.java b/framework/src/main/java/org/osgi/framework/hooks/resolver/ResolverHookFactory.java
new file mode 100644
index 0000000..1d4edd4
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/hooks/resolver/ResolverHookFactory.java
@@ -0,0 +1,94 @@
+/*
+ * 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.hooks.resolver;
+
+import java.util.Collection;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.FrameworkWiring;
+
+/** 
+ * OSGi Framework Resolver Hook Factory Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called by the framework during 
+ * a bundle resolver process to obtain a {@link ResolverHook resolver hook}
+ * instance which will be used for the duration of a resolve process.
+ * 
+ * @ThreadSafe
+ * @see ResolverHook
+ * @version $Id: 4023566367435f07c047a7ba571f3bedc53aa37a $
+ */
+public interface ResolverHookFactory {
+	/**
+	 * This method is called by the framework each time a resolve process begins
+	 * to obtain a {@link ResolverHook resolver hook} instance.  This resolver hook 
+	 * instance will be used for the duration of the resolve process.  At the end of 
+	 * the resolve process the method {@link ResolverHook#end()} must be called by 
+	 * the framework and the framework must not hold any references of the resolver 
+	 * hook instance.
+	 * <p>
+	 * The triggers represent the collection of bundles which triggered
+	 * the resolve process.  This collection may be empty if the triggers
+	 * cannot be determined by the framework.  In most cases the triggers 
+	 * can easily be determined.  Calling certain methods on 
+	 * {@link Bundle bundle} when a bundle is in the {@link Bundle#INSTALLED INSTALLED} 
+	 * state will cause the framework to begin a resolve process in order to resolve the 
+	 * bundle.  The following methods will start a resolve process in this case:
+	 * <ul>
+	 *   <li>{@link Bundle#start() start}</li>
+	 *   <li>{@link Bundle#loadClass(String) loadClass}</li>
+	 *   <li>{@link Bundle#findEntries(String, String, boolean) findEntries}</li>
+	 *   <li>{@link Bundle#getResource(String) getResource}</li>
+	 *   <li>{@link Bundle#getResources(String) getResources}</li>
+	 * </ul> 
+	 * In such cases the collection will contain the single bundle which the
+	 * framework is trying to resolve.  Other cases will cause multiple bundles to be
+	 * included in the trigger bundles collection.  When {@link FrameworkWiring#resolveBundles(Collection)
+	 * resolveBundles} is called the collection of triggers must include all the current bundle 
+	 * revisions for bundles passed to resolveBundles which are in the {@link Bundle#INSTALLED INSTALLED}
+	 * state.
+	 * <p>
+	 * When {@link FrameworkWiring#refreshBundles(Collection, org.osgi.framework.FrameworkListener...)}
+	 * is called the collection of triggers is determined with the following steps:
+	 * <ul>
+	 *   <li>If the collection of bundles passed is null then {@link FrameworkWiring#getRemovalPendingBundles()}
+	 *   is called to get the initial collection of bundles.</li>
+	 *   <li>The equivalent of calling {@link FrameworkWiring#getDependencyClosure(Collection)} is called with
+	 *   the initial collection of bundles to get the dependency closure collection of the bundles being refreshed.</li>
+	 *   <li>Remove any non-active bundles from the dependency closure collection.</li>
+	 *   <li>For each bundle remaining in the dependency closure collection get the current bundle revision
+	 *   and add it to the collection of triggers.</li> 
+	 * </ul>
+	 * <p>
+	 * As described above, a resolve process is typically initiated as a result of calling API that causes the 
+	 * framework to attempt to resolve one or more bundles.  
+	 * The framework is free to start a resolve process at any time for reasons other than calls to framework API.
+	 * For example, a resolve process may be used by the framework for diagnostic purposes and result in no
+	 * bundles actually becoming resolved at the end of the process.
+	 * Resolver hook implementations must be prepared for resolve processes that are initiated for other reasons
+	 * besides calls to framework API.
+	 * @param triggers an unmodifiable collection of bundles which triggered the resolve process.
+	 * This collection may be empty if the collection of trigger bundles cannot be
+	 * determined.
+	 * @return a resolver hook instance to be used for the duration of the resolve process.
+	 * A {@code null} value may be returned which indicates this resolver hook factory abstains from
+	 * the resolve process.
+	 */
+	ResolverHook begin(Collection<BundleRevision> triggers);
+}
diff --git a/framework/src/main/java/org/osgi/framework/hooks/service/EventHook.java b/framework/src/main/java/org/osgi/framework/hooks/service/EventHook.java
index 1249493..fb2ab09 100644
--- a/framework/src/main/java/org/osgi/framework/hooks/service/EventHook.java
+++ b/framework/src/main/java/org/osgi/framework/hooks/service/EventHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2008, 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.util.Collection;
 
+import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceEvent;
 
 /**
@@ -28,7 +29,8 @@
  * (register, modify, and unregister service) operations.
  * 
  * @ThreadSafe
- * @version $Revision: 6967 $
+ * @deprecated As of 1.1. Replaced by {@link EventListenerHook}.
+ * @version $Id: 8fb8cfa2c8847f99fd84711e12f02a57bf06932e $
  */
 
 public interface EventHook {
@@ -38,17 +40,15 @@
 	 * This method can filter the bundles which receive the event.
 	 * 
 	 * @param event The service event to be delivered.
-	 * @param contexts A <code>Collection</code> of Bundle Contexts for bundles
-	 *        which have listeners to which the specified event will be
-	 *        delivered. The implementation of this method may remove bundle
-	 *        contexts from the collection to prevent the event from being
-	 *        delivered to the associated bundles. The collection supports all
-	 *        the optional <code>Collection</code> operations except
-	 *        <code>add</code> and <code>addAll</code>. Attempting to add to the
-	 *        collection will result in an
-	 *        <code>UnsupportedOperationException</code>. The collection is not
-	 *        synchronized.
+	 * @param contexts A collection of Bundle Contexts for bundles which have
+	 *        listeners to which the specified event will be delivered. The
+	 *        implementation of this method may remove bundle contexts from the
+	 *        collection to prevent the event from being delivered to the
+	 *        associated bundles. The collection supports all the optional
+	 *        {@code Collection} operations except {@code add} and
+	 *        {@code addAll}. Attempting to add to the collection will
+	 *        result in an {@code UnsupportedOperationException}. The
+	 *        collection is not synchronized.
 	 */
-	void event(ServiceEvent event,
-			Collection/* <BundleContext> */contexts);
+	void event(ServiceEvent event, Collection<BundleContext> contexts);
 }
diff --git a/framework/src/main/java/org/osgi/framework/hooks/service/EventListenerHook.java b/framework/src/main/java/org/osgi/framework/hooks/service/EventListenerHook.java
new file mode 100644
index 0000000..6f25291
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/hooks/service/EventListenerHook.java
@@ -0,0 +1,61 @@
+/*
+ * 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.hooks.service;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.hooks.service.ListenerHook.ListenerInfo;
+
+/**
+ * OSGi Framework Service Event Listener Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during framework service
+ * (register, modify, and unregister service) operations.
+ * 
+ * @ThreadSafe
+ * @since 1.1
+ * @version $Id: 61c6aa7e7d4c85b3e5a6a3a340155bcda0074505 $
+ */
+
+public interface EventListenerHook {
+	/**
+	 * Event listener hook method. This method is called prior to service event
+	 * delivery when a publishing bundle registers, modifies or unregisters a
+	 * service. This method can filter the listeners which receive the event.
+	 * 
+	 * @param event The service event to be delivered.
+	 * @param listeners A map of Bundle Contexts to a collection of Listener
+	 *        Infos for the bundle's listeners to which the specified event will
+	 *        be delivered. The implementation of this method may remove bundle
+	 *        contexts from the map and listener infos from the collection
+	 *        values to prevent the event from being delivered to the associated
+	 *        listeners. The map supports all the optional {@code Map}
+	 *        operations except {@code put} and {@code putAll}. Attempting to
+	 *        add to the map will result in an
+	 *        {@code UnsupportedOperationException}. The collection values in
+	 *        the map supports all the optional {@code Collection} operations
+	 *        except {@code add} and {@code addAll}. Attempting to add to a
+	 *        collection will result in an {@code UnsupportedOperationException}
+	 *        . The map and the collections are not synchronized.
+	 */
+	void event(ServiceEvent event,
+			Map<BundleContext, Collection<ListenerInfo>> listeners);
+}
diff --git a/framework/src/main/java/org/osgi/framework/hooks/service/FindHook.java b/framework/src/main/java/org/osgi/framework/hooks/service/FindHook.java
index 0de1f0b..cb334c5 100644
--- a/framework/src/main/java/org/osgi/framework/hooks/service/FindHook.java
+++ b/framework/src/main/java/org/osgi/framework/hooks/service/FindHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2008, 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,6 +19,7 @@
 import java.util.Collection;
 
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
 
 /**
  * OSGi Framework Service Find Hook Service.
@@ -28,7 +29,7 @@
  * (get service references) operations.
  * 
  * @ThreadSafe
- * @version $Revision: 6967 $
+ * @version $Id: 4a939200fa6634a563379b057e11bd1b5d174b9d $
  */
 
 public interface FindHook {
@@ -39,25 +40,23 @@
 	 * 
 	 * @param context The bundle context of the bundle performing the find
 	 *        operation.
-	 * @param name The class name of the services to find or <code>null</code>
+	 * @param name The class name of the services to find or {@code null}
 	 *        to find all services.
 	 * @param filter The filter criteria of the services to find or
-	 *        <code>null</code> for no filter criteria.
-	 * @param allServices <code>true</code> if the find operation is the result
+	 *        {@code null} for no filter criteria.
+	 * @param allServices {@code true} if the find operation is the result
 	 *        of a call to
 	 *        {@link BundleContext#getAllServiceReferences(String, String)}
-	 * @param references A <code>Collection</code> of Service References to be
-	 *        returned as a result of the find operation. The implementation of
-	 *        this method may remove service references from the collection to
-	 *        prevent the references from being returned to the bundle
-	 *        performing the find operation. The collection supports all the
-	 *        optional <code>Collection</code> operations except
-	 *        <code>add</code> and <code>addAll</code>. Attempting to add to the
-	 *        collection will result in an
-	 *        <code>UnsupportedOperationException</code>. The collection is not
-	 *        synchronized.
+	 * @param references A collection of Service References to be returned as a
+	 *        result of the find operation. The implementation of this method
+	 *        may remove service references from the collection to prevent the
+	 *        references from being returned to the bundle performing the find
+	 *        operation. The collection supports all the optional
+	 *        {@code Collection} operations except {@code add} and
+	 *        {@code addAll}. Attempting to add to the collection will
+	 *        result in an {@code UnsupportedOperationException}. The
+	 *        collection is not synchronized.
 	 */
 	void find(BundleContext context, String name, String filter,
-			boolean allServices,
-			Collection/* <ServiceReference> */references);
+			boolean allServices, Collection<ServiceReference< ? >> references);
 }
diff --git a/framework/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java b/framework/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java
index 5934c0c..bdac7b5 100644
--- a/framework/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java
+++ b/framework/src/main/java/org/osgi/framework/hooks/service/ListenerHook.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2008, 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,7 +28,7 @@
  * addition and removal.
  * 
  * @ThreadSafe
- * @version $Revision: 6967 $
+ * @version $Id: c1687e95e568589cf3e6d927b7d372c9f88c5d16 $
  */
 
 public interface ListenerHook {
@@ -40,13 +40,13 @@
 	 * method will be called to provide the current collection of service
 	 * listeners which had been added prior to the hook being registered.
 	 * 
-	 * @param listeners A <code>Collection</code> of {@link ListenerInfo}s for
-	 *        newly added service listeners which are now listening to service
-	 *        events. Attempting to add to or remove from the collection will
-	 *        result in an <code>UnsupportedOperationException</code>. The
-	 *        collection is not synchronized.
+	 * @param listeners A collection of {@link ListenerInfo}s for newly added
+	 *        service listeners which are now listening to service events.
+	 *        Attempting to add to or remove from the collection will result in
+	 *        an {@code UnsupportedOperationException}. The collection is
+	 *        not synchronized.
 	 */
-	void added(Collection/* <ListenerInfo> */listeners);
+	void added(Collection<ListenerInfo> listeners);
 
 	/**
 	 * Removed listeners hook method. This method is called to provide the hook
@@ -54,19 +54,20 @@
 	 * method will be called as service listeners are removed while this hook is
 	 * registered.
 	 * 
-	 * @param listeners A <code>Collection</code> of {@link ListenerInfo}s for
-	 *        newly removed service listeners which are no longer listening to
-	 *        service events. Attempting to add to or remove from the collection
-	 *        will result in an <code>UnsupportedOperationException</code>. The
-	 *        collection is not synchronized.
+	 * @param listeners A collection of {@link ListenerInfo}s for newly removed
+	 *        service listeners which are no longer listening to service events.
+	 *        Attempting to add to or remove from the collection will result in
+	 *        an {@code UnsupportedOperationException}. The collection is
+	 *        not synchronized.
 	 */
-	void removed(Collection/* <ListenerInfo> */listeners);
+	void removed(Collection<ListenerInfo> listeners);
 
 	/**
 	 * Information about a Service Listener. This interface describes the bundle
 	 * which added the Service Listener and the filter with which it was added.
 	 * 
 	 * @ThreadSafe
+	 * @noimplement
 	 */
 	public interface ListenerInfo {
 		/**
@@ -80,17 +81,17 @@
 		 * Return the filter string with which the listener was added.
 		 * 
 		 * @return The filter string with which the listener was added. This may
-		 *         be <code>null</code> if the listener was added without a
+		 *         be {@code null} if the listener was added without a
 		 *         filter.
 		 */
 		String getFilter();
 
 		/**
 		 * Return the state of the listener for this addition and removal life
-		 * cycle. Initially this method will return <code>false</code>
+		 * cycle. Initially this method will return {@code false}
 		 * indicating the listener has been added but has not been removed.
 		 * After the listener has been removed, this method must always return
-		 * <code>true</code>.
+		 * {@code true}.
 		 * 
 		 * <p>
 		 * There is an extremely rare case in which removed notification to
@@ -102,32 +103,32 @@
 		 * service listener. This method can be used to detect this rare
 		 * occurrence.
 		 * 
-		 * @return <code>false</code> if the listener has not been been removed,
-		 *         <code>true</code> otherwise.
+		 * @return {@code false} if the listener has not been been removed,
+		 *         {@code true} otherwise.
 		 */
 		boolean isRemoved();
 
 		/**
-		 * Compares this <code>ListenerInfo</code> to another
-		 * <code>ListenerInfo</code>. Two <code>ListenerInfo</code>s are equals
+		 * Compares this {@code ListenerInfo} to another
+		 * {@code ListenerInfo}. Two {@code ListenerInfo}s are equals
 		 * if they refer to the same listener for a given addition and removal
 		 * life cycle. If the same listener is added again, it must have a
-		 * different <code>ListenerInfo</code> which is not equal to this
-		 * <code>ListenerInfo</code>.
+		 * different {@code ListenerInfo} which is not equal to this
+		 * {@code ListenerInfo}.
 		 * 
 		 * @param obj The object to compare against this
-		 *        <code>ListenerInfo</code>.
-		 * @return <code>true</code> if the other object is a
-		 *         <code>ListenerInfo</code> object and both objects refer to
+		 *        {@code ListenerInfo}.
+		 * @return {@code true} if the other object is a
+		 *         {@code ListenerInfo} object and both objects refer to
 		 *         the same listener for a given addition and removal life
 		 *         cycle.
 		 */
 		boolean equals(Object obj);
 
 		/**
-		 * Returns the hash code for this <code>ListenerInfo</code>.
+		 * Returns the hash code for this {@code ListenerInfo}.
 		 * 
-		 * @return The hash code of this <code>ListenerInfo</code>.
+		 * @return The hash code of this {@code ListenerInfo}.
 		 */
 		int hashCode();
 	}
diff --git a/framework/src/main/java/org/osgi/framework/hooks/weaving/WeavingException.java b/framework/src/main/java/org/osgi/framework/hooks/weaving/WeavingException.java
new file mode 100644
index 0000000..8842797
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/hooks/weaving/WeavingException.java
@@ -0,0 +1,51 @@
+/*
+ * 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.hooks.weaving;
+
+/**
+ * A weaving exception used to indicate that the class load should be failed but
+ * the weaving hook must not be blacklisted by the framework.
+ * 
+ * <p>
+ * This exception conforms to the general purpose exception chaining mechanism.
+ * 
+ * @version $Id: eb38b85f6ed66ec445fb2f0ee7143df021327a9a $
+ */
+
+public class WeavingException extends RuntimeException {
+	private static final long	serialVersionUID	= 1L;
+
+	/**
+	 * Creates a {@code WeavingException} with the specified message and
+	 * exception cause.
+	 * 
+	 * @param msg The associated message.
+	 * @param cause The cause of this exception.
+	 */
+	public WeavingException(String msg, Throwable cause) {
+		super(msg, cause);
+	}
+
+	/**
+	 * Creates a {@code WeavingException} with the specified message.
+	 * 
+	 * @param msg The message.
+	 */
+	public WeavingException(String msg) {
+		super(msg);
+	}
+}
diff --git a/framework/src/main/java/org/osgi/framework/hooks/weaving/WeavingHook.java b/framework/src/main/java/org/osgi/framework/hooks/weaving/WeavingHook.java
new file mode 100644
index 0000000..be57658
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/hooks/weaving/WeavingHook.java
@@ -0,0 +1,63 @@
+/*
+ * 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.hooks.weaving;
+
+/**
+ * OSGi Framework Weaving Hook Service.
+ * 
+ * <p>
+ * Bundles registering this service will be called during framework class
+ * loading operations. Weaving hook services are called when a class is being
+ * loaded by the framework and have an opportunity to transform the class file
+ * bytes that represents the class being loaded. Weaving hooks may also ask the
+ * framework to wire in additional dynamic imports to the bundle.
+ * 
+ * <p>
+ * When a class is being loaded, the framework will create a {@link WovenClass}
+ * object for the class and pass it to each registered weaving hook service for
+ * possible modification. The first weaving hook called will see the original
+ * class file bytes. Subsequently called weaving hooks will see the class file
+ * bytes as modified by previously called weaving hooks.
+ * 
+ * @ThreadSafe
+ * @version $Id: d1985029024baba2db1c56aab1e06ee953fd6365 $
+ */
+
+public interface WeavingHook {
+	/**
+	 * Weaving hook method.
+	 * 
+	 * This method can modify the specified woven class object to weave the
+	 * class being defined.
+	 * 
+	 * <p>
+	 * If this method throws any exception, the framework must log the exception
+	 * and fail the class load in progress. This weaving hook service must be
+	 * blacklisted by the framework and must not be called again. The
+	 * blacklisting of this weaving hook service must expire when this weaving
+	 * hook service is unregistered. However, this method can throw a
+	 * {@link WeavingException} to deliberately fail the class load in progress
+	 * without being blacklisted by the framework.
+	 * 
+	 * @param wovenClass The {@link WovenClass} object that represents the data
+	 *        that will be used to define the class.
+	 * @throws WeavingException If this weaving hook wants to deliberately fail
+	 *         the class load in progress without being blacklisted by the
+	 *         framework
+	 */
+	public void weave(WovenClass wovenClass);
+}
diff --git a/framework/src/main/java/org/osgi/framework/hooks/weaving/WovenClass.java b/framework/src/main/java/org/osgi/framework/hooks/weaving/WovenClass.java
new file mode 100644
index 0000000..34aa6d2
--- /dev/null
+++ b/framework/src/main/java/org/osgi/framework/hooks/weaving/WovenClass.java
@@ -0,0 +1,157 @@
+/*
+ * 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.hooks.weaving;
+
+import java.security.ProtectionDomain;
+import java.util.List;
+
+import org.osgi.framework.wiring.BundleWiring;
+
+/**
+ * A class being woven.
+ * 
+ * This object represents a class being woven and is passed to each
+ * {@link WeavingHook} for possible modification. It allows access to the most
+ * recently transformed class file bytes and to any additional packages that
+ * should be added to the bundle as dynamic imports.
+ * 
+ * <p>
+ * After weaving is {@link #isWeavingComplete() complete}, this object becomes
+ * effectively immutable.
+ * 
+ * @NotThreadSafe
+ * @noimplement
+ * @version $Id: c689a4c27dc39af1bf5f51338f1a8eaca1dddc1a $
+ */
+public interface WovenClass {
+
+	/**
+	 * Returns the class file bytes to be used to define the
+	 * {@link WovenClass#getClassName() named} class.
+	 * 
+	 * <p>
+	 * While weaving is not {@link #isWeavingComplete() complete}, this method
+	 * returns a reference to the class files byte array contained in this
+	 * object. After weaving is {@link #isWeavingComplete() complete}, this
+	 * object becomes effectively immutable and a copy of the class file byte
+	 * array is returned.
+	 * 
+	 * @return The bytes to be used to define the
+	 *         {@link WovenClass#getClassName() named} class.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[bundle,WEAVE]} and the Java runtime
+	 *         environment supports permissions.
+	 */
+	public byte[] getBytes();
+
+	/**
+	 * Set the class file bytes to be used to define the
+	 * {@link WovenClass#getClassName() named} class. This method must not be
+	 * called outside invocations of the {@link WeavingHook#weave(WovenClass)
+	 * weave} method by the framework.
+	 * 
+	 * <p>
+	 * While weaving is not {@link #isWeavingComplete() complete}, this method
+	 * replaces the reference to the array contained in this object with the
+	 * specified array. After weaving is {@link #isWeavingComplete() complete},
+	 * this object becomes effectively immutable and this method will throw an
+	 * {@link IllegalStateException}.
+	 * 
+	 * @param newBytes The new classfile that will be used to define the
+	 *        {@link WovenClass#getClassName() named} class. The specified array
+	 *        is retained by this object and the caller must not modify the
+	 *        specified array.
+	 * @throws NullPointerException If newBytes is {@code null}.
+	 * @throws IllegalStateException If weaving is {@link #isWeavingComplete()
+	 *         complete}.
+	 * @throws SecurityException If the caller does not have
+	 *         {@code AdminPermission[bundle,WEAVE]} and the Java runtime
+	 *         environment supports permissions.
+	 */
+	public void setBytes(byte[] newBytes);
+
+	/**
+	 * Returns the list of dynamic import package descriptions to add to the
+	 * {@link #getBundleWiring() bundle wiring} for this woven class. Changes
+	 * made to the returned list will be visible to later {@link WeavingHook
+	 * weaving hooks} called with this object. The returned list must not be
+	 * modified outside invocations of the {@link WeavingHook#weave(WovenClass)
+	 * weave} method by the framework.
+	 * 
+	 * <p>
+	 * After weaving is {@link #isWeavingComplete() complete}, this object
+	 * becomes effectively immutable and the returned list will be unmodifiable.
+	 * 
+	 * <p>
+	 * If the Java runtime environment supports permissions, the caller must
+	 * have {@code AdminPermission[bundle,WEAVE]} to modify the returned list.
+	 * 
+	 * @return A list containing zero or more dynamic import package
+	 *         descriptions to add to the bundle wiring for this woven class.
+	 *         This list must throw {@code IllegalArgumentException} if a
+	 *         malformed dynamic import package description is added.
+	 * @see "Core Specification, Dynamic Import Package, for the syntax of a dynamic import package description."
+	 */
+	public List<String> getDynamicImports();
+
+	/**
+	 * Returns whether weaving is complete in this woven class. Weaving is
+	 * complete after the last {@link WeavingHook weaving hook} is called and
+	 * the class is defined.
+	 * 
+	 * <p>
+	 * After weaving is complete, this object becomes effectively immutable.
+	 * 
+	 * @return {@code true} weaving is complete, {@code false} otherwise.
+	 */
+	public boolean isWeavingComplete();
+
+	/**
+	 * Returns the fully qualified name of the class being woven.
+	 * 
+	 * @return The fully qualified name of the class being woven.
+	 */
+	public String getClassName();
+
+	/**
+	 * Returns the protection domain to which the woven class will be assigned
+	 * when it is defined.
+	 * 
+	 * @return The protection domain to which the woven class will be assigned
+	 *         when it is defined, or {@code null} if no protection domain will
+	 *         be assigned.
+	 */
+	public ProtectionDomain getProtectionDomain();
+
+	/**
+	 * Returns the class associated with this woven class. When loading a class
+	 * for the first time this method will return {@code null} until weaving is
+	 * {@link #isWeavingComplete() complete}. Once weaving is complete, this
+	 * method will return the class object.
+	 * 
+	 * @return The class associated with this woven class, or {@code null} if
+	 *         weaving is not complete or the class definition failed.
+	 */
+	public Class< ? > getDefinedClass();
+
+	/**
+	 * Returns the bundle wiring whose class loader will define the woven class.
+	 * 
+	 * @return The bundle wiring whose class loader will define the woven class.
+	 */
+	public BundleWiring getBundleWiring();
+}
diff --git a/framework/src/main/java/org/osgi/framework/launch/Framework.java b/framework/src/main/java/org/osgi/framework/launch/Framework.java
index f7618aa..672db44 100644
--- a/framework/src/main/java/org/osgi/framework/launch/Framework.java
+++ b/framework/src/main/java/org/osgi/framework/launch/Framework.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2008, 2009). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2008, 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,6 +17,8 @@
 package org.osgi.framework.launch;
 
 import java.io.InputStream;
+import java.net.URL;
+import java.util.Enumeration;
 
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleException;
@@ -32,7 +34,8 @@
  * instance.
  * 
  * @ThreadSafe
- * @version $Revision: 6542 $
+ * @noimplement
+ * @version $Id: 2be857d06f3605a04f701b59f11e127c0f8940dc $
  */
 public interface Framework extends Bundle {
 
@@ -40,14 +43,17 @@
 	 * Initialize this Framework. After calling this method, this Framework
 	 * must:
 	 * <ul>
+	 * <li>Have generated a new {@link Constants#FRAMEWORK_UUID framework UUID}.
+	 * </li>
 	 * <li>Be in the {@link #STARTING} state.</li>
 	 * <li>Have a valid Bundle Context.</li>
 	 * <li>Be at start level 0.</li>
 	 * <li>Have event handling enabled.</li>
 	 * <li>Have reified Bundle objects for all installed bundles.</li>
 	 * <li>Have registered any framework services. For example,
-	 * <code>PackageAdmin</code>, <code>ConditionalPermissionAdmin</code>,
-	 * <code>StartLevel</code>.</li>
+	 * {@code ConditionalPermissionAdmin}.</li>
+	 * <li>Be {@link #adapt(Class) adaptable} to the OSGi defined types to which
+	 * a system bundle can be adapted.</li>
 	 * </ul>
 	 * 
 	 * <p>
@@ -61,8 +67,8 @@
 	 * @throws BundleException If this Framework could not be initialized.
 	 * @throws SecurityException If the Java Runtime Environment supports
 	 *         permissions and the caller does not have the appropriate
-	 *         <code>AdminPermission[this,EXECUTE]</code> or if there is a
-	 *         security manager already installed and the
+	 *         {@code AdminPermission[this,EXECUTE]} or if there is a security
+	 *         manager already installed and the
 	 *         {@link Constants#FRAMEWORK_SECURITY} configuration property is
 	 *         set.
 	 * 
@@ -70,8 +76,8 @@
 	void init() throws BundleException;
 
 	/**
-	 * Wait until this Framework has completely stopped. The <code>stop</code>
-	 * and <code>update</code> methods on a Framework performs an asynchronous
+	 * Wait until this Framework has completely stopped. The {@code stop}
+	 * and {@code update} methods on a Framework performs an asynchronous
 	 * stop of the Framework. This method can be used to wait until the
 	 * asynchronous stop of this Framework has completed. This method will only
 	 * wait if called when this Framework is in the {@link #STARTING},
@@ -84,7 +90,7 @@
 	 *        Framework has completely stopped. A value of zero will wait
 	 *        indefinitely.
 	 * @return A Framework Event indicating the reason this method returned. The
-	 *         following <code>FrameworkEvent</code> types may be returned by
+	 *         following {@code FrameworkEvent} types may be returned by
 	 *         this method.
 	 *         <ul>
 	 *         <li>{@link FrameworkEvent#STOPPED STOPPED} - This Framework has
@@ -98,7 +104,7 @@
 	 *         STOPPED_BOOTCLASSPATH_MODIFIED} - This Framework has been stopped
 	 *         and a bootclasspath extension bundle has been installed or
 	 *         updated. The VM must be restarted in order for the changed boot
-	 *         class path to take affect. </li>
+	 *         class path to take effect. </li>
 	 * 
 	 *         <li>{@link FrameworkEvent#ERROR ERROR} - The Framework
 	 *         encountered an error while shutting down or an error has occurred
@@ -127,12 +133,10 @@
 	 * <li>All installed bundles must be started in accordance with each
 	 * bundle's persistent <i>autostart setting</i>. This means some bundles
 	 * will not be started, some will be started with <i>eager activation</i>
-	 * and some will be started with their <i>declared activation</i> policy. If
-	 * this Framework implements the optional <i>Start Level Service
-	 * Specification</i>, then the start level of this Framework is moved to the
-	 * start level specified by the
-	 * {@link Constants#FRAMEWORK_BEGINNING_STARTLEVEL beginning start level}
-	 * framework property, as described in the <i>Start Level Service
+	 * and some will be started with their <i>declared activation</i> policy.
+	 * The start level of this Framework is moved to the start level specified
+	 * by the {@link Constants#FRAMEWORK_BEGINNING_STARTLEVEL beginning start
+	 * level} framework property, as described in the <i>Start Level
 	 * Specification</i>. If this framework property is not specified, then the
 	 * start level of this Framework is moved to start level one (1). Any
 	 * exceptions that occur during bundle starting must be wrapped in a
@@ -144,9 +148,9 @@
 	 * 
 	 * @throws BundleException If this Framework could not be started.
 	 * @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 Level Service Specification"
+	 * @see "Start Level Specification"
 	 */
 	void start() throws BundleException;
 
@@ -160,7 +164,7 @@
 	 * @param options Ignored. There are no start options for the Framework.
 	 * @throws BundleException If this Framework could not be started.
 	 * @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()
 	 */
@@ -175,12 +179,11 @@
 	 * <ol>
 	 * <li>This Framework's state is set to {@link #STOPPING}.</li>
 	 * <li>All installed bundles must be stopped without changing each bundle's
-	 * persistent <i>autostart setting</i>. If this Framework implements the
-	 * optional <i>Start Level Service Specification</i>, then the start level
-	 * of this Framework is moved to start level zero (0), as described in the
-	 * <i>Start Level Service Specification</i>. Any exceptions that occur
-	 * during bundle stopping must be wrapped in a {@link BundleException} and
-	 * then published as a framework event of type {@link FrameworkEvent#ERROR}</li>
+	 * persistent <i>autostart setting</i>. The start level of this Framework is
+	 * moved to start level zero (0), as described in the <i>Start Level
+	 * Specification</i>. Any exceptions that occur during bundle stopping must
+	 * be wrapped in a {@link BundleException} and then published as a framework
+	 * event of type {@link FrameworkEvent#ERROR}</li>
 	 * <li>Unregister all services registered by this Framework.</li>
 	 * <li>Event handling is disabled.</li>
 	 * <li>This Framework's state is set to {@link #RESOLVED}.</li>
@@ -196,9 +199,9 @@
 	 * @throws BundleException If stopping this Framework could not be
 	 *         initiated.
 	 * @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 Level Service Specification"
+	 * @see "Start Level Specification"
 	 */
 	void stop() throws BundleException;
 
@@ -213,7 +216,7 @@
 	 * @throws BundleException If stopping this Framework could not be
 	 *         initiated.
 	 * @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 #stop()
 	 */
@@ -227,7 +230,7 @@
 	 * 
 	 * @throws BundleException This Framework cannot be uninstalled.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,LIFECYCLE]</code>, and the Java
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java
 	 *         Runtime Environment supports permissions.
 	 */
 	void uninstall() throws BundleException;
@@ -248,7 +251,7 @@
 	 * @throws BundleException If stopping and restarting this Framework could
 	 *         not be initiated.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,LIFECYCLE]</code>, and the Java
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java
 	 *         Runtime Environment supports permissions.
 	 */
 	void update() throws BundleException;
@@ -265,7 +268,7 @@
 	 * @throws BundleException If stopping and restarting this Framework could
 	 *         not be initiated.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,LIFECYCLE]</code>, and the Java
+	 *         {@code AdminPermission[this,LIFECYCLE]}, and the Java
 	 *         Runtime Environment supports permissions.
 	 */
 	void update(InputStream in) throws BundleException;
@@ -281,12 +284,12 @@
 
 	/**
 	 * Returns the Framework location identifier. This Framework is assigned the
-	 * unique location &quot;<code>System Bundle</code>&quot; since this
+	 * unique location &quot;{@code System Bundle}&quot; since this
 	 * Framework is also a System Bundle.
 	 * 
-	 * @return The string &quot;<code>System Bundle</code>&quot;.
+	 * @return The string &quot;{@code System Bundle}&quot;.
 	 * @throws SecurityException If the caller does not have the appropriate
-	 *         <code>AdminPermission[this,METADATA]</code>, and the Java Runtime
+	 *         {@code AdminPermission[this,METADATA]}, and the Java Runtime
 	 *         Environment supports permissions.
 	 * @see Bundle#getLocation()
 	 * @see Constants#SYSTEM_BUNDLE_LOCATION
@@ -296,7 +299,7 @@
 	/**
 	 * Returns the symbolic name of this Framework. The symbolic name is unique
 	 * for the implementation of the framework. However, the symbolic name
-	 * &quot;<code>system.bundle</code>&quot; must be recognized as an alias to
+	 * &quot;{@code system.bundle}&quot; must be recognized as an alias to
 	 * the implementation-defined symbolic name since this Framework is also a
 	 * System Bundle.
 	 * 
@@ -305,4 +308,56 @@
 	 * @see Constants#SYSTEM_BUNDLE_SYMBOLICNAME
 	 */
 	String getSymbolicName();
+
+	/**
+	 * Returns {@code null} as a framework implementation does not have a
+	 * proper bundle from which to return entry paths.
+	 * 
+	 * @param path Ignored.
+	 * @return {@code null} as a framework implementation does not have a
+	 *         proper bundle from which to return entry paths.
+	 */
+	Enumeration<String> getEntryPaths(String path);
+
+	/**
+	 * Returns {@code null} as a framework implementation does not have a
+	 * proper bundle from which to return an entry.
+	 * 
+	 * @param path Ignored.
+	 * @return {@code null} as a framework implementation does not have a
+	 *         proper bundle from which to return an entry.
+	 */
+	URL getEntry(String path);
+
+	/**
+	 * Returns {@code null} as a framework implementation does not have a proper
+	 * bundle from which to return entries.
+	 * 
+	 * @param path Ignored.
+	 * @param filePattern Ignored.
+	 * @param recurse Ignored.
+	 * @return {@code null} as a framework implementation does not have a proper
+	 *         bundle from which to return entries.
+	 */
+	Enumeration<URL> findEntries(String path, String filePattern,
+			boolean recurse);
+
+	/**
+	 * Adapt this Framework to the specified type.
+	 * 
+	 * <p>
+	 * Adapting this Framework to the specified type may require certain checks,
+	 * including security checks, to succeed. If a check does not succeed, then
+	 * this Framework cannot be adapted and {@code null} is returned. If this
+	 * Framework is not {@link #init() initialized}, then {@code null} is
+	 * returned if the specified type is one of the OSGi defined types to which
+	 * a system bundle can be adapted.
+	 * 
+	 * @param <A> The type to which this Framework is to be adapted.
+	 * @param type Class object for the type to which this Framework is to be
+	 *        adapted.
+	 * @return The object, of the specified type, to which this Framework has
+	 *         been adapted or {@code null} if this Framework cannot be adapted
+	 */
+	<A> A adapt(Class<A> type);
 }
diff --git a/framework/src/main/java/org/osgi/framework/launch/FrameworkFactory.java b/framework/src/main/java/org/osgi/framework/launch/FrameworkFactory.java
index bcb6da3..649ef4b 100644
--- a/framework/src/main/java/org/osgi/framework/launch/FrameworkFactory.java
+++ b/framework/src/main/java/org/osgi/framework/launch/FrameworkFactory.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.
@@ -41,11 +41,12 @@
  * the resource and then load and construct a FrameworkFactory object for the
  * framework implementation. The FrameworkFactory implementation class must have
  * a public, no-argument constructor. Java&#8482; SE 6 introduced the
- * <code>ServiceLoader</code> class which can create a FrameworkFactory instance
+ * {@code ServiceLoader} class which can create a FrameworkFactory instance
  * from the resource.
  * 
  * @ThreadSafe
- * @version $Revision: 6888 $
+ * @noimplement
+ * @version $Id: c370e19dba77231f0dbf1601218ad97b20391ea0 $
  */
 public interface FrameworkFactory {
 
@@ -58,15 +59,15 @@
 	 *        use some reasonable default configuration appropriate for the
 	 *        current VM. For example, the system packages for the current
 	 *        execution environment should be properly exported. The specified
-	 *        configuration argument may be <code>null</code>. The created
+	 *        configuration argument may be {@code null}. The created
 	 *        framework instance must copy any information needed from the
 	 *        specified configuration argument since the configuration argument
 	 *        can be changed after the framework instance has been created.
 	 * @return A new, configured {@link Framework} instance. The framework
 	 *         instance must be in the {@link Bundle#INSTALLED} state.
 	 * @throws SecurityException If the caller does not have
-	 *         <code>AllPermission</code>, and the Java Runtime Environment
+	 *         {@code AllPermission}, and the Java Runtime Environment
 	 *         supports permissions.
 	 */
-	Framework newFramework(Map configuration);
+	Framework newFramework(Map<String, String> configuration);
 }
diff --git a/framework/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java b/framework/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java
index 67ba3e9..abe1515 100644
--- a/framework/src/main/java/org/osgi/service/packageadmin/ExportedPackage.java
+++ b/framework/src/main/java/org/osgi/service/packageadmin/ExportedPackage.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.
@@ -31,18 +31,21 @@
  * 
  * <p>
  * The information about an exported package provided by this object may change.
- * An <code>ExportedPackage</code> object becomes stale if the package it
+ * An {@code ExportedPackage} object becomes stale if the package it
  * references has been updated or removed as a result of calling
- * <code>PackageAdmin.refreshPackages()</code>.
+ * {@code PackageAdmin.refreshPackages()}.
  * 
- * If this object becomes stale, its <code>getName()</code> and
- * <code>getVersion()</code> methods continue to return their original values,
- * <code>isRemovalPending()</code> returns <code>true</code>, and
- * <code>getExportingBundle()</code> and <code>getImportingBundles()</code>
- * return <code>null</code>.
+ * If this object becomes stale, its {@code getName()} and
+ * {@code getVersion()} methods continue to return their original values,
+ * {@code isRemovalPending()} returns {@code true}, and
+ * {@code getExportingBundle()} and {@code getImportingBundles()}
+ * return {@code null}.
  * 
  * @ThreadSafe
- * @version $Revision: 5673 $
+ * @noimplement
+ * @deprecated The PackageAdmin service has been replaced by the
+ *             <code>org.osgi.framework.wiring</code> package.
+ * @version $Id: c56b99465e3f62a9808297a47de8cb7edb802119 $
  */
 public interface ExportedPackage {
 	/**
@@ -56,8 +59,8 @@
 	 * Returns the bundle exporting the package associated with this exported
 	 * package.
 	 * 
-	 * @return The exporting bundle, or <code>null</code> if this
-	 *         <code>ExportedPackage</code> object has become stale.
+	 * @return The exporting bundle, or {@code null} if this
+	 *         {@code ExportedPackage} object has become stale.
 	 */
 	public Bundle getExportingBundle();
 
@@ -71,8 +74,8 @@
 	 * in the returned array. See {@link RequiredBundle#getRequiringBundles()}.
 	 * 
 	 * @return The array of resolved bundles currently wired to this exported
-	 *         package, or <code>null</code> if this
-	 *         <code>ExportedPackage</code> object has become stale. The array
+	 *         package, or {@code null} if this
+	 *         {@code ExportedPackage} object has become stale. The array
 	 *         will be empty if no bundles are wired to this exported package.
 	 */
 	public Bundle[] getImportingBundles();
@@ -80,7 +83,7 @@
 	/**
 	 * Returns the version of this exported package.
 	 * 
-	 * @return The version of this exported package, or <code>null</code> if
+	 * @return The version of this exported package, or {@code null} if
 	 *         no version information is available.
 	 * @deprecated As of 1.2, replaced by {@link #getVersion}.
 	 */
@@ -97,14 +100,14 @@
 	public Version getVersion();
 
 	/**
-	 * Returns <code>true</code> if the package associated with this
-	 * <code>ExportedPackage</code> object has been exported by a bundle that
+	 * Returns {@code true} if the package associated with this
+	 * {@code ExportedPackage} object has been exported by a bundle that
 	 * has been updated or uninstalled.
 	 * 
-	 * @return <code>true</code> if the associated package is being exported
+	 * @return {@code true} if the associated package is being exported
 	 *         by a bundle that has been updated or uninstalled, or if this
-	 *         <code>ExportedPackage</code> object has become stale;
-	 *         <code>false</code> otherwise.
+	 *         {@code ExportedPackage} object has become stale;
+	 *         {@code false} otherwise.
 	 */
 	public boolean isRemovalPending();
 }
diff --git a/framework/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java b/framework/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java
index c93cd28..2c57890 100644
--- a/framework/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java
+++ b/framework/src/main/java/org/osgi/service/packageadmin/PackageAdmin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2001, 2009). 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.
@@ -28,7 +28,10 @@
  * with the Framework.
  * 
  * @ThreadSafe
- * @version $Revision: 6779 $
+ * @noimplement
+ * @version $Id: a268c3bdc986080fa16bdb2f56ba1d3800d030dd $
+ * @deprecated This service has been replaced by the
+ *             <code>org.osgi.framework.wiring</code> package.
  * @see org.osgi.service.packageadmin.ExportedPackage
  * @see org.osgi.service.packageadmin.RequiredBundle
  */
@@ -37,19 +40,19 @@
 	 * Gets the exported packages for the specified bundle.
 	 * 
 	 * @param bundle The bundle whose exported packages are to be returned, or
-	 *        <code>null</code> if all exported packages are to be returned. If
+	 *        {@code null} if all exported packages are to be returned. If
 	 *        the specified bundle is the system bundle (that is, the bundle
 	 *        with id zero), this method returns all the packages known to be
 	 *        exported by the system bundle. This will include the package
-	 *        specified by the <code>org.osgi.framework.system.packages</code>
+	 *        specified by the {@code org.osgi.framework.system.packages}
 	 *        system property as well as any other package exported by the
 	 *        framework implementation.
 	 * 
-	 * @return An array of exported packages, or <code>null</code> if the
+	 * @return An array of exported packages, or {@code null} if the
 	 *         specified bundle has no exported packages.
-	 * @throws IllegalArgumentException If the specified <code>Bundle</code> was
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was
 	 *         not created by the same framework instance that registered this
-	 *         <code>PackageAdmin</code> service.
+	 *         {@code PackageAdmin} service.
 	 */
 	public ExportedPackage[] getExportedPackages(Bundle bundle);
 
@@ -58,7 +61,7 @@
 	 * 
 	 * @param name The name of the exported packages to be returned.
 	 * 
-	 * @return An array of the exported packages, or <code>null</code> if no
+	 * @return An array of the exported packages, or {@code null} if no
 	 *         exported packages with the specified name exists.
 	 * @since 1.2
 	 */
@@ -73,7 +76,7 @@
 	 * 
 	 * @param name The name of the exported package to be returned.
 	 * 
-	 * @return The exported package, or <code>null</code> if no exported
+	 * @return The exported package, or {@code null} if no exported
 	 *         package with the specified name exists.
 	 * @see #getExportedPackages(String)
 	 */
@@ -101,49 +104,49 @@
 	 * graph any bundle that is wired to a package that is currently exported by
 	 * 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</code> bundles that are currently
+	 * graph may contain {@code UNINSTALLED} bundles that are currently
 	 * still exporting packages.
 	 * 
-	 * <li>Each bundle in the graph that is in the <code>ACTIVE</code> state
-	 * will be stopped as described in the <code>Bundle.stop</code> method.
+	 * <li>Each bundle in the graph that is in the {@code ACTIVE} state
+	 * will be stopped as described in the {@code Bundle.stop} method.
 	 * 
-	 * <li>Each bundle in the graph that is in the <code>RESOLVED</code> state
-	 * is unresolved and thus moved to the <code>INSTALLED</code> state. The
+	 * <li>Each bundle in the graph 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 graph are no longer
-	 * <code>RESOLVED</code>.
+	 * {@code RESOLVED}.
 	 * 
-	 * <li>Each bundle in the graph that is in the <code>UNINSTALLED</code>
+	 * <li>Each bundle in the graph that is in the {@code UNINSTALLED}
 	 * state is removed from the graph and is now completely removed from the
 	 * Framework.
 	 * 
-	 * <li>Each bundle in the graph that was in the <code>ACTIVE</code> state
-	 * prior to Step 2 is started as described in the <code>Bundle.start</code>
+	 * <li>Each bundle in the graph 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 another bundle offering a compatible package for
 	 * export has been installed in the Framework.
 	 * <li>A framework event of type
-	 * <code>FrameworkEvent.PACKAGES_REFRESHED</code> is fired.
+	 * {@code FrameworkEvent.PACKAGES_REFRESHED} is fired.
 	 * </ol>
 	 * 
 	 * <p>
 	 * For any exceptions that are thrown during any of these steps, a
-	 * <code>FrameworkEvent</code> of type <code>ERROR</code> is fired
+	 * {@code FrameworkEvent} of type {@code 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.
 	 * 
 	 * @param bundles The bundles whose exported packages are to be updated or
-	 *        removed, or <code>null</code> for all bundles updated or
+	 *        removed, or {@code null} for all bundles updated or
 	 *        uninstalled since the last call to this method.
 	 * @throws SecurityException If the caller does not have
-	 *         <code>AdminPermission[System Bundle,RESOLVE]</code> and the Java
+	 *         {@code AdminPermission[System Bundle,RESOLVE]} and the Java
 	 *         runtime environment supports permissions.
-	 * @throws IllegalArgumentException If the specified <code>Bundle</code>s
+	 * @throws IllegalArgumentException If the specified {@code Bundle}s
 	 *         were not created by the same framework instance that registered
-	 *         this <code>PackageAdmin</code> service.
+	 *         this {@code PackageAdmin} service.
 	 */
 	public void refreshPackages(Bundle[] bundles);
 
@@ -155,20 +158,20 @@
 	 * resolve all unresolved bundles installed in the framework.
 	 * 
 	 * <p>
-	 * If <code>null</code> is specified then the Framework will attempt to
+	 * If {@code null} is 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</code> to resolve all
+	 * @param bundles The bundles to resolve or {@code null} to resolve all
 	 *        unresolved bundles installed in the Framework.
-	 * @return <code>true</code> if all specified bundles are resolved;
+	 * @return {@code true} if all specified bundles are resolved;
 	 * @throws SecurityException If the caller does not have
-	 *         <code>AdminPermission[System Bundle,RESOLVE]</code> and the Java
+	 *         {@code AdminPermission[System Bundle,RESOLVE]} and the Java
 	 *         runtime environment supports permissions.
-	 * @throws IllegalArgumentException If the specified <code>Bundle</code>s
+	 * @throws IllegalArgumentException If the specified {@code Bundle}s
 	 *         were not created by the same framework instance that registered
-	 *         this <code>PackageAdmin</code> service.
+	 *         this {@code PackageAdmin} service.
 	 * @since 1.2
 	 */
 	public boolean resolveBundles(Bundle[] bundles);
@@ -177,12 +180,12 @@
 	 * Returns an array of required bundles having the specified symbolic name.
 	 * 
 	 * <p>
-	 * If <code>null</code> is specified, then all required bundles will be
+	 * If {@code null} is specified, then all required bundles will be
 	 * returned.
 	 * 
-	 * @param symbolicName The bundle symbolic name or <code>null</code> for
+	 * @param symbolicName The bundle symbolic name or {@code null} for
 	 *        all required bundles.
-	 * @return An array of required bundles or <code>null</code> if no
+	 * @return An array of required bundles or {@code null} if no
 	 *         required bundles exist for the specified symbolic name.
 	 * @since 1.2
 	 */
@@ -191,7 +194,7 @@
 	/**
 	 * Returns the bundles with the specified symbolic name whose bundle version
 	 * is within the specified version range. If no bundles are installed that
-	 * have the specified symbolic name, then <code>null</code> is returned.
+	 * have the specified symbolic name, then {@code null} is returned.
 	 * If a version range is specified, then only the bundles that have the
 	 * specified symbolic name and whose bundle versions belong to the specified
 	 * version range are returned. The returned bundles are ordered by version
@@ -201,31 +204,31 @@
 	 * @see org.osgi.framework.Constants#BUNDLE_VERSION_ATTRIBUTE
 	 * @param symbolicName The symbolic name of the desired bundles.
 	 * @param versionRange The version range of the desired bundles, or
-	 *        <code>null</code> if all versions are desired.
+	 *        {@code null} if all versions are desired.
 	 * @return An array of bundles with the specified name belonging to the
 	 *         specified version range ordered in descending version order, or
-	 *         <code>null</code> if no bundles are found.
+	 *         {@code null} if no bundles are found.
 	 * @since 1.2
 	 */
 	public Bundle[] getBundles(String symbolicName, String versionRange);
 
 	/**
 	 * Returns an array of attached fragment bundles for the specified bundle.
-	 * If the specified bundle is a fragment then <code>null</code> is returned.
+	 * If the specified bundle is a fragment then {@code null} is returned.
 	 * If no fragments are attached to the specified bundle then
-	 * <code>null</code> is returned.
+	 * {@code null} is returned.
 	 * <p>
 	 * This method does not attempt to resolve the specified bundle. If the
-	 * specified bundle is not resolved then <code>null</code> is returned.
+	 * specified bundle is not resolved then {@code null} is returned.
 	 * 
 	 * @param bundle The bundle whose attached fragment bundles are to be
 	 *        returned.
-	 * @return An array of fragment bundles or <code>null</code> if the bundle
+	 * @return An array of fragment bundles or {@code null} if the bundle
 	 *         does not have any attached fragment bundles or the bundle is not
 	 *         resolved.
-	 * @throws IllegalArgumentException If the specified <code>Bundle</code> was
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was
 	 *         not created by the same framework instance that registered this
-	 *         <code>PackageAdmin</code> service.
+	 *         {@code PackageAdmin} service.
 	 * @since 1.2
 	 */
 	public Bundle[] getFragments(Bundle bundle);
@@ -236,11 +239,11 @@
 	 * 
 	 * @param bundle The fragment bundle whose host bundles are to be returned.
 	 * @return An array containing the host bundles to which the specified
-	 *         fragment is attached or <code>null</code> if the specified bundle
+	 *         fragment is attached or {@code null} if the specified bundle
 	 *         is not a fragment or is not attached to any host bundles.
-	 * @throws IllegalArgumentException If the specified <code>Bundle</code> was
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was
 	 *         not created by the same framework instance that registered this
-	 *         <code>PackageAdmin</code> service.
+	 *         {@code PackageAdmin} service.
 	 * @since 1.2
 	 */
 	public Bundle[] getHosts(Bundle bundle);
@@ -249,13 +252,13 @@
 	 * Returns the bundle from which the specified class is loaded. The class
 	 * loader of the returned bundle must have been used to load the specified
 	 * class. If the class was not loaded by a bundle class loader then
-	 * <code>null</code> is returned.
+	 * {@code null} is returned.
 	 * 
 	 * @param clazz The class object from which to locate the bundle.
 	 * @return The bundle from which the specified class is loaded or
-	 *         <code>null</code> if the class was not loaded by a bundle class
+	 *         {@code null} if the class was not loaded by a bundle class
 	 *         loader created by the same framework instance that registered
-	 *         this <code>PackageAdmin</code> service.
+	 *         this {@code PackageAdmin} service.
 	 * @since 1.2
 	 */
 	public Bundle getBundle(Class clazz);
@@ -264,7 +267,7 @@
 	 * Bundle type indicating the bundle is a fragment bundle.
 	 * 
 	 * <p>
-	 * The value of <code>BUNDLE_TYPE_FRAGMENT</code> is 0x00000001.
+	 * The value of {@code BUNDLE_TYPE_FRAGMENT} is 0x00000001.
 	 * 
 	 * @since 1.2
 	 */
@@ -286,9 +289,9 @@
 	 * 
 	 * @param bundle The bundle for which to return the special type.
 	 * @return The special type of the bundle.
-	 * @throws IllegalArgumentException If the specified <code>Bundle</code> was
+	 * @throws IllegalArgumentException If the specified {@code Bundle} was
 	 *         not created by the same framework instance that registered this
-	 *         <code>PackageAdmin</code> service.
+	 *         {@code PackageAdmin} service.
 	 * @since 1.2
 	 */
 	public int getBundleType(Bundle bundle);
diff --git a/framework/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java b/framework/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java
index b15c5df..34c0b08 100644
--- a/framework/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java
+++ b/framework/src/main/java/org/osgi/service/packageadmin/RequiredBundle.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2004, 2008). 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.
@@ -25,25 +25,28 @@
  * Objects implementing this interface are created by the Package Admin service.
  * 
  * <p>
- * The term <i>required bundle</i> refers to a resolved bundle that has a
- * bundle symbolic name and is not a fragment. That is, a bundle that may be
- * required by other bundles. This bundle may or may not be currently required
- * by other bundles.
+ * The term <i>required bundle</i> refers to a resolved bundle that has a bundle
+ * symbolic name and is not a fragment. That is, a bundle that may be required
+ * by other bundles. This bundle may or may not be currently required by other
+ * bundles.
  * 
  * <p>
  * The information about a required bundle provided by this object may change. A
- * <code>RequiredBundle</code> object becomes stale if an exported package of
+ * {@code RequiredBundle} object becomes stale if an exported package of
  * the bundle it references has been updated or removed as a result of calling
- * <code>PackageAdmin.refreshPackages()</code>).
+ * {@code PackageAdmin.refreshPackages()}).
  * 
- * If this object becomes stale, its <code>getSymbolicName()</code> and
- * <code>getVersion()</code> methods continue to return their original values,
- * <code>isRemovalPending()</code> returns true, and <code>getBundle()</code>
- * and <code>getRequiringBundles()</code> return <code>null</code>.
+ * If this object becomes stale, its {@code getSymbolicName()} and
+ * {@code getVersion()} methods continue to return their original values,
+ * {@code isRemovalPending()} returns true, and {@code getBundle()}
+ * and {@code getRequiringBundles()} return {@code null}.
  * 
  * @since 1.2
  * @ThreadSafe
- * @version $Revision: 5673 $
+ * @noimplement
+ * @deprecated The PackageAdmin service has been replaced by the
+ *             <code>org.osgi.framework.wiring</code> package.
+ * @version $Id: 1606b0422cae6769b7eedc2d565df61841da1e22 $
  */
 public interface RequiredBundle {
 	/**
@@ -56,8 +59,8 @@
 	/**
 	 * Returns the bundle associated with this required bundle.
 	 * 
-	 * @return The bundle, or <code>null</code> if this
-	 *         <code>RequiredBundle</code> object has become stale.
+	 * @return The bundle, or {@code null} if this
+	 *         {@code RequiredBundle} object has become stale.
 	 */
 	public Bundle getBundle();
 
@@ -70,7 +73,7 @@
 	 * included in the returned array.
 	 * 
 	 * @return An array of bundles currently requiring this required bundle, or
-	 *         <code>null</code> if this <code>RequiredBundle</code> object
+	 *         {@code null} if this {@code RequiredBundle} object
 	 *         has become stale. The array will be empty if no bundles require
 	 *         this required package.
 	 */
@@ -86,12 +89,12 @@
 	public Version getVersion();
 
 	/**
-	 * Returns <code>true</code> if the bundle associated with this
-	 * <code>RequiredBundle</code> object has been updated or uninstalled.
+	 * Returns {@code true} if the bundle associated with this
+	 * {@code RequiredBundle} object has been updated or uninstalled.
 	 * 
-	 * @return <code>true</code> if the required bundle has been updated or
-	 *         uninstalled, or if the <code>RequiredBundle</code> object has
-	 *         become stale; <code>false</code> otherwise.
+	 * @return {@code true} if the required bundle has been updated or
+	 *         uninstalled, or if the {@code RequiredBundle} object has
+	 *         become stale; {@code false} otherwise.
 	 */
 	public boolean isRemovalPending();
 }
diff --git a/framework/src/main/java/org/osgi/service/startlevel/StartLevel.java b/framework/src/main/java/org/osgi/service/startlevel/StartLevel.java
index 8a69b03..5efb41c 100644
--- a/framework/src/main/java/org/osgi/service/startlevel/StartLevel.java
+++ b/framework/src/main/java/org/osgi/service/startlevel/StartLevel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2009). All Rights Reserved.
+ * 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.
@@ -31,7 +31,7 @@
  * higher start level than 1.
  * <p>
  * Access to the StartLevel service is protected by corresponding
- * <code>ServicePermission</code>. In addition <code>AdminPermission</code>
+ * {@code ServicePermission}. In addition {@code AdminPermission}
  * is required to actually modify start level information.
  * <p>
  * Start Level support in the Framework includes the ability to control the
@@ -48,17 +48,17 @@
  * When the Framework is launched, the Framework will enter start level one and
  * all bundles which are assigned to start level one and whose autostart setting
  * indicates the bundle should be started are started as described in the
- * <code>Bundle.start</code> method. The Framework will continue to increase
+ * {@code Bundle.start} method. The Framework will continue to increase
  * the start level, starting bundles at each start level, until the Framework
  * has reached a beginning start level. At this point the Framework has
  * completed starting bundles and will then fire a Framework event of type
- * <code>FrameworkEvent.STARTED</code> to announce it has completed its
+ * {@code FrameworkEvent.STARTED} to announce it has completed its
  * launch.
  * 
  * <p>
  * Within a start level, bundles may be started in an order defined by the
  * Framework implementation. This may be something like ascending
- * <code>Bundle.getBundleId</code> order or an order based upon dependencies
+ * {@code Bundle.getBundleId} order or an order based upon dependencies
  * between bundles. A similar but reversed order may be used when stopping
  * bundles within a start level.
  * 
@@ -67,7 +67,10 @@
  * start level of the framework.
  * 
  * @ThreadSafe
- * @version $Revision: 6747 $
+ * @noimplement
+ * @version $Id: bf1b71ed6c9f9d75785b26dccb34362017d93f4a $
+ * @deprecated This service has been replaced by the
+ *             <code>org.osgi.framework.startlevel</code> package.
  */
 public interface StartLevel {
 	/**
@@ -103,12 +106,12 @@
 	 * 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 #isBundleActivationPolicyUsed(Bundle)} returns <code>true</code>
+	 * {@link #isBundleActivationPolicyUsed(Bundle)} 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</code> to announce it has moved
+	 * {@code FrameworkEvent.STARTLEVEL_CHANGED} to announce it has moved
 	 * to the specified start level.
 	 * 
 	 * <p>
@@ -126,13 +129,13 @@
 	 * </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</code> to announce it has moved
+	 * {@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</code>
+	 * 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 return.
 	 * 
@@ -140,7 +143,7 @@
 	 * @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]</code> and the
+	 *         {@code AdminPermission[System Bundle,STARTLEVEL]} and the
 	 *         Java runtime environment supports permissions.
 	 */
 	public void setStartLevel(int startlevel);
@@ -153,7 +156,7 @@
 	 * @throws java.lang.IllegalArgumentException If the specified bundle has
 	 *         been uninstalled or if the specified bundle was not created by
 	 *         the same framework instance that registered this
-	 *         <code>StartLevel</code> service.
+	 *         {@code StartLevel} service.
 	 */
 	public int getBundleStartLevel(Bundle bundle);
 
@@ -171,7 +174,7 @@
 	 * specified 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 #isBundleActivationPolicyUsed(Bundle)} returns <code>true</code>
+	 * {@link #isBundleActivationPolicyUsed(Bundle)} returns {@code true}
 	 * for the bundle. The actual starting of this bundle must occur
 	 * asynchronously.
 	 * <p>
@@ -187,9 +190,9 @@
 	 *         uninstalled, or if the specified start level is less than or
 	 *         equal to zero, or if the specified bundle is the system bundle,
 	 *         or if the specified bundle was not created by the same framework
-	 *         instance that registered this <code>StartLevel</code> service.
+	 *         instance that registered this {@code StartLevel} service.
 	 * @throws SecurityException If the caller does not have
-	 *         <code>AdminPermission[bundle,EXECUTE]</code> and the Java runtime
+	 *         {@code AdminPermission[bundle,EXECUTE]} and the Java runtime
 	 *         environment supports permissions.
 	 */
 	public void setBundleStartLevel(Bundle bundle, int startlevel);
@@ -213,7 +216,7 @@
 	 * Framework.
 	 * 
 	 * <p>
-	 * When a Bundle is installed via <code>BundleContext.installBundle</code>,
+	 * When a Bundle is installed via {@code BundleContext.installBundle},
 	 * it is assigned the initial bundle start level value.
 	 * 
 	 * <p>
@@ -227,7 +230,7 @@
 	 * @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]</code> and the
+	 *         {@code AdminPermission[System Bundle,STARTLEVEL]} and the
 	 *         Java runtime environment supports permissions.
 	 */
 	public void setInitialBundleStartLevel(int startlevel);
@@ -240,13 +243,13 @@
 	 * started when its start level is reached.
 	 * 
 	 * @param bundle The bundle whose autostart setting is to be examined.
-	 * @return <code>true</code> if the autostart setting of the bundle
-	 *         indicates the bundle is to be started. <code>false</code>
+	 * @return {@code true} if the autostart setting of the bundle
+	 *         indicates the bundle is to be started. {@code false}
 	 *         otherwise.
 	 * @throws java.lang.IllegalArgumentException If the specified bundle has
 	 *         been uninstalled or if the specified bundle was not created by
 	 *         the same framework instance that registered this
-	 *         <code>StartLevel</code> service.
+	 *         {@code StartLevel} service.
 	 * @see Bundle#START_TRANSIENT
 	 */
 	public boolean isBundlePersistentlyStarted(Bundle bundle);
@@ -259,13 +262,13 @@
 	 * activation policy is to be used when the bundle is started.
 	 * 
 	 * @param bundle The bundle whose autostart setting is to be examined.
-	 * @return <code>true</code> if the bundle's autostart setting indicates the
+	 * @return {@code true} if the bundle's autostart setting indicates the
 	 *         activation policy declared in the manifest must be used.
-	 *         <code>false</code> if the bundle must be eagerly activated.
+	 *         {@code false} if the bundle must be eagerly activated.
 	 * @throws java.lang.IllegalArgumentException If the specified bundle has
 	 *         been uninstalled or if the specified bundle was not created by
 	 *         the same framework instance that registered this
-	 *         <code>StartLevel</code> service.
+	 *         {@code StartLevel} service.
 	 * @since 1.1
 	 * @see Bundle#START_ACTIVATION_POLICY
 	 */
diff --git a/framework/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java b/framework/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java
index 1ad37a2..c20a051 100644
--- a/framework/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java
+++ b/framework/src/main/java/org/osgi/service/url/AbstractURLStreamHandlerService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ * 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.
@@ -19,16 +19,16 @@
 import java.net.*;
 
 /**
- * Abstract implementation of the <code>URLStreamHandlerService</code>
+ * Abstract implementation of the {@code URLStreamHandlerService}
  * interface. All the methods simply invoke the corresponding methods on
- * <code>java.net.URLStreamHandler</code> except for <code>parseURL</code>
- * and <code>setURL</code>, which use the <code>URLStreamHandlerSetter</code>
+ * {@code java.net.URLStreamHandler} except for {@code parseURL}
+ * and {@code setURL}, which use the {@code URLStreamHandlerSetter}
  * parameter. Subclasses of this abstract class should not need to override the
- * <code>setURL</code> and <code>parseURL(URLStreamHandlerSetter,...)</code>
+ * {@code setURL} and {@code parseURL(URLStreamHandlerSetter,...)}
  * methods.
  * 
  * @ThreadSafe
- * @version $Revision: 5673 $
+ * @version $Id: 465a0ed86f5d49b338ffc6a13bb68f60f04e54d6 $
  */
 public abstract class AbstractURLStreamHandlerService extends URLStreamHandler
 		implements URLStreamHandlerService {
@@ -39,18 +39,18 @@
 			throws java.io.IOException;
 
 	/**
-	 * The <code>URLStreamHandlerSetter</code> object passed to the parseURL
+	 * The {@code URLStreamHandlerSetter} object passed to the parseURL
 	 * method.
 	 */
 	protected volatile URLStreamHandlerSetter	realHandler;
 
 	/**
-	 * Parse a URL using the <code>URLStreamHandlerSetter</code> object. This
-	 * method sets the <code>realHandler</code> field with the specified
-	 * <code>URLStreamHandlerSetter</code> object and then calls
-	 * <code>parseURL(URL,String,int,int)</code>.
+	 * Parse a URL using the {@code URLStreamHandlerSetter} object. This
+	 * method sets the {@code realHandler} field with the specified
+	 * {@code URLStreamHandlerSetter} object and then calls
+	 * {@code parseURL(URL,String,int,int)}.
 	 * 
-	 * @param realHandler The object on which the <code>setURL</code> method
+	 * @param realHandler The object on which the {@code setURL} method
 	 *        must be invoked for the specified URL.
 	 * @see "java.net.URLStreamHandler.parseURL"
 	 */
@@ -61,7 +61,7 @@
 	}
 
 	/**
-	 * This method calls <code>super.toExternalForm</code>.
+	 * This method calls {@code super.toExternalForm}.
 	 * 
 	 * @see "java.net.URLStreamHandler.toExternalForm"
 	 */
@@ -70,7 +70,7 @@
 	}
 
 	/**
-	 * This method calls <code>super.equals(URL,URL)</code>.
+	 * This method calls {@code super.equals(URL,URL)}.
 	 * 
 	 * @see "java.net.URLStreamHandler.equals(URL,URL)"
 	 */
@@ -79,7 +79,7 @@
 	}
 
 	/**
-	 * This method calls <code>super.getDefaultPort</code>.
+	 * This method calls {@code super.getDefaultPort}.
 	 * 
 	 * @see "java.net.URLStreamHandler.getDefaultPort"
 	 */
@@ -88,7 +88,7 @@
 	}
 
 	/**
-	 * This method calls <code>super.getHostAddress</code>.
+	 * This method calls {@code super.getHostAddress}.
 	 * 
 	 * @see "java.net.URLStreamHandler.getHostAddress"
 	 */
@@ -97,7 +97,7 @@
 	}
 
 	/**
-	 * This method calls <code>super.hashCode(URL)</code>.
+	 * This method calls {@code super.hashCode(URL)}.
 	 * 
 	 * @see "java.net.URLStreamHandler.hashCode(URL)"
 	 */
@@ -106,7 +106,7 @@
 	}
 
 	/**
-	 * This method calls <code>super.hostsEqual</code>.
+	 * This method calls {@code super.hostsEqual}.
 	 * 
 	 * @see "java.net.URLStreamHandler.hostsEqual"
 	 */
@@ -115,7 +115,7 @@
 	}
 
 	/**
-	 * This method calls <code>super.sameFile</code>.
+	 * This method calls {@code super.sameFile}.
 	 * 
 	 * @see "java.net.URLStreamHandler.sameFile"
 	 */
@@ -125,7 +125,7 @@
 
 	/**
 	 * This method calls
-	 * <code>realHandler.setURL(URL,String,String,int,String,String)</code>.
+	 * {@code realHandler.setURL(URL,String,String,int,String,String)}.
 	 * 
 	 * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String)"
 	 * @deprecated This method is only for compatibility with handlers written
@@ -138,7 +138,7 @@
 
 	/**
 	 * This method calls
-	 * <code>realHandler.setURL(URL,String,String,int,String,String,String,String)</code>.
+	 * {@code realHandler.setURL(URL,String,String,int,String,String,String,String)}.
 	 * 
 	 * @see "java.net.URLStreamHandler.setURL(URL,String,String,int,String,String,String,String)"
 	 */
diff --git a/framework/src/main/java/org/osgi/service/url/URLConstants.java b/framework/src/main/java/org/osgi/service/url/URLConstants.java
index ae95305..fbf768b 100644
--- a/framework/src/main/java/org/osgi/service/url/URLConstants.java
+++ b/framework/src/main/java/org/osgi/service/url/URLConstants.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ * 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.
@@ -18,15 +18,16 @@
 
 /**
  * Defines standard names for property keys associated with
- * {@link URLStreamHandlerService} and <code>java.net.ContentHandler</code>
+ * {@link URLStreamHandlerService} and {@code java.net.ContentHandler}
  * services.
  * 
  * <p>
  * The values associated with these keys are of type
- * <code>java.lang.String[]</code> or <code>java.lang.String</code>, unless
+ * {@code java.lang.String[]} or {@code java.lang.String}, unless
  * otherwise indicated.
  * 
- * @version $Revision: 5673 $
+ * @noimplement
+ * @version $Id: 5ec8db316249f4b956fe083b986c11153d0fa8fe $
  */
 public interface URLConstants {
 	/**
diff --git a/framework/src/main/java/org/osgi/service/url/URLStreamHandlerService.java b/framework/src/main/java/org/osgi/service/url/URLStreamHandlerService.java
index b1ff7d8..7cc5d6e 100644
--- a/framework/src/main/java/org/osgi/service/url/URLStreamHandlerService.java
+++ b/framework/src/main/java/org/osgi/service/url/URLStreamHandlerService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ * 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.
@@ -20,22 +20,22 @@
 
 /**
  * Service interface with public versions of the protected
- * <code>java.net.URLStreamHandler</code> methods.
+ * {@code java.net.URLStreamHandler} methods.
  * <p>
  * The important differences between this interface and the
- * <code>URLStreamHandler</code> class are that the <code>setURL</code>
- * method is absent and the <code>parseURL</code> method takes a
+ * {@code URLStreamHandler} class are that the {@code setURL}
+ * method is absent and the {@code parseURL} method takes a
  * {@link URLStreamHandlerSetter} object as the first argument. Classes
- * implementing this interface must call the <code>setURL</code> method on the
- * <code>URLStreamHandlerSetter</code> object received in the
- * <code>parseURL</code> method instead of
- * <code>URLStreamHandler.setURL</code> to avoid a
- * <code>SecurityException</code>.
+ * implementing this interface must call the {@code setURL} method on the
+ * {@code URLStreamHandlerSetter} object received in the
+ * {@code parseURL} method instead of
+ * {@code URLStreamHandler.setURL} to avoid a
+ * {@code SecurityException}.
  * 
  * @see AbstractURLStreamHandlerService
  * 
  * @ThreadSafe
- * @version $Revision: 5673 $
+ * @version $Id: 4982ef5b407669975afe2856a9702246d2d9c2ba $
  */
 public interface URLStreamHandlerService {
 	/**
@@ -44,11 +44,11 @@
 	public URLConnection openConnection(URL u) throws java.io.IOException;
 
 	/**
-	 * Parse a URL. This method is called by the <code>URLStreamHandler</code>
-	 * proxy, instead of <code>java.net.URLStreamHandler.parseURL</code>,
-	 * passing a <code>URLStreamHandlerSetter</code> object.
+	 * Parse a URL. This method is called by the {@code URLStreamHandler}
+	 * proxy, instead of {@code java.net.URLStreamHandler.parseURL},
+	 * passing a {@code URLStreamHandlerSetter} object.
 	 * 
-	 * @param realHandler The object on which <code>setURL</code> must be
+	 * @param realHandler The object on which {@code setURL} must be
 	 *        invoked for this URL.
 	 * @see "java.net.URLStreamHandler.parseURL"
 	 */
diff --git a/framework/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java b/framework/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java
index 36bdce8..dd2e0c2 100644
--- a/framework/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java
+++ b/framework/src/main/java/org/osgi/service/url/URLStreamHandlerSetter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
+ * 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.
@@ -19,20 +19,20 @@
 import java.net.URL;
 
 /**
- * Interface used by <code>URLStreamHandlerService</code> objects to call the
- * <code>setURL</code> method on the proxy <code>URLStreamHandler</code>
+ * Interface used by {@code URLStreamHandlerService} objects to call the
+ * {@code setURL} method on the proxy {@code URLStreamHandler}
  * object.
  * 
  * <p>
  * Objects of this type are passed to the
  * {@link URLStreamHandlerService#parseURL} method. Invoking the
- * <code>setURL</code> method on the <code>URLStreamHandlerSetter</code>
- * object will invoke the <code>setURL</code> method on the proxy
- * <code>URLStreamHandler</code> object that is actually registered with
- * <code>java.net.URL</code> for the protocol.
+ * {@code setURL} method on the {@code URLStreamHandlerSetter}
+ * object will invoke the {@code setURL} method on the proxy
+ * {@code URLStreamHandler} object that is actually registered with
+ * {@code java.net.URL} for the protocol.
  * 
  * @ThreadSafe
- * @version $Revision: 5673 $
+ * @version $Id: f55d4c29678503c244f56dcb2b5621b3be11cc8d $
  */
 public interface URLStreamHandlerSetter {
 	/**
diff --git a/framework/src/main/java/org/osgi/util/tracker/AbstractTracked.java b/framework/src/main/java/org/osgi/util/tracker/AbstractTracked.java
index 681148f..64a271a 100644
--- a/framework/src/main/java/org/osgi/util/tracker/AbstractTracked.java
+++ b/framework/src/main/java/org/osgi/util/tracker/AbstractTracked.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2007, 2008). 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.
@@ -30,11 +30,14 @@
  * tracked items. This is not a public class. It is only for use by the
  * implementation of the Tracker class.
  * 
+ * @param <S> The tracked item. It is the key.
+ * @param <T> The value mapped to the tracked item.
+ * @param <R> The reason the tracked item is being tracked or untracked.
  * @ThreadSafe
- * @version $Revision: 5871 $
+ * @version $Id: 79452e6c28683021f2bcf11d3689ec75c6b5642f $
  * @since 1.4
  */
-abstract class AbstractTracked {
+abstract class AbstractTracked<S, T, R> {
 	/* set this to true to compile in debug messages */
 	static final boolean		DEBUG	= false;
 
@@ -43,7 +46,7 @@
 	 * 
 	 * @GuardedBy this
 	 */
-	private final Map			tracked;
+	private final Map<S, T>		tracked;
 
 	/**
 	 * Modification count. This field is initialized to zero and incremented by
@@ -67,7 +70,7 @@
 	 * 
 	 * @GuardedBy this
 	 */
-	private final List			adding;
+	private final List<S>		adding;
 
 	/**
 	 * true if the tracked object is closed.
@@ -94,16 +97,16 @@
 	 * 
 	 * @GuardedBy this
 	 */
-	private final LinkedList	initial;
+	private final LinkedList<S>	initial;
 
 	/**
 	 * AbstractTracked constructor.
 	 */
 	AbstractTracked() {
-		tracked = new HashMap();
+		tracked = new HashMap<S, T>();
 		trackingCount = 0;
-		adding = new ArrayList(6);
-		initial = new LinkedList();
+		adding = new ArrayList<S>(6);
+		initial = new LinkedList<S>();
 		closed = false;
 	}
 
@@ -114,17 +117,15 @@
 	 * This method must be called from Tracker's open method while synchronized
 	 * on this object in the same synchronized block as the add listener call.
 	 * 
-	 * @param list The initial list of items to be tracked. <code>null</code>
+	 * @param list The initial list of items to be tracked. {@code null}
 	 *        entries in the list are ignored.
 	 * @GuardedBy this
 	 */
-	void setInitial(Object[] list) {
+	void setInitial(S[] list) {
 		if (list == null) {
 			return;
 		}
-		int size = list.length;
-		for (int i = 0; i < size; i++) {
-			Object item = list[i];
+		for (S item : list) {
 			if (item == null) {
 				continue;
 			}
@@ -145,7 +146,7 @@
 	 */
 	void trackInitial() {
 		while (true) {
-			Object item;
+			S item;
 			synchronized (this) {
 				if (closed || (initial.size() == 0)) {
 					/*
@@ -202,8 +203,8 @@
 	 * @param item Item to be tracked.
 	 * @param related Action related object.
 	 */
-	void track(final Object item, final Object related) {
-		final Object object;
+	void track(final S item, final R related) {
+		final T object;
 		synchronized (this) {
 			if (closed) {
 				return;
@@ -250,11 +251,11 @@
 	 * @param item Item to be tracked.
 	 * @param related Action related object.
 	 */
-	private void trackAdding(final Object item, final Object related) {
+	private void trackAdding(final S item, final R related) {
 		if (DEBUG) {
 			System.out.println("AbstractTracked.trackAdding: " + item); //$NON-NLS-1$
 		}
-		Object object = null;
+		T object = null;
 		boolean becameUntracked = false;
 		/* Call customizer outside of synchronized region */
 		try {
@@ -305,8 +306,8 @@
 	 * @param item Item to be untracked.
 	 * @param related Action related object.
 	 */
-	void untrack(final Object item, final Object related) {
-		final Object object;
+	void untrack(final S item, final R related) {
+		final T object;
 		synchronized (this) {
 			if (initial.remove(item)) { /*
 										 * if this item is already in the list
@@ -367,6 +368,18 @@
 	}
 
 	/**
+	 * Returns if the tracker is empty.
+	 * 
+	 * @return Whether the tracker is empty.
+	 * 
+	 * @GuardedBy this
+	 * @since 1.5
+	 */
+	boolean isEmpty() {
+		return tracked.isEmpty();
+	}
+
+	/**
 	 * Return the customized object for the specified item
 	 * 
 	 * @param item The item to lookup in the map
@@ -374,19 +387,19 @@
 	 * 
 	 * @GuardedBy this
 	 */
-	Object getCustomizedObject(final Object item) {
+	T getCustomizedObject(final S item) {
 		return tracked.get(item);
 	}
 
 	/**
-	 * Return the list of tracked items.
+	 * Copy the tracked items into an array.
 	 * 
 	 * @param list An array to contain the tracked items.
 	 * @return The specified list if it is large enough to hold the tracked
 	 *         items or a new array large enough to hold the tracked items.
 	 * @GuardedBy this
 	 */
-	Object[] getTracked(final Object[] list) {
+	S[] copyKeys(final S[] list) {
 		return tracked.keySet().toArray(list);
 	}
 
@@ -401,7 +414,7 @@
 	}
 
 	/**
-	 * Returns the tracking count for this <code>ServiceTracker</code> object.
+	 * Returns the tracking count for this {@code ServiceTracker} object.
 	 * 
 	 * The tracking count is initialized to 0 when this object is opened. Every
 	 * time an item is added, modified or removed from this object the tracking
@@ -415,15 +428,32 @@
 	}
 
 	/**
+	 * Copy the tracked items and associated values into the specified map.
+	 * 
+	 * @param <M> Type of {@code Map} to hold the tracked items and
+	 *        associated values.
+	 * @param map The map into which to copy the tracked items and associated
+	 *        values. This map must not be a user provided map so that user code
+	 *        is not executed while synchronized on this.
+	 * @return The specified map.
+	 * @GuardedBy this
+	 * @since 1.5
+	 */
+	<M extends Map< ? super S, ? super T>> M copyEntries(final M map) {
+		map.putAll(tracked);
+		return map;
+	}
+
+	/**
 	 * Call the specific customizer adding method. This method must not be
 	 * called while synchronized on this object.
 	 * 
 	 * @param item Item to be tracked.
 	 * @param related Action related object.
-	 * @return Customized object for the tracked item or <code>null</code> if
+	 * @return Customized object for the tracked item or {@code null} if
 	 *         the item is not to be tracked.
 	 */
-	abstract Object customizerAdding(final Object item, final Object related);
+	abstract T customizerAdding(final S item, final R related);
 
 	/**
 	 * Call the specific customizer modified method. This method must not be
@@ -433,8 +463,8 @@
 	 * @param related Action related object.
 	 * @param object Customized object for the tracked item.
 	 */
-	abstract void customizerModified(final Object item, final Object related,
-			final Object object);
+	abstract void customizerModified(final S item, final R related,
+			final T object);
 
 	/**
 	 * Call the specific customizer removed method. This method must not be
@@ -444,6 +474,6 @@
 	 * @param related Action related object.
 	 * @param object Customized object for the tracked item.
 	 */
-	abstract void customizerRemoved(final Object item, final Object related,
-			final Object object);
+	abstract void customizerRemoved(final S item, final R related,
+			final T object);
 }
diff --git a/framework/src/main/java/org/osgi/util/tracker/BundleTracker.java b/framework/src/main/java/org/osgi/util/tracker/BundleTracker.java
index 8791d98..4973503 100644
--- a/framework/src/main/java/org/osgi/util/tracker/BundleTracker.java
+++ b/framework/src/main/java/org/osgi/util/tracker/BundleTracker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2007, 2008). 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.
@@ -16,55 +16,59 @@
 
 package org.osgi.util.tracker;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.SynchronousBundleListener;
 
 /**
- * The <code>BundleTracker</code> class simplifies tracking bundles much like
- * the <code>ServiceTracker</code> simplifies tracking services.
+ * The {@code BundleTracker} class simplifies tracking bundles much like
+ * the {@code ServiceTracker} simplifies tracking services.
  * <p>
- * A <code>BundleTracker</code> is constructed with state criteria and a
- * <code>BundleTrackerCustomizer</code> object. A <code>BundleTracker</code> can
- * use the <code>BundleTrackerCustomizer</code> to select which bundles are
+ * A {@code BundleTracker} is constructed with state criteria and a
+ * {@code BundleTrackerCustomizer} object. A {@code BundleTracker} can
+ * use the {@code BundleTrackerCustomizer} to select which bundles are
  * tracked and to create a customized object to be tracked with the bundle. The
- * <code>BundleTracker</code> can then be opened to begin tracking all bundles
+ * {@code BundleTracker} can then be opened to begin tracking all bundles
  * whose state matches the specified state criteria.
  * <p>
- * The <code>getBundles</code> method can be called to get the
- * <code>Bundle</code> objects of the bundles being tracked. The
- * <code>getObject</code> method can be called to get the customized object for
+ * The {@code getBundles} method can be called to get the
+ * {@code Bundle} objects of the bundles being tracked. The
+ * {@code getObject} method can be called to get the customized object for
  * a tracked bundle.
  * <p>
- * The <code>BundleTracker</code> class is thread-safe. It does not call a
- * <code>BundleTrackerCustomizer</code> while holding any locks.
- * <code>BundleTrackerCustomizer</code> implementations must also be
+ * The {@code BundleTracker} class is thread-safe. It does not call a
+ * {@code BundleTrackerCustomizer} while holding any locks.
+ * {@code BundleTrackerCustomizer} implementations must also be
  * thread-safe.
  * 
+ * @param <T> The type of the tracked object.
  * @ThreadSafe
- * @version $Revision: 5894 $
+ * @version $Id: ebfd73a4e19f025d6ad9029d99c17944ee8c420a $
  * @since 1.4
  */
-public class BundleTracker implements BundleTrackerCustomizer {
+public class BundleTracker<T> implements BundleTrackerCustomizer<T> {
 	/* set this to true to compile in debug messages */
-	static final boolean			DEBUG	= false;
+	static final boolean				DEBUG	= false;
 
 	/**
-	 * The Bundle Context used by this <code>BundleTracker</code>.
+	 * The Bundle Context used by this {@code BundleTracker}.
 	 */
-	protected final BundleContext	context;
+	protected final BundleContext		context;
 
 	/**
-	 * The <code>BundleTrackerCustomizer</code> object for this tracker.
+	 * The {@code BundleTrackerCustomizer} object for this tracker.
 	 */
-	final BundleTrackerCustomizer	customizer;
+	final BundleTrackerCustomizer<T>	customizer;
 
 	/**
-	 * Tracked bundles: <code>Bundle</code> object -> customized Object and
-	 * <code>BundleListener</code> object
+	 * Tracked bundles: {@code Bundle} object -> customized Object and
+	 * {@code BundleListener} object
 	 */
-	private volatile Tracked		tracked;
+	private volatile Tracked			tracked;
 
 	/**
 	 * Accessor method for the current Tracked object. This method is only
@@ -81,50 +85,50 @@
 	 * State mask for bundles being tracked. This field contains the ORed values
 	 * of the bundle states being tracked.
 	 */
-	final int						mask;
+	final int	mask;
 
 	/**
-	 * Create a <code>BundleTracker</code> for bundles whose state is present in
+	 * Create a {@code BundleTracker} for bundles whose state is present in
 	 * the specified state mask.
 	 * 
 	 * <p>
 	 * Bundles whose state is present on the specified state mask will be
-	 * tracked by this <code>BundleTracker</code>.
+	 * tracked by this {@code BundleTracker}.
 	 * 
-	 * @param context The <code>BundleContext</code> against which the tracking
+	 * @param context The {@code BundleContext} against which the tracking
 	 *        is done.
-	 * @param stateMask The bit mask of the <code>OR</code>ing of the bundle
+	 * @param stateMask The bit mask of the {@code OR}ing of the bundle
 	 *        states to be tracked.
 	 * @param customizer The customizer object to call when bundles are added,
-	 *        modified, or removed in this <code>BundleTracker</code>. If
-	 *        customizer is <code>null</code>, then this
-	 *        <code>BundleTracker</code> will be used as the
-	 *        <code>BundleTrackerCustomizer</code> and this
-	 *        <code>BundleTracker</code> will call the
-	 *        <code>BundleTrackerCustomizer</code> methods on itself.
+	 *        modified, or removed in this {@code BundleTracker}. If
+	 *        customizer is {@code null}, then this
+	 *        {@code BundleTracker} will be used as the
+	 *        {@code BundleTrackerCustomizer} and this
+	 *        {@code BundleTracker} will call the
+	 *        {@code BundleTrackerCustomizer} methods on itself.
 	 * @see Bundle#getState()
 	 */
 	public BundleTracker(BundleContext context, int stateMask,
-			BundleTrackerCustomizer customizer) {
+			BundleTrackerCustomizer<T> customizer) {
 		this.context = context;
 		this.mask = stateMask;
 		this.customizer = (customizer == null) ? this : customizer;
 	}
 
 	/**
-	 * Open this <code>BundleTracker</code> and begin tracking bundles.
+	 * Open this {@code BundleTracker} and begin tracking bundles.
 	 * 
 	 * <p>
 	 * Bundle which match the state criteria specified when this
-	 * <code>BundleTracker</code> was created are now tracked by this
-	 * <code>BundleTracker</code>.
+	 * {@code BundleTracker} was created are now tracked by this
+	 * {@code BundleTracker}.
 	 * 
-	 * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
-	 *         with which this <code>BundleTracker</code> was created is no
+	 * @throws java.lang.IllegalStateException If the {@code BundleContext}
+	 *         with which this {@code BundleTracker} was created is no
 	 *         longer valid.
 	 * @throws java.lang.SecurityException If the caller and this class do not
 	 *         have the appropriate
-	 *         <code>AdminPermission[context bundle,LISTENER]</code>, and the
+	 *         {@code AdminPermission[context bundle,LISTENER]}, and the
 	 *         Java Runtime Environment supports permissions.
 	 */
 	public void open() {
@@ -150,7 +154,7 @@
 						}
 					}
 					/* set tracked with the initial bundles */
-					t.setInitial(bundles); 
+					t.setInitial(bundles);
 				}
 			}
 			tracked = t;
@@ -160,10 +164,10 @@
 	}
 
 	/**
-	 * Close this <code>BundleTracker</code>.
+	 * Close this {@code BundleTracker}.
 	 * 
 	 * <p>
-	 * This method should be called when this <code>BundleTracker</code> should
+	 * This method should be called when this {@code BundleTracker} should
 	 * end the tracking of bundles.
 	 * 
 	 * <p>
@@ -200,80 +204,81 @@
 
 	/**
 	 * Default implementation of the
-	 * <code>BundleTrackerCustomizer.addingBundle</code> method.
+	 * {@code BundleTrackerCustomizer.addingBundle} method.
 	 * 
 	 * <p>
-	 * This method is only called when this <code>BundleTracker</code> has been
-	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+	 * This method is only called when this {@code BundleTracker} has been
+	 * constructed with a {@code null BundleTrackerCustomizer} argument.
 	 * 
 	 * <p>
-	 * This implementation simply returns the specified <code>Bundle</code>.
+	 * This implementation simply returns the specified {@code Bundle}.
 	 * 
 	 * <p>
 	 * This method can be overridden in a subclass to customize the object to be
 	 * tracked for the bundle being added.
 	 * 
-	 * @param bundle The <code>Bundle</code> being added to this
-	 *        <code>BundleTracker</code> object.
+	 * @param bundle The {@code Bundle} being added to this
+	 *        {@code BundleTracker} object.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or <code>null</code> if there is no bundle event associated
+	 *        called or {@code null} if there is no bundle event associated
 	 *        with the call to this method.
 	 * @return The specified bundle.
 	 * @see BundleTrackerCustomizer#addingBundle(Bundle, BundleEvent)
 	 */
-	public Object addingBundle(Bundle bundle, BundleEvent event) {
-		return bundle;
+	public T addingBundle(Bundle bundle, BundleEvent event) {
+		T result = (T) bundle;
+		return result;
 	}
 
 	/**
 	 * Default implementation of the
-	 * <code>BundleTrackerCustomizer.modifiedBundle</code> method.
+	 * {@code BundleTrackerCustomizer.modifiedBundle} method.
 	 * 
 	 * <p>
-	 * This method is only called when this <code>BundleTracker</code> has been
-	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+	 * This method is only called when this {@code BundleTracker} has been
+	 * constructed with a {@code null BundleTrackerCustomizer} argument.
 	 * 
 	 * <p>
 	 * This implementation does nothing.
 	 * 
-	 * @param bundle The <code>Bundle</code> whose state has been modified.
+	 * @param bundle The {@code Bundle} whose state has been modified.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or <code>null</code> if there is no bundle event associated
+	 *        called or {@code null} if there is no bundle event associated
 	 *        with the call to this method.
 	 * @param object The customized object for the specified Bundle.
 	 * @see BundleTrackerCustomizer#modifiedBundle(Bundle, BundleEvent, Object)
 	 */
-	public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
+	public void modifiedBundle(Bundle bundle, BundleEvent event, T object) {
 		/* do nothing */
 	}
 
 	/**
 	 * Default implementation of the
-	 * <code>BundleTrackerCustomizer.removedBundle</code> method.
+	 * {@code BundleTrackerCustomizer.removedBundle} method.
 	 * 
 	 * <p>
-	 * This method is only called when this <code>BundleTracker</code> has been
-	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+	 * This method is only called when this {@code BundleTracker} has been
+	 * constructed with a {@code null BundleTrackerCustomizer} argument.
 	 * 
 	 * <p>
 	 * This implementation does nothing.
 	 * 
-	 * @param bundle The <code>Bundle</code> being removed.
+	 * @param bundle The {@code Bundle} being removed.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or <code>null</code> if there is no bundle event associated
+	 *        called or {@code null} if there is no bundle event associated
 	 *        with the call to this method.
 	 * @param object The customized object for the specified bundle.
 	 * @see BundleTrackerCustomizer#removedBundle(Bundle, BundleEvent, Object)
 	 */
-	public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
+	public void removedBundle(Bundle bundle, BundleEvent event, T object) {
 		/* do nothing */
 	}
 
 	/**
-	 * Return an array of <code>Bundle</code>s for all bundles being tracked by
-	 * this <code>BundleTracker</code>.
+	 * Return an array of {@code Bundle}s for all bundles being tracked by
+	 * this {@code BundleTracker}.
 	 * 
-	 * @return An array of <code>Bundle</code>s or <code>null</code> if no
+	 * @return An array of {@code Bundle}s or {@code null} if no
 	 *         bundles are being tracked.
 	 */
 	public Bundle[] getBundles() {
@@ -286,20 +291,20 @@
 			if (length == 0) {
 				return null;
 			}
-			return (Bundle[]) t.getTracked(new Bundle[length]);
+			return t.copyKeys(new Bundle[length]);
 		}
 	}
 
 	/**
-	 * Returns the customized object for the specified <code>Bundle</code> if
-	 * the specified bundle is being tracked by this <code>BundleTracker</code>.
+	 * Returns the customized object for the specified {@code Bundle} if
+	 * the specified bundle is being tracked by this {@code BundleTracker}.
 	 * 
-	 * @param bundle The <code>Bundle</code> being tracked.
-	 * @return The customized object for the specified <code>Bundle</code> or
-	 *         <code>null</code> if the specified <code>Bundle</code> is not
+	 * @param bundle The {@code Bundle} being tracked.
+	 * @return The customized object for the specified {@code Bundle} or
+	 *         {@code null} if the specified {@code Bundle} is not
 	 *         being tracked.
 	 */
-	public Object getObject(Bundle bundle) {
+	public T getObject(Bundle bundle) {
 		final Tracked t = tracked();
 		if (t == null) { /* if BundleTracker is not open */
 			return null;
@@ -310,14 +315,14 @@
 	}
 
 	/**
-	 * Remove a bundle from this <code>BundleTracker</code>.
+	 * Remove a bundle from this {@code BundleTracker}.
 	 * 
-	 * The specified bundle will be removed from this <code>BundleTracker</code>
+	 * The specified bundle will be removed from this {@code BundleTracker}
 	 * . If the specified bundle was being tracked then the
-	 * <code>BundleTrackerCustomizer.removedBundle</code> method will be called
+	 * {@code BundleTrackerCustomizer.removedBundle} method will be called
 	 * for that bundle.
 	 * 
-	 * @param bundle The <code>Bundle</code> to be removed.
+	 * @param bundle The {@code Bundle} to be removed.
 	 */
 	public void remove(Bundle bundle) {
 		final Tracked t = tracked();
@@ -329,7 +334,7 @@
 
 	/**
 	 * Return the number of bundles being tracked by this
-	 * <code>BundleTracker</code>.
+	 * {@code BundleTracker}.
 	 * 
 	 * @return The number of bundles being tracked.
 	 */
@@ -344,23 +349,22 @@
 	}
 
 	/**
-	 * Returns the tracking count for this <code>BundleTracker</code>.
+	 * Returns the tracking count for this {@code BundleTracker}.
 	 * 
-	 * The tracking count is initialized to 0 when this
-	 * <code>BundleTracker</code> is opened. Every time a bundle is added,
-	 * modified or removed from this <code>BundleTracker</code> the tracking
-	 * count is incremented.
+	 * The tracking count is initialized to 0 when this {@code BundleTracker} is
+	 * opened. Every time a bundle is added, modified or removed from this
+	 * {@code BundleTracker} the tracking count is incremented.
 	 * 
 	 * <p>
-	 * The tracking count can be used to determine if this
-	 * <code>BundleTracker</code> has added, modified or removed a bundle by
-	 * comparing a tracking count value previously collected with the current
-	 * tracking count value. If the value has not changed, then no bundle has
-	 * been added, modified or removed from this <code>BundleTracker</code>
-	 * since the previous tracking count was collected.
+	 * The tracking count can be used to determine if this {@code BundleTracker}
+	 * has added, modified or removed a bundle by comparing a tracking count
+	 * value previously collected with the current tracking count value. If the
+	 * value has not changed, then no bundle has been added, modified or removed
+	 * from this {@code BundleTracker} since the previous tracking count was
+	 * collected.
 	 * 
-	 * @return The tracking count for this <code>BundleTracker</code> or -1 if
-	 *         this <code>BundleTracker</code> is not open.
+	 * @return The tracking count for this {@code BundleTracker} or -1 if this
+	 *         {@code BundleTracker} is not open.
 	 */
 	public int getTrackingCount() {
 		final Tracked t = tracked();
@@ -373,13 +377,53 @@
 	}
 
 	/**
+	 * Return a {@code Map} with the {@code Bundle}s and customized
+	 * objects for all bundles being tracked by this {@code BundleTracker}.
+	 * 
+	 * @return A {@code Map} with the {@code Bundle}s and customized
+	 *         objects for all services being tracked by this
+	 *         {@code BundleTracker}. If no bundles are being tracked, then
+	 *         the returned map is empty.
+	 * @since 1.5
+	 */
+	public Map<Bundle, T> getTracked() {
+		Map<Bundle, T> map = new HashMap<Bundle, T>();
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return map;
+		}
+		synchronized (t) {
+			return t.copyEntries(map);
+		}
+	}
+
+	/**
+	 * Return if this {@code BundleTracker} is empty.
+	 * 
+	 * @return {@code true} if this {@code BundleTracker} is not tracking any
+	 *         bundles.
+	 * @since 1.5
+	 */
+	public boolean isEmpty() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return true;
+		}
+		synchronized (t) {
+			return t.isEmpty();
+		}
+	}
+
+	/**
 	 * Inner class which subclasses AbstractTracked. This class is the
-	 * <code>SynchronousBundleListener</code> object for the tracker.
+	 * {@code SynchronousBundleListener} object for the tracker.
 	 * 
 	 * @ThreadSafe
 	 * @since 1.4
 	 */
-	class Tracked extends AbstractTracked implements SynchronousBundleListener {
+	private final class Tracked extends AbstractTracked<Bundle, T, BundleEvent>
+			implements
+			SynchronousBundleListener {
 		/**
 		 * Tracked constructor.
 		 */
@@ -388,11 +432,11 @@
 		}
 
 		/**
-		 * <code>BundleListener</code> method for the <code>BundleTracker</code>
+		 * {@code BundleListener} method for the {@code BundleTracker}
 		 * class. This method must NOT be synchronized to avoid deadlock
 		 * potential.
 		 * 
-		 * @param event <code>BundleEvent</code> object from the framework.
+		 * @param event {@code BundleEvent} object from the framework.
 		 */
 		public void bundleChanged(final BundleEvent event) {
 			/*
@@ -431,13 +475,11 @@
 		 * 
 		 * @param item Item to be tracked.
 		 * @param related Action related object.
-		 * @return Customized object for the tracked item or <code>null</code>
+		 * @return Customized object for the tracked item or {@code null}
 		 *         if the item is not to be tracked.
 		 */
-		Object customizerAdding(final Object item,
-				final Object related) {
-			return customizer
-					.addingBundle((Bundle) item, (BundleEvent) related);
+		T customizerAdding(final Bundle item, final BundleEvent related) {
+			return customizer.addingBundle(item, related);
 		}
 
 		/**
@@ -448,10 +490,9 @@
 		 * @param related Action related object.
 		 * @param object Customized object for the tracked item.
 		 */
-		void customizerModified(final Object item,
-				final Object related, final Object object) {
-			customizer.modifiedBundle((Bundle) item, (BundleEvent) related,
-					object);
+		void customizerModified(final Bundle item, final BundleEvent related,
+				final T object) {
+			customizer.modifiedBundle(item, related, object);
 		}
 
 		/**
@@ -462,10 +503,9 @@
 		 * @param related Action related object.
 		 * @param object Customized object for the tracked item.
 		 */
-		void customizerRemoved(final Object item,
-				final Object related, final Object object) {
-			customizer.removedBundle((Bundle) item, (BundleEvent) related,
-					object);
+		void customizerRemoved(final Bundle item, final BundleEvent related,
+				final T object) {
+			customizer.removedBundle(item, related, object);
 		}
 	}
 }
diff --git a/framework/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java b/framework/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java
index 100c6b4..a7c9a23 100644
--- a/framework/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java
+++ b/framework/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) OSGi Alliance (2007, 2008). 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,85 +20,86 @@
 import org.osgi.framework.BundleEvent;
 
 /**
- * The <code>BundleTrackerCustomizer</code> interface allows a
- * <code>BundleTracker</code> to customize the <code>Bundle</code>s that are
- * tracked. A <code>BundleTrackerCustomizer</code> is called when a bundle is
- * being added to a <code>BundleTracker</code>. The
- * <code>BundleTrackerCustomizer</code> can then return an object for the
- * tracked bundle. A <code>BundleTrackerCustomizer</code> is also called when a
+ * The {@code BundleTrackerCustomizer} interface allows a
+ * {@code BundleTracker} to customize the {@code Bundle}s that are
+ * tracked. A {@code BundleTrackerCustomizer} is called when a bundle is
+ * being added to a {@code BundleTracker}. The
+ * {@code BundleTrackerCustomizer} can then return an object for the
+ * tracked bundle. A {@code BundleTrackerCustomizer} is also called when a
  * tracked bundle is modified or has been removed from a
- * <code>BundleTracker</code>.
+ * {@code BundleTracker}.
  * 
  * <p>
  * The methods in this interface may be called as the result of a
- * <code>BundleEvent</code> being received by a <code>BundleTracker</code>.
- * Since <code>BundleEvent</code>s are received synchronously by the
- * <code>BundleTracker</code>, it is highly recommended that implementations of
+ * {@code BundleEvent} being received by a {@code BundleTracker}.
+ * Since {@code BundleEvent}s are received synchronously by the
+ * {@code BundleTracker}, it is highly recommended that implementations of
  * these methods do not alter bundle states while being synchronized on any
  * object.
  * 
  * <p>
- * The <code>BundleTracker</code> class is thread-safe. It does not call a
- * <code>BundleTrackerCustomizer</code> while holding any locks.
- * <code>BundleTrackerCustomizer</code> implementations must also be
+ * The {@code BundleTracker} class is thread-safe. It does not call a
+ * {@code BundleTrackerCustomizer} while holding any locks.
+ * {@code BundleTrackerCustomizer} implementations must also be
  * thread-safe.
  * 
+ * @param <T> The type of the tracked object.
  * @ThreadSafe
- * @version $Revision: 5874 $
+ * @version $Id: 0e80f2555530b217faef57726a5938f0087a45c5 $
  * @since 1.4
  */
-public interface BundleTrackerCustomizer {
+public interface BundleTrackerCustomizer<T> {
 	/**
-	 * A bundle is being added to the <code>BundleTracker</code>.
+	 * A bundle is being added to the {@code BundleTracker}.
 	 * 
 	 * <p>
 	 * This method is called before a bundle which matched the search parameters
-	 * of the <code>BundleTracker</code> is added to the
-	 * <code>BundleTracker</code>. This method should return the object to be
-	 * tracked for the specified <code>Bundle</code>. The returned object is
-	 * stored in the <code>BundleTracker</code> and is available from the
+	 * of the {@code BundleTracker} is added to the
+	 * {@code BundleTracker}. This method should return the object to be
+	 * tracked for the specified {@code Bundle}. The returned object is
+	 * stored in the {@code BundleTracker} and is available from the
 	 * {@link BundleTracker#getObject(Bundle) getObject} method.
 	 * 
-	 * @param bundle The <code>Bundle</code> being added to the
-	 *        <code>BundleTracker</code>.
+	 * @param bundle The {@code Bundle} being added to the
+	 *        {@code BundleTracker}.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or <code>null</code> if there is no bundle event associated
+	 *        called or {@code null} if there is no bundle event associated
 	 *        with the call to this method.
-	 * @return The object to be tracked for the specified <code>Bundle</code>
-	 *         object or <code>null</code> if the specified <code>Bundle</code>
+	 * @return The object to be tracked for the specified {@code Bundle}
+	 *         object or {@code null} if the specified {@code Bundle}
 	 *         object should not be tracked.
 	 */
-	public Object addingBundle(Bundle bundle, BundleEvent event);
+	public T addingBundle(Bundle bundle, BundleEvent event);
 
 	/**
-	 * A bundle tracked by the <code>BundleTracker</code> has been modified.
+	 * A bundle tracked by the {@code BundleTracker} has been modified.
 	 * 
 	 * <p>
 	 * This method is called when a bundle being tracked by the
-	 * <code>BundleTracker</code> has had its state modified.
+	 * {@code BundleTracker} has had its state modified.
 	 * 
-	 * @param bundle The <code>Bundle</code> whose state has been modified.
+	 * @param bundle The {@code Bundle} whose state has been modified.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or <code>null</code> if there is no bundle event associated
+	 *        called or {@code null} if there is no bundle event associated
 	 *        with the call to this method.
 	 * @param object The tracked object for the specified bundle.
 	 */
 	public void modifiedBundle(Bundle bundle, BundleEvent event,
-			Object object);
+			T object);
 
 	/**
-	 * A bundle tracked by the <code>BundleTracker</code> has been removed.
+	 * A bundle tracked by the {@code BundleTracker} has been removed.
 	 * 
 	 * <p>
 	 * This method is called after a bundle is no longer being tracked by the
-	 * <code>BundleTracker</code>.
+	 * {@code BundleTracker}.
 	 * 
-	 * @param bundle The <code>Bundle</code> that has been removed.
+	 * @param bundle The {@code Bundle} that has been removed.
 	 * @param event The bundle event which caused this customizer method to be
-	 *        called or <code>null</code> if there is no bundle event associated
+	 *        called or {@code null} if there is no bundle event associated
 	 *        with the call to this method.
 	 * @param object The tracked object for the specified bundle.
 	 */
 	public void removedBundle(Bundle bundle, BundleEvent event,
-			Object object);
+			T object);
 }
diff --git a/framework/src/main/java/org/osgi/util/tracker/ServiceTracker.java b/framework/src/main/java/org/osgi/util/tracker/ServiceTracker.java
index b4e373b..f5cd086 100644
--- a/framework/src/main/java/org/osgi/util/tracker/ServiceTracker.java
+++ b/framework/src/main/java/org/osgi/util/tracker/ServiceTracker.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,8 +16,10 @@
 
 package org.osgi.util.tracker;
 
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import java.lang.reflect.Array;
+import java.util.Collections;
+import java.util.SortedMap;
+import java.util.TreeMap;
 
 import org.osgi.framework.AllServiceListener;
 import org.osgi.framework.BundleContext;
@@ -27,73 +29,74 @@
 import org.osgi.framework.ServiceEvent;
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
 
 /**
- * The <code>ServiceTracker</code> class simplifies using services from the
+ * The {@code ServiceTracker} class simplifies using services from the
  * Framework's service registry.
  * <p>
- * A <code>ServiceTracker</code> object is constructed with search criteria and
- * a <code>ServiceTrackerCustomizer</code> object. A <code>ServiceTracker</code>
- * can use a <code>ServiceTrackerCustomizer</code> to customize the service
- * objects to be tracked. The <code>ServiceTracker</code> can then be opened to
+ * A {@code ServiceTracker} object is constructed with search criteria and
+ * a {@code ServiceTrackerCustomizer} object. A {@code ServiceTracker}
+ * can use a {@code ServiceTrackerCustomizer} to customize the service
+ * objects to be tracked. The {@code ServiceTracker} can then be opened to
  * begin tracking all services in the Framework's service registry that match
- * the specified search criteria. The <code>ServiceTracker</code> correctly
- * handles all of the details of listening to <code>ServiceEvent</code>s and
+ * the specified search criteria. The {@code ServiceTracker} correctly
+ * handles all of the details of listening to {@code ServiceEvent}s and
  * getting and ungetting services.
  * <p>
- * The <code>getServiceReferences</code> method can be called to get references
- * to the services being tracked. The <code>getService</code> and
- * <code>getServices</code> methods can be called to get the service objects for
+ * The {@code getServiceReferences} method can be called to get references
+ * to the services being tracked. The {@code getService} and
+ * {@code getServices} methods can be called to get the service objects for
  * the tracked service.
  * <p>
- * The <code>ServiceTracker</code> class is thread-safe. It does not call a
- * <code>ServiceTrackerCustomizer</code> while holding any locks.
- * <code>ServiceTrackerCustomizer</code> implementations must also be
+ * The {@code ServiceTracker} class is thread-safe. It does not call a
+ * {@code ServiceTrackerCustomizer} while holding any locks.
+ * {@code ServiceTrackerCustomizer} implementations must also be
  * thread-safe.
  * 
+ * @param <S> The type of the service being tracked.
+ * @param <T> The type of the tracked object.
  * @ThreadSafe
- * @version $Revision: 6386 $
+ * @version $Id: df62459c90f49d06e89ff8f20915a9eec401217e $
  */
-public class ServiceTracker implements ServiceTrackerCustomizer {
+public class ServiceTracker<S, T> implements ServiceTrackerCustomizer<S, T> {
 	/* set this to true to compile in debug messages */
-	static final boolean				DEBUG			= false;
+	static final boolean					DEBUG	= false;
 	/**
-	 * The Bundle Context used by this <code>ServiceTracker</code>.
+	 * The Bundle Context used by this {@code ServiceTracker}.
 	 */
-	protected final BundleContext		context;
+	protected final BundleContext			context;
 	/**
-	 * The Filter used by this <code>ServiceTracker</code> which specifies the
+	 * The Filter used by this {@code ServiceTracker} which specifies the
 	 * search criteria for the services to track.
 	 * 
 	 * @since 1.1
 	 */
-	protected final Filter				filter;
+	protected final Filter					filter;
 	/**
-	 * The <code>ServiceTrackerCustomizer</code> for this tracker.
+	 * The {@code ServiceTrackerCustomizer} for this tracker.
 	 */
-	final ServiceTrackerCustomizer		customizer;
+	final ServiceTrackerCustomizer<S, T>	customizer;
 	/**
 	 * Filter string for use when adding the ServiceListener. If this field is
 	 * set, then certain optimizations can be taken since we don't have a user
 	 * supplied filter.
 	 */
-	final String						listenerFilter;
+	final String							listenerFilter;
 	/**
 	 * Class name to be tracked. If this field is set, then we are tracking by
 	 * class name.
 	 */
-	private final String				trackClass;
+	private final String					trackClass;
 	/**
 	 * Reference to be tracked. If this field is set, then we are tracking a
 	 * single ServiceReference.
 	 */
-	private final ServiceReference		trackReference;
+	private final ServiceReference<S>		trackReference;
 	/**
-	 * Tracked services: <code>ServiceReference</code> -> customized Object and
-	 * <code>ServiceListener</code> object
+	 * Tracked services: {@code ServiceReference} -> customized Object and
+	 * {@code ServiceListener} object
 	 */
-	private volatile Tracked			tracked;
+	private volatile Tracked				tracked;
 
 	/**
 	 * Accessor method for the current Tracked object. This method is only
@@ -111,49 +114,43 @@
 	 * 
 	 * This field is volatile since it is accessed by multiple threads.
 	 */
-	private volatile ServiceReference	cachedReference;
+	private volatile ServiceReference<S>	cachedReference;
 	/**
 	 * Cached service object for getService.
 	 * 
 	 * This field is volatile since it is accessed by multiple threads.
 	 */
-	private volatile Object				cachedService;
+	private volatile T						cachedService;
 
 	/**
-	 * org.osgi.framework package version which introduced
-	 * {@link ServiceEvent#MODIFIED_ENDMATCH}
-	 */
-	private static final Version		endMatchVersion	= new Version(1, 5, 0);
-
-	/**
-	 * Create a <code>ServiceTracker</code> on the specified
-	 * <code>ServiceReference</code>.
+	 * Create a {@code ServiceTracker} on the specified
+	 * {@code ServiceReference}.
 	 * 
 	 * <p>
-	 * The service referenced by the specified <code>ServiceReference</code>
-	 * will be tracked by this <code>ServiceTracker</code>.
+	 * The service referenced by the specified {@code ServiceReference}
+	 * will be tracked by this {@code ServiceTracker}.
 	 * 
-	 * @param context The <code>BundleContext</code> against which the tracking
+	 * @param context The {@code BundleContext} against which the tracking
 	 *        is done.
-	 * @param reference The <code>ServiceReference</code> for the service to be
+	 * @param reference The {@code ServiceReference} for the service to be
 	 *        tracked.
 	 * @param customizer The customizer object to call when services are added,
-	 *        modified, or removed in this <code>ServiceTracker</code>. If
-	 *        customizer is <code>null</code>, then this
-	 *        <code>ServiceTracker</code> will be used as the
-	 *        <code>ServiceTrackerCustomizer</code> and this
-	 *        <code>ServiceTracker</code> will call the
-	 *        <code>ServiceTrackerCustomizer</code> methods on itself.
+	 *        modified, or removed in this {@code ServiceTracker}. If
+	 *        customizer is {@code null}, then this
+	 *        {@code ServiceTracker} will be used as the
+	 *        {@code ServiceTrackerCustomizer} and this
+	 *        {@code ServiceTracker} will call the
+	 *        {@code ServiceTrackerCustomizer} methods on itself.
 	 */
 	public ServiceTracker(final BundleContext context,
-			final ServiceReference reference,
-			final ServiceTrackerCustomizer customizer) {
+			final ServiceReference<S> reference,
+			final ServiceTrackerCustomizer<S, T> customizer) {
 		this.context = context;
 		this.trackReference = reference;
 		this.trackClass = null;
 		this.customizer = (customizer == null) ? this : customizer;
 		this.listenerFilter = "(" + Constants.SERVICE_ID + "="
-				+ reference.getProperty(Constants.SERVICE_ID).toString() + ")"; 
+				+ reference.getProperty(Constants.SERVICE_ID).toString() + ")";
 		try {
 			this.filter = context.createFilter(listenerFilter);
 		}
@@ -170,32 +167,32 @@
 	}
 
 	/**
-	 * Create a <code>ServiceTracker</code> on the specified class name.
+	 * Create a {@code ServiceTracker} on the specified class name.
 	 * 
 	 * <p>
 	 * Services registered under the specified class name will be tracked by
-	 * this <code>ServiceTracker</code>.
+	 * this {@code ServiceTracker}.
 	 * 
-	 * @param context The <code>BundleContext</code> against which the tracking
+	 * @param context The {@code BundleContext} against which the tracking
 	 *        is done.
 	 * @param clazz The class name of the services to be tracked.
 	 * @param customizer The customizer object to call when services are added,
-	 *        modified, or removed in this <code>ServiceTracker</code>. If
-	 *        customizer is <code>null</code>, then this
-	 *        <code>ServiceTracker</code> will be used as the
-	 *        <code>ServiceTrackerCustomizer</code> and this
-	 *        <code>ServiceTracker</code> will call the
-	 *        <code>ServiceTrackerCustomizer</code> methods on itself.
+	 *        modified, or removed in this {@code ServiceTracker}. If
+	 *        customizer is {@code null}, then this
+	 *        {@code ServiceTracker} will be used as the
+	 *        {@code ServiceTrackerCustomizer} and this
+	 *        {@code ServiceTracker} will call the
+	 *        {@code ServiceTrackerCustomizer} methods on itself.
 	 */
 	public ServiceTracker(final BundleContext context, final String clazz,
-			final ServiceTrackerCustomizer customizer) {
+			final ServiceTrackerCustomizer<S, T> customizer) {
 		this.context = context;
 		this.trackReference = null;
 		this.trackClass = clazz;
 		this.customizer = (customizer == null) ? this : customizer;
 		// we call clazz.toString to verify clazz is non-null!
 		this.listenerFilter = "(" + Constants.OBJECTCLASS + "="
-				+ clazz.toString() + ")"; 
+				+ clazz.toString() + ")";
 		try {
 			this.filter = context.createFilter(listenerFilter);
 		}
@@ -212,42 +209,31 @@
 	}
 
 	/**
-	 * Create a <code>ServiceTracker</code> on the specified <code>Filter</code>
+	 * Create a {@code ServiceTracker} on the specified {@code Filter}
 	 * object.
 	 * 
 	 * <p>
-	 * Services which match the specified <code>Filter</code> object will be
-	 * tracked by this <code>ServiceTracker</code>.
+	 * Services which match the specified {@code Filter} object will be
+	 * tracked by this {@code ServiceTracker}.
 	 * 
-	 * @param context The <code>BundleContext</code> against which the tracking
+	 * @param context The {@code BundleContext} against which the tracking
 	 *        is done.
-	 * @param filter The <code>Filter</code> to select the services to be
+	 * @param filter The {@code Filter} to select the services to be
 	 *        tracked.
 	 * @param customizer The customizer object to call when services are added,
-	 *        modified, or removed in this <code>ServiceTracker</code>. If
-	 *        customizer is null, then this <code>ServiceTracker</code> will be
-	 *        used as the <code>ServiceTrackerCustomizer</code> and this
-	 *        <code>ServiceTracker</code> will call the
-	 *        <code>ServiceTrackerCustomizer</code> methods on itself.
+	 *        modified, or removed in this {@code ServiceTracker}. If
+	 *        customizer is null, then this {@code ServiceTracker} will be
+	 *        used as the {@code ServiceTrackerCustomizer} and this
+	 *        {@code ServiceTracker} will call the
+	 *        {@code ServiceTrackerCustomizer} methods on itself.
 	 * @since 1.1
 	 */
 	public ServiceTracker(final BundleContext context, final Filter filter,
-			final ServiceTrackerCustomizer customizer) {
+			final ServiceTrackerCustomizer<S, T> customizer) {
 		this.context = context;
 		this.trackReference = null;
 		this.trackClass = null;
-		final Version frameworkVersion = (Version) AccessController
-				.doPrivileged(new PrivilegedAction() {
-					public Object run() {
-						String version = context
-								.getProperty(Constants.FRAMEWORK_VERSION);
-						return (version == null) ? Version.emptyVersion
-								: new Version(version);
-					}
-				});
-		final boolean endMatchSupported = (frameworkVersion
-				.compareTo(endMatchVersion) >= 0);
-		this.listenerFilter = endMatchSupported ? filter.toString() : null;
+		this.listenerFilter = filter.toString();
 		this.filter = filter;
 		this.customizer = (customizer == null) ? this : customizer;
 		if ((context == null) || (filter == null)) {
@@ -259,13 +245,37 @@
 	}
 
 	/**
-	 * Open this <code>ServiceTracker</code> and begin tracking services.
+	 * Create a {@code ServiceTracker} on the specified class.
 	 * 
 	 * <p>
-	 * This implementation calls <code>open(false)</code>.
+	 * Services registered under the name of the specified class will be tracked
+	 * by this {@code ServiceTracker}.
 	 * 
-	 * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
-	 *         with which this <code>ServiceTracker</code> was created is no
+	 * @param context The {@code BundleContext} against which the tracking
+	 *        is done.
+	 * @param clazz The class of the services to be tracked.
+	 * @param customizer The customizer object to call when services are added,
+	 *        modified, or removed in this {@code ServiceTracker}. If
+	 *        customizer is {@code null}, then this
+	 *        {@code ServiceTracker} will be used as the
+	 *        {@code ServiceTrackerCustomizer} and this
+	 *        {@code ServiceTracker} will call the
+	 *        {@code ServiceTrackerCustomizer} methods on itself.
+	 * @since 1.5
+	 */
+	public ServiceTracker(final BundleContext context, final Class<S> clazz,
+			final ServiceTrackerCustomizer<S, T> customizer) {
+		this(context, clazz.getName(), customizer);
+	}
+
+	/**
+	 * Open this {@code ServiceTracker} and begin tracking services.
+	 * 
+	 * <p>
+	 * This implementation calls {@code open(false)}.
+	 * 
+	 * @throws java.lang.IllegalStateException If the {@code BundleContext}
+	 *         with which this {@code ServiceTracker} was created is no
 	 *         longer valid.
 	 * @see #open(boolean)
 	 */
@@ -274,22 +284,22 @@
 	}
 
 	/**
-	 * Open this <code>ServiceTracker</code> and begin tracking services.
+	 * Open this {@code ServiceTracker} and begin tracking services.
 	 * 
 	 * <p>
 	 * Services which match the search criteria specified when this
-	 * <code>ServiceTracker</code> was created are now tracked by this
-	 * <code>ServiceTracker</code>.
+	 * {@code ServiceTracker} was created are now tracked by this
+	 * {@code ServiceTracker}.
 	 * 
-	 * @param trackAllServices If <code>true</code>, then this
-	 *        <code>ServiceTracker</code> will track all matching services
-	 *        regardless of class loader accessibility. If <code>false</code>,
-	 *        then this <code>ServiceTracker</code> will only track matching
+	 * @param trackAllServices If {@code true}, then this
+	 *        {@code ServiceTracker} will track all matching services
+	 *        regardless of class loader accessibility. If {@code false},
+	 *        then this {@code ServiceTracker} will only track matching
 	 *        services which are class loader accessible to the bundle whose
-	 *        <code>BundleContext</code> is used by this
-	 *        <code>ServiceTracker</code>.
-	 * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
-	 *         with which this <code>ServiceTracker</code> was created is no
+	 *        {@code BundleContext} is used by this
+	 *        {@code ServiceTracker}.
+	 * @throws java.lang.IllegalStateException If the {@code BundleContext}
+	 *         with which this {@code ServiceTracker} was created is no
 	 *         longer valid.
 	 * @since 1.3
 	 */
@@ -300,13 +310,13 @@
 				return;
 			}
 			if (DEBUG) {
-				System.out.println("ServiceTracker.open: " + filter); 
+				System.out.println("ServiceTracker.open: " + filter);
 			}
 			t = trackAllServices ? new AllTracked() : new Tracked();
 			synchronized (t) {
 				try {
 					context.addServiceListener(t, listenerFilter);
-					ServiceReference[] references = null;
+					ServiceReference<S>[] references = null;
 					if (trackClass != null) {
 						references = getInitialReferences(trackAllServices,
 								trackClass, null);
@@ -314,23 +324,22 @@
 					else {
 						if (trackReference != null) {
 							if (trackReference.getBundle() != null) {
-								references = new ServiceReference[] {trackReference};
+								ServiceReference<S>[] single = new ServiceReference[] {trackReference};
+								references = single;
 							}
 						}
 						else { /* user supplied filter */
 							references = getInitialReferences(trackAllServices,
-									null,
-									(listenerFilter != null) ? listenerFilter
-											: filter.toString());
+									null, listenerFilter);
 						}
 					}
 					/* set tracked with the initial references */
-					t.setInitial(references); 
+					t.setInitial(references);
 				}
 				catch (InvalidSyntaxException e) {
 					throw new RuntimeException(
 							"unexpected InvalidSyntaxException: "
-									+ e.getMessage(), e); 
+									+ e.getMessage(), e);
 				}
 			}
 			tracked = t;
@@ -340,33 +349,33 @@
 	}
 
 	/**
-	 * Returns the list of initial <code>ServiceReference</code>s that will be
-	 * tracked by this <code>ServiceTracker</code>.
+	 * Returns the list of initial {@code ServiceReference}s that will be
+	 * tracked by this {@code ServiceTracker}.
 	 * 
-	 * @param trackAllServices If <code>true</code>, use
-	 *        <code>getAllServiceReferences</code>.
+	 * @param trackAllServices If {@code true}, use
+	 *        {@code getAllServiceReferences}.
 	 * @param className The class name with which the service was registered, or
-	 *        <code>null</code> for all services.
-	 * @param filterString The filter criteria or <code>null</code> for all
+	 *        {@code null} for all services.
+	 * @param filterString The filter criteria or {@code null} for all
 	 *        services.
-	 * @return The list of initial <code>ServiceReference</code>s.
+	 * @return The list of initial {@code ServiceReference}s.
 	 * @throws InvalidSyntaxException If the specified filterString has an
 	 *         invalid syntax.
 	 */
-	private ServiceReference[] getInitialReferences(boolean trackAllServices,
-			String className, String filterString)
+	private ServiceReference<S>[] getInitialReferences(
+			boolean trackAllServices, String className, String filterString)
 			throws InvalidSyntaxException {
-		if (trackAllServices) {
-			return context.getAllServiceReferences(className, filterString);
-		}
-		return context.getServiceReferences(className, filterString);
+		ServiceReference<S>[] result = (ServiceReference<S>[]) ((trackAllServices) ? context
+				.getAllServiceReferences(className, filterString)
+				: context.getServiceReferences(className, filterString));
+		return result;
 	}
 
 	/**
-	 * Close this <code>ServiceTracker</code>.
+	 * Close this {@code ServiceTracker}.
 	 * 
 	 * <p>
-	 * This method should be called when this <code>ServiceTracker</code> should
+	 * This method should be called when this {@code ServiceTracker} should
 	 * end the tracking of services.
 	 * 
 	 * <p>
@@ -375,14 +384,14 @@
 	 */
 	public void close() {
 		final Tracked outgoing;
-		final ServiceReference[] references;
+		final ServiceReference<S>[] references;
 		synchronized (this) {
 			outgoing = tracked;
 			if (outgoing == null) {
 				return;
 			}
 			if (DEBUG) {
-				System.out.println("ServiceTracker.close: " + filter); 
+				System.out.println("ServiceTracker.close: " + filter);
 			}
 			outgoing.close();
 			references = getServiceReferences();
@@ -405,26 +414,25 @@
 		}
 		if (DEBUG) {
 			if ((cachedReference == null) && (cachedService == null)) {
-				System.out
-						.println("ServiceTracker.close[cached cleared]: "
-						+ filter); 
+				System.out.println("ServiceTracker.close[cached cleared]: "
+						+ filter);
 			}
 		}
 	}
 
 	/**
 	 * Default implementation of the
-	 * <code>ServiceTrackerCustomizer.addingService</code> method.
+	 * {@code ServiceTrackerCustomizer.addingService} method.
 	 * 
 	 * <p>
-	 * This method is only called when this <code>ServiceTracker</code> has been
-	 * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
+	 * This method is only called when this {@code ServiceTracker} has been
+	 * constructed with a {@code null ServiceTrackerCustomizer} argument.
 	 * 
 	 * <p>
-	 * This implementation returns the result of calling <code>getService</code>
-	 * on the <code>BundleContext</code> with which this
-	 * <code>ServiceTracker</code> was created passing the specified
-	 * <code>ServiceReference</code>.
+	 * This implementation returns the result of calling {@code getService}
+	 * on the {@code BundleContext} with which this
+	 * {@code ServiceTracker} was created passing the specified
+	 * {@code ServiceReference}.
 	 * <p>
 	 * This method can be overridden in a subclass to customize the service
 	 * object to be tracked for the service being added. In that case, take care
@@ -433,22 +441,23 @@
 	 * the service.
 	 * 
 	 * @param reference The reference to the service being added to this
-	 *        <code>ServiceTracker</code>.
+	 *        {@code ServiceTracker}.
 	 * @return The service object to be tracked for the service added to this
-	 *         <code>ServiceTracker</code>.
+	 *         {@code ServiceTracker}.
 	 * @see ServiceTrackerCustomizer#addingService(ServiceReference)
 	 */
-	public Object addingService(ServiceReference reference) {
-		return context.getService(reference);
+	public T addingService(ServiceReference<S> reference) {
+		T result = (T) context.getService(reference);
+		return result;
 	}
 
 	/**
 	 * Default implementation of the
-	 * <code>ServiceTrackerCustomizer.modifiedService</code> method.
+	 * {@code ServiceTrackerCustomizer.modifiedService} method.
 	 * 
 	 * <p>
-	 * This method is only called when this <code>ServiceTracker</code> has been
-	 * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
+	 * This method is only called when this {@code ServiceTracker} has been
+	 * constructed with a {@code null ServiceTrackerCustomizer} argument.
 	 * 
 	 * <p>
 	 * This implementation does nothing.
@@ -457,22 +466,22 @@
 	 * @param service The service object for the modified service.
 	 * @see ServiceTrackerCustomizer#modifiedService(ServiceReference, Object)
 	 */
-	public void modifiedService(ServiceReference reference, Object service) {
+	public void modifiedService(ServiceReference<S> reference, T service) {
 		/* do nothing */
 	}
 
 	/**
 	 * Default implementation of the
-	 * <code>ServiceTrackerCustomizer.removedService</code> method.
+	 * {@code ServiceTrackerCustomizer.removedService} method.
 	 * 
 	 * <p>
-	 * This method is only called when this <code>ServiceTracker</code> has been
-	 * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
+	 * This method is only called when this {@code ServiceTracker} has been
+	 * constructed with a {@code null ServiceTrackerCustomizer} argument.
 	 * 
 	 * <p>
-	 * This implementation calls <code>ungetService</code>, on the
-	 * <code>BundleContext</code> with which this <code>ServiceTracker</code>
-	 * was created, passing the specified <code>ServiceReference</code>.
+	 * This implementation calls {@code ungetService}, on the
+	 * {@code BundleContext} with which this {@code ServiceTracker}
+	 * was created, passing the specified {@code ServiceReference}.
 	 * <p>
 	 * This method can be overridden in a subclass. If the default
 	 * implementation of {@link #addingService(ServiceReference) addingService}
@@ -482,19 +491,19 @@
 	 * @param service The service object for the removed service.
 	 * @see ServiceTrackerCustomizer#removedService(ServiceReference, Object)
 	 */
-	public void removedService(ServiceReference reference, Object service) {
+	public void removedService(ServiceReference<S> reference, T service) {
 		context.ungetService(reference);
 	}
 
 	/**
 	 * Wait for at least one service to be tracked by this
-	 * <code>ServiceTracker</code>. This method will also return when this
-	 * <code>ServiceTracker</code> is closed.
+	 * {@code ServiceTracker}. This method will also return when this
+	 * {@code ServiceTracker} is closed.
 	 * 
 	 * <p>
-	 * It is strongly recommended that <code>waitForService</code> is not used
-	 * during the calling of the <code>BundleActivator</code> methods.
-	 * <code>BundleActivator</code> methods are expected to complete in a short
+	 * It is strongly recommended that {@code waitForService} is not used
+	 * during the calling of the {@code BundleActivator} methods.
+	 * {@code BundleActivator} methods are expected to complete in a short
 	 * period of time.
 	 * 
 	 * <p>
@@ -508,11 +517,11 @@
 	 *         current thread.
 	 * @throws IllegalArgumentException If the value of timeout is negative.
 	 */
-	public Object waitForService(long timeout) throws InterruptedException {
+	public T waitForService(long timeout) throws InterruptedException {
 		if (timeout < 0) {
-			throw new IllegalArgumentException("timeout value is negative"); 
+			throw new IllegalArgumentException("timeout value is negative");
 		}
-		Object object = getService(); 
+		T object = getService();
 		while (object == null) {
 			final Tracked t = tracked();
 			if (t == null) { /* if ServiceTracker is not open */
@@ -523,7 +532,7 @@
 					t.wait(timeout);
 				}
 			}
-			object = getService(); 
+			object = getService();
 			if (timeout > 0) {
 				return object;
 			}
@@ -532,13 +541,13 @@
 	}
 
 	/**
-	 * Return an array of <code>ServiceReference</code>s for all services being
-	 * tracked by this <code>ServiceTracker</code>.
+	 * Return an array of {@code ServiceReference}s for all services being
+	 * tracked by this {@code ServiceTracker}.
 	 * 
-	 * @return Array of <code>ServiceReference</code>s or <code>null</code> if
+	 * @return Array of {@code ServiceReference}s or {@code null} if
 	 *         no services are being tracked.
 	 */
-	public ServiceReference[] getServiceReferences() {
+	public ServiceReference<S>[] getServiceReferences() {
 		final Tracked t = tracked();
 		if (t == null) { /* if ServiceTracker is not open */
 			return null;
@@ -548,45 +557,45 @@
 			if (length == 0) {
 				return null;
 			}
-			return (ServiceReference[]) t
-					.getTracked(new ServiceReference[length]);
+			ServiceReference<S>[] result = new ServiceReference[length];
+			return t.copyKeys(result);
 		}
 	}
 
 	/**
-	 * Returns a <code>ServiceReference</code> for one of the services being
-	 * tracked by this <code>ServiceTracker</code>.
+	 * Returns a {@code ServiceReference} for one of the services being
+	 * tracked by this {@code ServiceTracker}.
 	 * 
 	 * <p>
 	 * If multiple services are being tracked, the service with the highest
-	 * ranking (as specified in its <code>service.ranking</code> property) is
+	 * ranking (as specified in its {@code service.ranking} property) is
 	 * returned. If there is a tie in ranking, the service with the lowest
-	 * service ID (as specified in its <code>service.id</code> property); that
+	 * service ID (as specified in its {@code service.id} property); that
 	 * is, the service that was registered first is returned. This is the same
-	 * algorithm used by <code>BundleContext.getServiceReference</code>.
+	 * algorithm used by {@code BundleContext.getServiceReference}.
 	 * 
 	 * <p>
 	 * This implementation calls {@link #getServiceReferences()} to get the list
 	 * of references for the tracked services.
 	 * 
-	 * @return A <code>ServiceReference</code> or <code>null</code> if no
+	 * @return A {@code ServiceReference} or {@code null} if no
 	 *         services are being tracked.
 	 * @since 1.1
 	 */
-	public ServiceReference getServiceReference() {
-		ServiceReference reference = cachedReference;
+	public ServiceReference<S> getServiceReference() {
+		ServiceReference<S> reference = cachedReference;
 		if (reference != null) {
 			if (DEBUG) {
 				System.out
 						.println("ServiceTracker.getServiceReference[cached]: "
-								+ filter); 
+								+ filter);
 			}
 			return reference;
 		}
 		if (DEBUG) {
-			System.out.println("ServiceTracker.getServiceReference: " + filter); 
+			System.out.println("ServiceTracker.getServiceReference: " + filter);
 		}
-		ServiceReference[] references = getServiceReferences(); 
+		ServiceReference<S>[] references = getServiceReferences();
 		int length = (references == null) ? 0 : references.length;
 		if (length == 0) { /* if no service is being tracked */
 			return null;
@@ -634,15 +643,15 @@
 
 	/**
 	 * Returns the service object for the specified
-	 * <code>ServiceReference</code> if the specified referenced service is
-	 * being tracked by this <code>ServiceTracker</code>.
+	 * {@code ServiceReference} if the specified referenced service is
+	 * being tracked by this {@code ServiceTracker}.
 	 * 
 	 * @param reference The reference to the desired service.
-	 * @return A service object or <code>null</code> if the service referenced
-	 *         by the specified <code>ServiceReference</code> is not being
+	 * @return A service object or {@code null} if the service referenced
+	 *         by the specified {@code ServiceReference} is not being
 	 *         tracked.
 	 */
-	public Object getService(ServiceReference reference) {
+	public T getService(ServiceReference<S> reference) {
 		final Tracked t = tracked();
 		if (t == null) { /* if ServiceTracker is not open */
 			return null;
@@ -654,7 +663,7 @@
 
 	/**
 	 * Return an array of service objects for all services being tracked by this
-	 * <code>ServiceTracker</code>.
+	 * {@code ServiceTracker}.
 	 * 
 	 * <p>
 	 * This implementation calls {@link #getServiceReferences()} to get the list
@@ -662,7 +671,7 @@
 	 * {@link #getService(ServiceReference)} for each reference to get the
 	 * tracked service object.
 	 * 
-	 * @return An array of service objects or <code>null</code> if no services
+	 * @return An array of service objects or {@code null} if no services
 	 *         are being tracked.
 	 */
 	public Object[] getServices() {
@@ -671,14 +680,14 @@
 			return null;
 		}
 		synchronized (t) {
-			ServiceReference[] references = getServiceReferences(); 
+			ServiceReference<S>[] references = getServiceReferences();
 			int length = (references == null) ? 0 : references.length;
 			if (length == 0) {
 				return null;
 			}
 			Object[] objects = new Object[length];
 			for (int i = 0; i < length; i++) {
-				objects[i] = getService(references[i]); 
+				objects[i] = getService(references[i]);
 			}
 			return objects;
 		}
@@ -686,46 +695,45 @@
 
 	/**
 	 * Returns a service object for one of the services being tracked by this
-	 * <code>ServiceTracker</code>.
+	 * {@code ServiceTracker}.
 	 * 
 	 * <p>
 	 * If any services are being tracked, this implementation returns the result
-	 * of calling <code>getService(getServiceReference())</code>.
+	 * of calling {@code getService(getServiceReference())}.
 	 * 
-	 * @return A service object or <code>null</code> if no services are being
+	 * @return A service object or {@code null} if no services are being
 	 *         tracked.
 	 */
-	public Object getService() {
-		Object service = cachedService;
+	public T getService() {
+		T service = cachedService;
 		if (service != null) {
 			if (DEBUG) {
-				System.out
-						.println("ServiceTracker.getService[cached]: "
-						+ filter); 
+				System.out.println("ServiceTracker.getService[cached]: "
+						+ filter);
 			}
 			return service;
 		}
 		if (DEBUG) {
-			System.out.println("ServiceTracker.getService: " + filter); 
+			System.out.println("ServiceTracker.getService: " + filter);
 		}
-		ServiceReference reference = getServiceReference(); 
+		ServiceReference<S> reference = getServiceReference();
 		if (reference == null) {
 			return null;
 		}
-		return cachedService = getService(reference); 
+		return cachedService = getService(reference);
 	}
 
 	/**
-	 * Remove a service from this <code>ServiceTracker</code>.
+	 * Remove a service from this {@code ServiceTracker}.
 	 * 
 	 * The specified service will be removed from this
-	 * <code>ServiceTracker</code>. If the specified service was being tracked
-	 * then the <code>ServiceTrackerCustomizer.removedService</code> method will
+	 * {@code ServiceTracker}. If the specified service was being tracked
+	 * then the {@code ServiceTrackerCustomizer.removedService} method will
 	 * be called for that service.
 	 * 
 	 * @param reference The reference to the service to be removed.
 	 */
-	public void remove(ServiceReference reference) {
+	public void remove(ServiceReference<S> reference) {
 		final Tracked t = tracked();
 		if (t == null) { /* if ServiceTracker is not open */
 			return;
@@ -735,7 +743,7 @@
 
 	/**
 	 * Return the number of services being tracked by this
-	 * <code>ServiceTracker</code>.
+	 * {@code ServiceTracker}.
 	 * 
 	 * @return The number of services being tracked.
 	 */
@@ -750,24 +758,23 @@
 	}
 
 	/**
-	 * Returns the tracking count for this <code>ServiceTracker</code>.
+	 * Returns the tracking count for this {@code ServiceTracker}.
 	 * 
-	 * The tracking count is initialized to 0 when this
-	 * <code>ServiceTracker</code> is opened. Every time a service is added,
-	 * modified or removed from this <code>ServiceTracker</code>, the tracking
-	 * count is incremented.
+	 * The tracking count is initialized to 0 when this {@code ServiceTracker}
+	 * is opened. Every time a service is added, modified or removed from this
+	 * {@code ServiceTracker}, the tracking count is incremented.
 	 * 
 	 * <p>
 	 * The tracking count can be used to determine if this
-	 * <code>ServiceTracker</code> has added, modified or removed a service by
+	 * {@code ServiceTracker} has added, modified or removed a service by
 	 * comparing a tracking count value previously collected with the current
 	 * tracking count value. If the value has not changed, then no service has
-	 * been added, modified or removed from this <code>ServiceTracker</code>
-	 * since the previous tracking count was collected.
+	 * been added, modified or removed from this {@code ServiceTracker} since
+	 * the previous tracking count was collected.
 	 * 
 	 * @since 1.2
-	 * @return The tracking count for this <code>ServiceTracker</code> or -1 if
-	 *         this <code>ServiceTracker</code> is not open.
+	 * @return The tracking count for this {@code ServiceTracker} or -1 if this
+	 *         {@code ServiceTracker} is not open.
 	 */
 	public int getTrackingCount() {
 		final Tracked t = tracked();
@@ -792,17 +799,113 @@
 		cachedReference = null; /* clear cached value */
 		cachedService = null; /* clear cached value */
 		if (DEBUG) {
-			System.out.println("ServiceTracker.modified: " + filter); 
+			System.out.println("ServiceTracker.modified: " + filter);
+		}
+	}
+
+	/**
+	 * Return a {@code SortedMap} of the {@code ServiceReference}s and
+	 * service objects for all services being tracked by this
+	 * {@code ServiceTracker}. The map is sorted in reverse natural order
+	 * of {@code ServiceReference}. That is, the first entry is the service
+	 * with the highest ranking and the lowest service id.
+	 * 
+	 * @return A {@code SortedMap} with the {@code ServiceReference}s
+	 *         and service objects for all services being tracked by this
+	 *         {@code ServiceTracker}. If no services are being tracked,
+	 *         then the returned map is empty.
+	 * @since 1.5
+	 */
+	public SortedMap<ServiceReference<S>, T> getTracked() {
+		SortedMap<ServiceReference<S>, T> map = new TreeMap<ServiceReference<S>, T>(
+				Collections.reverseOrder());
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return map;
+		}
+		synchronized (t) {
+			return t.copyEntries(map);
+		}
+	}
+
+	/**
+	 * Return if this {@code ServiceTracker} is empty.
+	 * 
+	 * @return {@code true} if this {@code ServiceTracker} is not tracking any
+	 *         services.
+	 * @since 1.5
+	 */
+	public boolean isEmpty() {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return true;
+		}
+		synchronized (t) {
+			return t.isEmpty();
+		}
+	}
+
+	/**
+	 * Return an array of service objects for all services being tracked by this
+	 * {@code ServiceTracker}. The runtime type of the returned array is that of
+	 * the specified array.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getServiceReferences()} to get the list
+	 * of references for the tracked services and then calls
+	 * {@link #getService(ServiceReference)} for each reference to get the
+	 * tracked service object.
+	 * 
+	 * @param array An array into which the tracked service objects will be
+	 *        stored, if the array is large enough.
+	 * @return An array of service objects being tracked. If the specified array
+	 *         is large enough to hold the result, then the specified array is
+	 *         returned. If the specified array is longer then necessary to hold
+	 *         the result, the array element after the last service object is
+	 *         set to {@code null}. If the specified array is not large enough
+	 *         to hold the result, a new array is created and returned.
+	 * @since 1.5
+	 */
+	public T[] getServices(T[] array) {
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			if (array.length > 0) {
+				array[0] = null;
+			}
+			return array;
+		}
+		synchronized (t) {
+			ServiceReference<S>[] references = getServiceReferences();
+			int length = (references == null) ? 0 : references.length;
+			if (length == 0) {
+				if (array.length > 0) {
+					array[0] = null;
+				}
+				return array;
+			}
+			if (length > array.length) {
+				array = (T[]) Array.newInstance(array.getClass()
+						.getComponentType(), length);
+			}
+			for (int i = 0; i < length; i++) {
+				array[i] = getService(references[i]);
+			}
+			if (array.length > length) {
+				array[length] = null;
+			}
+			return array;
 		}
 	}
 
 	/**
 	 * Inner class which subclasses AbstractTracked. This class is the
-	 * <code>ServiceListener</code> object for the tracker.
+	 * {@code ServiceListener} object for the tracker.
 	 * 
 	 * @ThreadSafe
 	 */
-	class Tracked extends AbstractTracked implements ServiceListener {
+	private class Tracked extends
+			AbstractTracked<ServiceReference<S>, T, ServiceEvent>
+			implements ServiceListener {
 		/**
 		 * Tracked constructor.
 		 */
@@ -811,13 +914,13 @@
 		}
 
 		/**
-		 * <code>ServiceListener</code> method for the
-		 * <code>ServiceTracker</code> class. This method must NOT be
+		 * {@code ServiceListener} method for the
+		 * {@code ServiceTracker} class. This method must NOT be
 		 * synchronized to avoid deadlock potential.
 		 * 
-		 * @param event <code>ServiceEvent</code> object from the framework.
+		 * @param event {@code ServiceEvent} object from the framework.
 		 */
-		public void serviceChanged(final ServiceEvent event) {
+		final public void serviceChanged(final ServiceEvent event) {
 			/*
 			 * Check if we had a delayed call (which could happen when we
 			 * close).
@@ -825,40 +928,21 @@
 			if (closed) {
 				return;
 			}
-			final ServiceReference reference = event.getServiceReference();
+			final ServiceReference<S> reference = (ServiceReference<S>) event
+					.getServiceReference();
 			if (DEBUG) {
-				System.out
-						.println("ServiceTracker.Tracked.serviceChanged["
-						+ event.getType() + "]: " + reference);  
+				System.out.println("ServiceTracker.Tracked.serviceChanged["
+						+ event.getType() + "]: " + reference);
 			}
 
 			switch (event.getType()) {
 				case ServiceEvent.REGISTERED :
 				case ServiceEvent.MODIFIED :
-					if (listenerFilter != null) { // service listener added with
-						// filter
-						track(reference, event);
-						/*
-						 * If the customizer throws an unchecked exception, it
-						 * is safe to let it propagate
-						 */
-					}
-					else { // service listener added without filter
-						if (filter.match(reference)) {
-							track(reference, event);
-							/*
-							 * If the customizer throws an unchecked exception,
-							 * it is safe to let it propagate
-							 */
-						}
-						else {
-							untrack(reference, event);
-							/*
-							 * If the customizer throws an unchecked exception,
-							 * it is safe to let it propagate
-							 */
-						}
-					}
+					track(reference, event);
+					/*
+					 * If the customizer throws an unchecked exception, it is
+					 * safe to let it propagate
+					 */
 					break;
 				case ServiceEvent.MODIFIED_ENDMATCH :
 				case ServiceEvent.UNREGISTERING :
@@ -877,7 +961,7 @@
 		 * 
 		 * @GuardedBy this
 		 */
-		void modified() {
+		final void modified() {
 			super.modified(); /* increment the modification count */
 			ServiceTracker.this.modified();
 		}
@@ -888,12 +972,12 @@
 		 * 
 		 * @param item Item to be tracked.
 		 * @param related Action related object.
-		 * @return Customized object for the tracked item or <code>null</code>
+		 * @return Customized object for the tracked item or {@code null}
 		 *         if the item is not to be tracked.
 		 */
-		Object customizerAdding(final Object item,
-				final Object related) {
-			return customizer.addingService((ServiceReference) item);
+		final T customizerAdding(final ServiceReference<S> item,
+				final ServiceEvent related) {
+			return customizer.addingService(item);
 		}
 
 		/**
@@ -904,9 +988,9 @@
 		 * @param related Action related object.
 		 * @param object Customized object for the tracked item.
 		 */
-		void customizerModified(final Object item,
-				final Object related, final Object object) {
-			customizer.modifiedService((ServiceReference) item, object);
+		final void customizerModified(final ServiceReference<S> item,
+				final ServiceEvent related, final T object) {
+			customizer.modifiedService(item, object);
 		}
 
 		/**
@@ -917,9 +1001,9 @@
 		 * @param related Action related object.
 		 * @param object Customized object for the tracked item.
 		 */
-		void customizerRemoved(final Object item,
-				final Object related, final Object object) {
-			customizer.removedService((ServiceReference) item, object);
+		final void customizerRemoved(final ServiceReference<S> item,
+				final ServiceEvent related, final T object) {
+			customizer.removedService(item, object);
 		}
 	}
 
@@ -930,7 +1014,7 @@
 	 * @since 1.3
 	 * @ThreadSafe
 	 */
-	class AllTracked extends Tracked implements AllServiceListener {
+	private class AllTracked extends Tracked implements AllServiceListener {
 		/**
 		 * AllTracked constructor.
 		 */
diff --git a/framework/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java b/framework/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
index 5c270e3..b2caddc 100644
--- a/framework/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
+++ b/framework/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.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,76 +19,78 @@
 import org.osgi.framework.ServiceReference;
 
 /**
- * The <code>ServiceTrackerCustomizer</code> interface allows a
- * <code>ServiceTracker</code> to customize the service objects that are
- * tracked. A <code>ServiceTrackerCustomizer</code> is called when a service is
- * being added to a <code>ServiceTracker</code>. The
- * <code>ServiceTrackerCustomizer</code> can then return an object for the
- * tracked service. A <code>ServiceTrackerCustomizer</code> is also called when
+ * The {@code ServiceTrackerCustomizer} interface allows a
+ * {@code ServiceTracker} to customize the service objects that are
+ * tracked. A {@code ServiceTrackerCustomizer} is called when a service is
+ * being added to a {@code ServiceTracker}. The
+ * {@code ServiceTrackerCustomizer} can then return an object for the
+ * tracked service. A {@code ServiceTrackerCustomizer} is also called when
  * a tracked service is modified or has been removed from a
- * <code>ServiceTracker</code>.
+ * {@code ServiceTracker}.
  * 
  * <p>
  * The methods in this interface may be called as the result of a
- * <code>ServiceEvent</code> being received by a <code>ServiceTracker</code>.
- * Since <code>ServiceEvent</code>s are synchronously delivered by the
+ * {@code ServiceEvent} being received by a {@code ServiceTracker}.
+ * Since {@code ServiceEvent}s are synchronously delivered by the
  * Framework, it is highly recommended that implementations of these methods do
- * not register (<code>BundleContext.registerService</code>), modify (
- * <code>ServiceRegistration.setProperties</code>) or unregister (
- * <code>ServiceRegistration.unregister</code>) a service while being
+ * not register ({@code BundleContext.registerService}), modify (
+ * {@code ServiceRegistration.setProperties}) or unregister (
+ * {@code ServiceRegistration.unregister}) a service while being
  * synchronized on any object.
  * 
  * <p>
- * The <code>ServiceTracker</code> class is thread-safe. It does not call a
- * <code>ServiceTrackerCustomizer</code> while holding any locks.
- * <code>ServiceTrackerCustomizer</code> implementations must also be
+ * The {@code ServiceTracker} class is thread-safe. It does not call a
+ * {@code ServiceTrackerCustomizer} while holding any locks.
+ * {@code ServiceTrackerCustomizer} implementations must also be
  * thread-safe.
  * 
+ * @param <S> The type of the service being tracked.
+ * @param <T> The type of the tracked object.
  * @ThreadSafe
- * @version $Revision: 5874 $
+ * @version $Id: c654a963336cee74762b8f54c8cef8d5774f8b4d $
  */
-public interface ServiceTrackerCustomizer {
+public interface ServiceTrackerCustomizer<S, T> {
 	/**
-	 * A service is being added to the <code>ServiceTracker</code>.
+	 * A service is being added to the {@code ServiceTracker}.
 	 * 
 	 * <p>
 	 * This method is called before a service which matched the search
-	 * parameters of the <code>ServiceTracker</code> is added to the
-	 * <code>ServiceTracker</code>. This method should return the service object
-	 * to be tracked for the specified <code>ServiceReference</code>. The
-	 * returned service object is stored in the <code>ServiceTracker</code> and
-	 * is available from the <code>getService</code> and
-	 * <code>getServices</code> methods.
+	 * parameters of the {@code ServiceTracker} is added to the
+	 * {@code ServiceTracker}. This method should return the service object
+	 * to be tracked for the specified {@code ServiceReference}. The
+	 * returned service object is stored in the {@code ServiceTracker} and
+	 * is available from the {@code getService} and
+	 * {@code getServices} methods.
 	 * 
 	 * @param reference The reference to the service being added to the
-	 *        <code>ServiceTracker</code>.
+	 *        {@code ServiceTracker}.
 	 * @return The service object to be tracked for the specified referenced
-	 *         service or <code>null</code> if the specified referenced service
+	 *         service or {@code null} if the specified referenced service
 	 *         should not be tracked.
 	 */
-	public Object addingService(ServiceReference reference);
+	public T addingService(ServiceReference<S> reference);
 
 	/**
-	 * A service tracked by the <code>ServiceTracker</code> has been modified.
+	 * A service tracked by the {@code ServiceTracker} has been modified.
 	 * 
 	 * <p>
 	 * This method is called when a service being tracked by the
-	 * <code>ServiceTracker</code> has had it properties modified.
+	 * {@code ServiceTracker} has had it properties modified.
 	 * 
 	 * @param reference The reference to the service that has been modified.
 	 * @param service The service object for the specified referenced service.
 	 */
-	public void modifiedService(ServiceReference reference, Object service);
+	public void modifiedService(ServiceReference<S> reference, T service);
 
 	/**
-	 * A service tracked by the <code>ServiceTracker</code> has been removed.
+	 * A service tracked by the {@code ServiceTracker} has been removed.
 	 * 
 	 * <p>
 	 * This method is called after a service is no longer being tracked by the
-	 * <code>ServiceTracker</code>.
+	 * {@code ServiceTracker}.
 	 * 
 	 * @param reference The reference to the service that has been removed.
 	 * @param service The service object for the specified referenced service.
 	 */
-	public void removedService(ServiceReference reference, Object service);
+	public void removedService(ServiceReference<S> reference, T service);
 }
diff --git a/framework/src/main/resources/org/osgi/framework/hooks/bundle/packageinfo b/framework/src/main/resources/org/osgi/framework/hooks/bundle/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/framework/src/main/resources/org/osgi/framework/hooks/bundle/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/framework/src/main/resources/org/osgi/framework/hooks/resolver/packageinfo b/framework/src/main/resources/org/osgi/framework/hooks/resolver/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/framework/src/main/resources/org/osgi/framework/hooks/resolver/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/framework/src/main/resources/org/osgi/framework/hooks/service/packageinfo b/framework/src/main/resources/org/osgi/framework/hooks/service/packageinfo
index 7c8de03..3987f9c 100644
--- a/framework/src/main/resources/org/osgi/framework/hooks/service/packageinfo
+++ b/framework/src/main/resources/org/osgi/framework/hooks/service/packageinfo
@@ -1 +1 @@
-version 1.0
+version 1.1
diff --git a/framework/src/main/resources/org/osgi/framework/hooks/weaving/packageinfo b/framework/src/main/resources/org/osgi/framework/hooks/weaving/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/framework/src/main/resources/org/osgi/framework/hooks/weaving/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/framework/src/main/resources/org/osgi/framework/packageinfo b/framework/src/main/resources/org/osgi/framework/packageinfo
index ccee95e..fec6063 100644
--- a/framework/src/main/resources/org/osgi/framework/packageinfo
+++ b/framework/src/main/resources/org/osgi/framework/packageinfo
@@ -1 +1 @@
-version 1.5
+version 1.6
diff --git a/framework/src/main/resources/org/osgi/framework/startlevel/packageinfo b/framework/src/main/resources/org/osgi/framework/startlevel/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/framework/src/main/resources/org/osgi/framework/startlevel/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/framework/src/main/resources/org/osgi/framework/wiring/packageinfo b/framework/src/main/resources/org/osgi/framework/wiring/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/framework/src/main/resources/org/osgi/framework/wiring/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/framework/src/main/resources/org/osgi/util/tracker/packageinfo b/framework/src/main/resources/org/osgi/util/tracker/packageinfo
index cc13f19..ccee95e 100644
--- a/framework/src/main/resources/org/osgi/util/tracker/packageinfo
+++ b/framework/src/main/resources/org/osgi/util/tracker/packageinfo
@@ -1 +1 @@
-version 1.4
+version 1.5