Upgrade to latest OSGi compendium API. (FELIX-1205)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@797561 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationContext.java b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationContext.java
index c04fcf8..41c8864 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationContext.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationContext.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.application/src/org/osgi/application/ApplicationContext.java,v 1.15 2006/07/11 13:19:02 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
@@ -24,26 +22,26 @@
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
 
-
 /**
  * <code>ApplicationContext</code> is the access point for an OSGi-aware
  * application to the features of the OSGi Service Platform. Each application
  * instance will have its own <code>ApplicationContext</code> instance, which
  * will not be reused after destorying the corresponding application instace.
  * <p>
- * Application instances can obtain their <code>ApplicationContext</code>
- * using the {@link Framework#getApplicationContext} method.
+ * Application instances can obtain their <code>ApplicationContext</code> using
+ * the {@link Framework#getApplicationContext} method.
  * <p>
- * The lifecycle of an <code>ApplicationContext</code> instance is bound to
- * the lifecycle of the corresponding application instance. The 
+ * The lifecycle of an <code>ApplicationContext</code> instance is bound to the
+ * lifecycle of the corresponding application instance. The
  * <code>ApplicationContext</code> becomes available when the application is
  * started and it is invalidated when the application instance is stopped (i.e.
- * the "stop" method of the application activator object returned).
- * All method calls (except {@link #getApplicationId()} and 
- * {@link #getInstanceId()}) to an invalidated context object result an 
- * <code>IllegalStateException</code>.
+ * the "stop" method of the application activator object returned). All method
+ * calls (except {@link #getApplicationId()} and {@link #getInstanceId()}) to an
+ * invalidated context object result an <code>IllegalStateException</code>.
  * 
  * @see org.osgi.application.Framework
+ * 
+ * @version $Revision: 5673 $
  */
 public interface ApplicationContext {
 
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceEvent.java b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceEvent.java
index cfb4cec..cbb3ee5 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceEvent.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceEvent.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.application/src/org/osgi/application/ApplicationServiceEvent.java,v 1.6 2006/07/11 13:19:02 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
@@ -40,7 +38,7 @@
  * @see org.osgi.framework.ServiceEvent
  * @see ApplicationServiceListener
  * 
- * @version $Revision: 1.6 $
+ * @version $Revision: 5673 $
  */
 public class ApplicationServiceEvent extends ServiceEvent {
 
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceListener.java b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceListener.java
index 1a7d36f..7db5d2b 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/ApplicationServiceListener.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.application/src/org/osgi/application/ApplicationServiceListener.java,v 1.6 2006/07/12 21:21:34 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
@@ -54,7 +52,7 @@
  * objects is further filtered according to package sources as defined in
  * {@link ServiceReference#isAssignableTo(Bundle, String)}.
  * 
- * @version $Revision: 1.6 $
+ * @version $Revision: 5673 $
  * @see ApplicationServiceEvent
  * @see ServicePermission
  */
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/Framework.java b/org.osgi.compendium/src/main/java/org/osgi/application/Framework.java
index 4696115..b81e93c 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/application/Framework.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/Framework.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.application/src/org/osgi/application/Framework.java,v 1.9 2006/07/11 13:19:02 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,8 +19,10 @@
 import java.util.Hashtable;
 
 /**
- * Using this class, OSGi-aware applications can obtain their {@link ApplicationContext}. 
- *
+ * Using this class, OSGi-aware applications can obtain their
+ * {@link ApplicationContext}.
+ * 
+ * @version $Revision: 5673 $
  */
 public final class Framework {
 
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/package.html b/org.osgi.compendium/src/main/java/org/osgi/application/package.html
new file mode 100644
index 0000000..5230b62
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Foreign Application Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.application; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/application/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/application/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/application/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationAdminPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationAdminPermission.java
index 5615148..1993330 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationAdminPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationAdminPermission.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ApplicationAdminPermission.java,v 1.34 2006/07/12 21:22:11 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). 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,21 +17,27 @@
 package org.osgi.service.application;
 
 import java.security.Permission;
-import java.util.*;
+import java.util.Hashtable;
+import java.util.StringTokenizer;
+import java.util.Vector;
 
-import org.osgi.framework.*;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
 
 /**
- * This class implements permissions for manipulating applications and
- * their instances.
+ * This class implements permissions for manipulating applications and their
+ * instances.
  * <P>
  * ApplicationAdminPermission can be targeted to applications that matches the
  * specified filter.
  * <P>
  * ApplicationAdminPermission may be granted for different actions:
- * <code>lifecycle</code>, <code>schedule</code> and <code>lock</code>.
- * The permission <code>schedule</code> implies the permission
+ * <code>lifecycle</code>, <code>schedule</code> and <code>lock</code>. The
+ * permission <code>schedule</code> implies the permission
  * <code>lifecycle</code>.
+ * 
+ * @version $Revision: 6860 $
  */
 public class ApplicationAdminPermission extends Permission {
 	private static final long serialVersionUID = 1L;
@@ -146,7 +150,7 @@
 			try {
 				newPerm = new ApplicationAdminPermission( this.filter, this.actions );
 			}catch( InvalidSyntaxException e ) {
-				throw new RuntimeException( "Internal error" ); /* this can never happen */
+				throw new RuntimeException(e); /* this can never happen */
 			}
 		}
 		else	
@@ -303,6 +307,9 @@
   	private String pattern;
   	private ApplicationDescriptor appDesc;
   	
+  	/**
+  	 * @param pattern
+  	 */
   	public SignerWrapper(String pattern) {
   		this.pattern = pattern;    			
   	}
@@ -333,71 +340,9 @@
   }
   
   private Filter getFilter() {
-  	String transformedFilter = filter;
-  	
   	if (appliedFilter == null) {
   		try {
-  			int pos = filter.indexOf("signer"); //$NON-NLS-1$
-  			if (pos != -1){ 
-  			
-  				//there may be a signer attribute 
-    			StringBuffer filterBuf = new StringBuffer(filter);
-    			int numAsteriskFound = 0; //use as offset to replace in buffer
-    			
-    			int walkbackPos; //temp pos
-
-    			//find occurences of (signer= and escape out *'s
-    			while (pos != -1) {
-
-    				//walk back and look for '(' to see if this is an attr
-    				walkbackPos = pos-1; 
-    				
-    				//consume whitespace
-    				while(walkbackPos >= 0 && Character.isWhitespace(filter.charAt(walkbackPos))) {
-    					walkbackPos--;
-    				}
-    				if (walkbackPos <0) {
-    					//filter is invalid - FilterImpl will throw error
-    					break;
-    				}
-    				
-    				//check to see if we have unescaped '('
-    				if (filter.charAt(walkbackPos) != '(' || (walkbackPos > 0 && filter.charAt(walkbackPos-1) == '\\')) {
-    					//'(' was escaped or not there
-    					pos = filter.indexOf("signer",pos+6); //$NON-NLS-1$
-    					continue;
-    				}     				
-    				pos+=6; //skip over 'signer'
-
-    				//found signer - consume whitespace before '='
-    				while (Character.isWhitespace(filter.charAt(pos))) {
-    					pos++;
-    				}
-
-    				//look for '='
-    				if (filter.charAt(pos) != '=') {
-    					//attr was signerx - keep looking
-    					pos = filter.indexOf("signer",pos); //$NON-NLS-1$
-    					continue;
-    				}
-    				pos++; //skip over '='
-    				
-    				//found signer value - escape '*'s
-    				while (!(filter.charAt(pos) == ')' && filter.charAt(pos-1) != '\\')) {
-    					if (filter.charAt(pos) == '*') {
-    						filterBuf.insert(pos+numAsteriskFound,'\\');
-    						numAsteriskFound++;
-    					}
-    					pos++;
-    				}
-
-    				//end of signer value - look for more?
-    				pos = filter.indexOf("signer",pos); //$NON-NLS-1$
-    			} //end while (pos != -1)
-    			transformedFilter = filterBuf.toString();
-  			} //end if (pos != -1)
-
-  			appliedFilter = FrameworkUtil.createFilter( transformedFilter );
+  			appliedFilter = FrameworkUtil.createFilter(filter);
 		} catch (InvalidSyntaxException e) {
 			//we will return null
 		}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationDescriptor.java b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationDescriptor.java
index 4764bd7..37287e2 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationDescriptor.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationDescriptor.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ApplicationDescriptor.java,v 1.61 2006/07/10 12:02:31 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). 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,7 +18,9 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.security.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
 import java.util.Map;
 
 import org.osgi.framework.Constants;
@@ -30,6 +30,8 @@
  * An OSGi service that represents an installed application and stores
  * information about it. The application descriptor can be used for instance
  * creation.
+ * 
+ * @version $Revision: 6860 $
  */
 
 public abstract class ApplicationDescriptor {
@@ -263,8 +265,9 @@
 	 * The following steps are made:
 	 * <UL>
 	 * <LI>Check for the appropriate permission.
-	 * <LI>Check the locking state of the application. If locked then return
-	 * null otherwise continue.
+	 * <LI>Check the locking state of the application. If locked then throw
+	 *     an {@link ApplicationException} with the reason code 
+	 *     {@link ApplicationException#APPLICATION_LOCKED}.
 	 * <LI>Calls the <code>launchSpecific()</code> method to create and start an application
 	 * instance.
 	 * <LI>Returns the <code>ApplicationHandle</code> returned by the 
@@ -290,7 +293,7 @@
 	 *       <code>org.osgi.</code>.</li>
 	 * </ul>
 	 * <P>
-	 * The method is synchonous, it return only when the application instance was
+	 * The method is synchronous, it return only when the application instance was
 	 * successfully started or the attempt to start it failed.
 	 * <P>
 	 * This method never returns <code>null</code>. If launching an application fails,
@@ -386,7 +389,9 @@
 	 * <p>
 	 * The <code>Map</code> argument of the  method contains startup 
 	 * arguments for the application. The keys used in the Map must be non-null, 
-	 * non-empty <code>String<code> objects.
+	 * non-empty <code>String<code> objects. The argument values must be
+     * of primitive types, wrapper classes of primitive types, <code>String</code>
+     * or arrays or collections of these.
      * <p>
      * The created schedules have a unique identifier within the scope of this
      * <code>ApplicationDescriptor</code>. This identifier can be specified
@@ -428,6 +433,9 @@
      *               <li> {@link ApplicationException#APPLICATION_SCHEDULING_FAILED}
      *                 if the scheduling failed due to some internal reason
      *                 (e.g. persistent storage error).
+     *               <li> {@link ApplicationException#APPLICATION_INVALID_STARTUP_ARGUMENT}
+     *                 if the specified startup argument doesn't satisfy the 
+	 *                 type or value constraints of startup arguments.
      *              </ul>
 	 * @throws SecurityException
 	 *             if the caller doesn't have "schedule"
@@ -594,7 +602,7 @@
 				throw e;
 			}
 			catch (Throwable e) {
-				throw new RuntimeException(e.toString());
+				throw new RuntimeException(e);
 			}
 		}
 
@@ -614,7 +622,7 @@
 				throw e;
 			}
 			catch (Throwable e) {
-				throw new RuntimeException(e.toString());
+				throw new RuntimeException(e);
 			}
 		}
 
@@ -634,7 +642,7 @@
 				throw e;
 			}
 			catch (Throwable e) {
-				throw new RuntimeException(e.toString());
+				throw new RuntimeException(e);
 			}
 		}
 
@@ -654,7 +662,7 @@
 				throw e;
 			}
 			catch (Throwable e) {
-				throw new RuntimeException(e.toString());
+				throw new RuntimeException(e);
 			}
 		}
 
@@ -682,7 +690,7 @@
 				throw e;
 			}
 			catch (Throwable e) {
-				throw new RuntimeException(e.toString());
+				throw new RuntimeException(e);
 			}
 		}
 
@@ -705,7 +713,7 @@
 				throw e;
 			}
 			catch (Throwable e) {
-				throw new RuntimeException(e.toString());
+				throw new RuntimeException(e);
 			}
 		}
 	}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationException.java b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationException.java
index c30e112..485f71d 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationException.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ApplicationException.java,v 1.10 2006/07/10 11:49:12 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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,28 +17,37 @@
 package org.osgi.service.application;
 
 /**
- * This exception is used to indicate problems related to application 
- * lifecycle management.
+ * This exception is used to indicate problems related to application lifecycle
+ * management.
  * 
- * <code>ApplicationException</code> object is created by the Application Admin to denote
- * an exception condition in the lifecycle of an application.
- * <code>ApplicationException</code>s should not be created by developers.
- * <br/>
- * <code>ApplicationException</code>s are associated with an error code. This code
- * describes the type of problem reported in this exception. The possible codes are:
+ * <code>ApplicationException</code> object is created by the Application Admin
+ * to denote an exception condition in the lifecycle of an application.
+ * <code>ApplicationException</code>s should not be created by developers. <br/>
+ * <code>ApplicationException</code>s are associated with an error code. This
+ * code describes the type of problem reported in this exception. The possible
+ * codes are:
  * <ul>
- * <li> {@link #APPLICATION_LOCKED} - The application couldn't be launched because it is locked.</li>
- * <li> {@link #APPLICATION_NOT_LAUNCHABLE} - The application is not in launchable state.</li>
- * <li> {@link #APPLICATION_INTERNAL_ERROR} - An exception was thrown by the application or its
- *       container during launch.</li>
+ * <li> {@link #APPLICATION_LOCKED} - The application couldn't be launched
+ * because it is locked.</li>
+ * <li> {@link #APPLICATION_NOT_LAUNCHABLE} - The application is not in
+ * launchable state.</li>
+ * <li> {@link #APPLICATION_INTERNAL_ERROR} - An exception was thrown by the
+ * application or its container during launch.</li>
  * <li> {@link #APPLICATION_SCHEDULING_FAILED} - The scheduling of an application
- *       failed.
+ * failed.
+ * <li> {@link #APPLICATION_DUPLICATE_SCHEDULE_ID} - The application scheduling
+ * failed because the specified identifier is already in use.
+ * <li> {@link #APPLICATION_EXITVALUE_NOT_AVAILABLE} - The exit value is not
+ * available for an application instance because the instance has not
+ * terminated.
+ * <li> {@link #APPLICATION_INVALID_STARTUP_ARGUMENT} - One of the specified 
+ * startup arguments is invalid, for example its type is not permitted.
  * </ul>
  * 
+ * @version $Revision: 6083 $
  */
 public class ApplicationException extends Exception {
 	private static final long serialVersionUID = -7173190453622508207L;
-	private final Throwable cause;
 	private final int errorCode;
 	
 	/**
@@ -54,16 +61,17 @@
 	 * attribute is false.
 	 */
 	public static final int APPLICATION_NOT_LAUNCHABLE = 0x02;
-	
+
 	/**
-	 * An exception was thrown by the application or the corresponding
-	 * container during launch. The exception is available in {@link #getCause()}.
+	 * An exception was thrown by the application or the corresponding container
+	 * during launch. The exception is available from <code>getCause()</code>.
 	 */
 	public static final int APPLICATION_INTERNAL_ERROR = 0x03;
     
     /**
      * The application schedule could not be created due to some internal error
-     * (for example, the schedule information couldn't be saved).
+     * (for example, the schedule information couldn't be saved due to some
+	 * storage error).
      */
     public static final int APPLICATION_SCHEDULING_FAILED = 0x04;
     
@@ -74,11 +82,28 @@
     public static final int APPLICATION_DUPLICATE_SCHEDULE_ID = 0x05;
 
 	/**
+	 * The exit value is not available for an application instance because the
+	 * instance has not terminated.
+	 *
+	 * @since 1.1
+	 */
+    public static final int APPLICATION_EXITVALUE_NOT_AVAILABLE = 0x06;
+
+	/**
+	 * One of the specified startup arguments is invalid, for example its 
+	 * type is not permitted.
+	 *
+	 * @since 1.1
+	 */
+    public static final int APPLICATION_INVALID_STARTUP_ARGUMENT = 0x07;
+
+	/**
 	 * Creates an <code>ApplicationException</code> with the specified error code.
 	 * @param errorCode The code of the error 
 	 */
 	public ApplicationException(int errorCode) {
-		this(errorCode,(Throwable) null);
+		super();
+		this.errorCode = errorCode;
 	}
 	
 	/**
@@ -88,8 +113,7 @@
 	 * @param cause The cause of this exception.
 	 */
 	public ApplicationException(int errorCode, Throwable cause) {
-		super();
-		this.cause = cause;
+		super(cause);
 		this.errorCode = errorCode;
 	}
 
@@ -99,7 +123,8 @@
 	 * @param message The associated message
 	 */
 	public ApplicationException(int errorCode, String message) {
-		this(errorCode, message,null);
+		super(message);
+		this.errorCode = errorCode;
 	}
 
 	/**
@@ -110,24 +135,24 @@
 	 * @param cause The cause of this exception.
 	 */
 	public ApplicationException(int errorCode, String message, Throwable cause) {
-		super(message);
-		this.cause = cause;
+		super(message, cause);
 		this.errorCode = errorCode;
 	}
 
 	/**
-	 * Returns the cause of this exception or <code>null</code> if no cause
-	 * was specified when this exception was created.
+	 * Returns the cause of this exception or <code>null</code> if no cause was
+	 * set.
 	 * 
-	 * @return The cause of this exception or <code>null</code> if no cause
-	 *         was specified.
+	 * @return The cause of this exception or <code>null</code> if no cause was
+	 *         set.
 	 */
 	public Throwable getCause() {
-		return cause;
+		return super.getCause();
 	}
 
 	/**
-	 * Returns the error code associcated with this exception.
+	 * Returns the error code associated with this exception.
+	 * 
 	 * @return The error code of this exception.
 	 */
 	public int getErrorCode() {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationHandle.java b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationHandle.java
index a0bdc89..7168269 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationHandle.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/ApplicationHandle.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ApplicationHandle.java,v 1.41 2006/07/10 12:02:31 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). 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,7 +18,9 @@
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.security.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
 
 import org.osgi.framework.Constants;
 
@@ -29,6 +29,8 @@
  * of an application. It provides the functionality to query and manipulate the
  * lifecycle state of the represented application instance. It defines constants
  * for the lifecycle states.
+ * 
+ * @version $Revision: 5901 $
  */
 public abstract class ApplicationHandle {
 	/*
@@ -50,11 +52,19 @@
 	public final static String APPLICATION_DESCRIPTOR	= "application.descriptor";
 	
 	/**
-	 * The property key for the state of this appliction instance.
+	 * The property key for the state of this application instance.
 	 */
 	public final static String APPLICATION_STATE		= "application.state";
 
 	/**
+	 * The property key for the supports exit value property of this application
+	 * instance.
+	 * 
+	 * @since 1.1
+	 */
+	public final static String APPLICATION_SUPPORTS_EXITVALUE = "application.supports.exitvalue";
+
+	/**
 	 * The application instance is running. This is the initial state of a newly
 	 * created application instance.
 	 */
@@ -137,6 +147,45 @@
 	public abstract String getState();
 
 	/**
+	 * Returns the exit value for the application instance. The timeout
+	 * specifies how the method behaves when the application has not yet
+	 * terminated. A negative, zero or positive value may be used.
+	 * <ul>
+	 * <li> negative - The method does not wait for termination. If the
+	 * application has not terminated then an <code>ApplicationException</code>
+	 * is thrown.</li>
+	 * 
+	 * <li> zero - The method waits until the application terminates.</li>
+	 * 
+	 * <li> positive - The method waits until the application terminates or the
+	 * timeout expires. If the timeout expires and the application has not
+	 * terminated then an <code>ApplicationException</code> is thrown.</li>
+	 * </ul>
+	 * <p>
+	 * The default implementation throws an
+	 * <code>UnsupportedOperationException</code>. The application model should
+	 * override this method if exit values are supported.
+	 * </p>
+	 * 
+	 * @param timeout The maximum time in milliseconds to wait for the
+	 *        application to timeout.
+	 * @return The exit value for the application instance. The value is
+	 *         application specific.
+	 * @throws UnsupportedOperationException If the application model does not
+	 *         support exit values.
+	 * @throws InterruptedException If the thread is interrupted while waiting
+	 *         for the timeout.
+	 * @throws ApplicationException If the application has not terminated. The
+	 *         error code will be
+	 *         {@link ApplicationException#APPLICATION_EXITVALUE_NOT_AVAILABLE}.
+	 * 
+	 * @since 1.1
+	 */
+	public Object getExitValue(long timeout) throws ApplicationException, InterruptedException{
+		throw new UnsupportedOperationException();
+	}
+
+	/**
 	 * Returns the unique identifier of this instance. This value is also
 	 * available as a service property of this application handle's service.pid.
 	 * 
@@ -181,7 +230,7 @@
 		}catch( SecurityException se ) {
 			descriptor.isLaunchableSpecific(); /* check whether the bundle was uninstalled */
 			                                   /* if yes, throws IllegalStateException */
-			throw se;                          /* otherwise throw the catched SecurityException */
+			throw se; /* otherwise throw the caught SecurityException */
 		}
 		destroySpecific();
 	}
@@ -265,7 +314,7 @@
 				throw e;
 			}
 			catch (Throwable e) {
-				throw new RuntimeException(e.toString());
+				throw new RuntimeException(e);
 			}
 		}
 		void destroy() {
@@ -284,7 +333,7 @@
 				throw e;
 			}
 			catch (Throwable e) {
-				throw new RuntimeException(e.toString());
+				throw new RuntimeException(e);
 			}
 		}
 	}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/ScheduledApplication.java b/org.osgi.compendium/src/main/java/org/osgi/service/application/ScheduledApplication.java
index 46cfe5e..02d776f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/application/ScheduledApplication.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/ScheduledApplication.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.application/src/org/osgi/service/application/ScheduledApplication.java,v 1.20 2006/07/06 14:59:29 sboshev Exp $
- * 
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,10 +27,12 @@
  * Each <code>ScheduledApplication</code> instance has an identifier which is
  * unique within the scope of the application being scheduled.
  * <p>
- * <code>ScheduledApplication</code> instances are registered as services.
- * The {@link #APPLICATION_PID} service property contains the PID of the
- * application being scheduled, the {@link #SCHEDULE_ID} service property
- * contains the schedule identifier.
+ * <code>ScheduledApplication</code> instances are registered as services. The
+ * {@link #APPLICATION_PID} service property contains the PID of the application
+ * being scheduled, the {@link #SCHEDULE_ID} service property contains the
+ * schedule identifier.
+ * 
+ * @version $Revision: 5673 $
  */
 public interface ScheduledApplication {
     
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/application/package.html
new file mode 100644
index 0000000..18daeb5
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Application Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.application; version=&quot;[1.1,2.0)&quot;
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/application/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/application/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/application/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintContainer.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintContainer.java
new file mode 100644
index 0000000..23cb758
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintContainer.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.container;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.osgi.service.blueprint.reflect.BeanMetadata;
+import org.osgi.service.blueprint.reflect.ComponentMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceListMetadata;
+import org.osgi.service.blueprint.reflect.ReferenceMetadata;
+import org.osgi.service.blueprint.reflect.ServiceMetadata;
+import org.osgi.service.blueprint.reflect.ServiceReferenceMetadata;
+
+/**
+ * A Blueprint Container represents the managed state of a Blueprint bundle.
+ * 
+ * A Blueprint Container provides access to all managed components. These are
+ * the beans, services, and service references. Only bundles in the
+ * <code>ACTIVE</code> state (and also the <code>STARTING</code> state for
+ * bundles awaiting lazy activation) can have an associated Blueprint Container.
+ * A given Bundle Context has at most one associated Blueprint Container.
+ * 
+ * A Blueprint Container can be obtained by injecting the predefined
+ * &quot;blueprintContainer&quot; component id. The Blueprint Container is also
+ * registered as a service and its managed components can be queried.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7556 $
+ */
+public interface BlueprintContainer {
+	/**
+	 * Returns the set of component ids managed by this Blueprint Container.
+	 * 
+	 * @return An immutable Set of Strings, containing the ids of all of the
+	 *         components managed within this Blueprint Container.
+	 */
+	Set/* <String> */getComponentIds();
+
+	/**
+	 * Return the component instance for the specified component id.
+	 * 
+	 * If the component's manager has not yet been activated, calling this
+	 * operation will atomically activate it. If the component has singleton
+	 * scope, the activation will cause the component instance to be created and
+	 * initialized. If the component has prototype scope, then each call to this
+	 * method will return a new component instance.
+	 * 
+	 * @param id The component id for the requested component instance.
+	 * @return A component instance for the component with the specified
+	 *         component id.
+	 * @throws NoSuchComponentException If no component with the specified
+	 *         component id is managed by this Blueprint Container.
+	 */
+	Object getComponentInstance(String id);
+
+	/**
+	 * Return the Component Metadata object for the component with the specified
+	 * component id.
+	 * 
+	 * @param id The component id for the requested Component Metadata.
+	 * @return The Component Metadata object for the component with the
+	 *         specified component id.
+	 * @throws NoSuchComponentException If no component with the specified
+	 *         component id is managed by this Blueprint Container.
+	 */
+	ComponentMetadata getComponentMetadata(String id);
+
+	/**
+	 * Return all {@link ComponentMetadata} objects of the specified Component
+	 * Metadata type. The supported Component Metadata types are
+	 * {@link ComponentMetadata} (which returns the Component Metadata for all
+	 * defined manager types), {@link BeanMetadata} ,
+	 * {@link ServiceReferenceMetadata} (which returns both
+	 * {@link ReferenceMetadata} and {@link ReferenceListMetadata} objects), and
+	 * {@link ServiceMetadata}. The collection will include all Component
+	 * Metadata objects of the requested type, including components that are
+	 * declared inline.
+	 * 
+	 * @param type The super type or type of the requested Component Metadata
+	 *        objects.
+	 * @return An immutable collection of Component Metadata objects of the
+	 *         specified type.
+	 */
+	/* <T extends ComponentMetadata> */Collection/* <T> */getMetadata(
+			Class/* <T> */type);
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintEvent.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintEvent.java
new file mode 100644
index 0000000..8e0dedf
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintEvent.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.container;
+
+import org.osgi.framework.Bundle;
+
+/**
+ * A Blueprint Event.
+ * 
+ * <p>
+ * <code>BlueprintEvent</code> objects are delivered to all registered
+ * {@link BlueprintListener} services. Blueprint Events must be asynchronously
+ * delivered in chronological order with respect to each listener.
+ * 
+ * <p>
+ * In addition, after a Blueprint Listener is registered, the Blueprint extender
+ * will synchronously send to this Blueprint Listener the last Blueprint Event
+ * for each ready Blueprint bundle managed by this extender. This
+ * <em>replay</em> of Blueprint Events is designed so that the new Blueprint
+ * Listener can be informed of the state of each Blueprint bundle. Blueprint
+ * Events sent during this replay will have the {@link #isReplay()} flag set.
+ * The Blueprint extender must ensure that this replay phase does not interfere
+ * with new Blueprint Events so that the chronological order of all Blueprint
+ * Events received by the Blueprint Listener is preserved. If the last Blueprint
+ * Event for a given Blueprint bundle is {@link #DESTROYED}, the extender must
+ * not send it during this replay phase.
+ * 
+ * <p>
+ * A type code is used to identify the type of event. The following event types
+ * are defined:
+ * <ul>
+ * <li>{@link #CREATING}</li>
+ * <li>{@link #CREATED}</li>
+ * <li>{@link #DESTROYING}</li>
+ * <li>{@link #DESTROYED}</li>
+ * <li>{@link #FAILURE}</li>
+ * <li>{@link #GRACE_PERIOD}</li>
+ * <li>{@link #WAITING}</li>
+ * </ul>
+ * 
+ * <p>
+ * In addition to calling the registered {@link BlueprintListener} services, the
+ * Blueprint extender must also send those events to the Event Admin service, if
+ * it is available.
+ * 
+ * @see BlueprintListener
+ * @see EventConstants
+ * @Immutable
+ * @version $Revision: 7591 $
+ */
+public class BlueprintEvent {
+
+	/**
+	 * The Blueprint extender has started creating a Blueprint Container for the
+	 * bundle.
+	 */
+	public static final int	CREATING		= 1;
+	/**
+	 * The Blueprint extender has created a Blueprint Container for the bundle.
+	 * This event is sent after the Blueprint Container has been registered as a
+	 * service.
+	 */
+	public static final int	CREATED			= 2;
+	/**
+	 * The Blueprint extender has started destroying the Blueprint Container for
+	 * the bundle.
+	 */
+	public static final int	DESTROYING		= 3;
+	/**
+	 * The Blueprint Container for the bundle has been completely destroyed.
+	 * This event is sent after the Blueprint Container has been unregistered as
+	 * a service.
+	 */
+	public static final int	DESTROYED		= 4;
+	/**
+	 * The Blueprint Container creation for the bundle has failed. If this event
+	 * is sent after a timeout in the Grace Period, the
+	 * {@link #getDependencies()} method must return an array of missing
+	 * mandatory dependencies. The event must also contain the cause of the
+	 * failure as a <code>Throwable</code> through the {@link #getCause()}
+	 * method.
+	 */
+	public static final int	FAILURE			= 5;
+	/**
+	 * The Blueprint Container has entered the grace period. The list of missing
+	 * dependencies must be made available through the
+	 * {@link #getDependencies()} method. During the grace period, a
+	 * {@link #GRACE_PERIOD} event is sent each time the set of unsatisfied
+	 * dependencies changes.
+	 */
+	public static final int	GRACE_PERIOD	= 6;
+	/**
+	 * The Blueprint Container is waiting on the availability of a service to
+	 * satisfy an invocation on a referenced service. The missing dependency
+	 * must be made available through the {@link #getDependencies()} method
+	 * which will return an array containing one filter object as a String.
+	 */
+	public static final int	WAITING			= 7;
+
+	/**
+	 * Type of this event.
+	 * 
+	 * @see #getType()
+	 */
+	private final int		type;
+	/**
+	 * The time when the event occurred.
+	 * 
+	 * @see #getTimestamp()
+	 */
+	private final long		timestamp;
+	/**
+	 * The Blueprint bundle.
+	 * 
+	 * @see #getBundle()
+	 */
+	private final Bundle	bundle;
+	/**
+	 * The Blueprint extender bundle.
+	 * 
+	 * @see #getExtenderBundle()
+	 */
+	private final Bundle	extenderBundle;
+	/**
+	 * An array containing filters identifying the missing dependencies. Must
+	 * not be <code>null</code> when the event type requires it.
+	 * 
+	 * @see #getDependencies()
+	 */
+	private final String[]	dependencies;
+	/**
+	 * Cause of the failure.
+	 * 
+	 * @see #getCause()
+	 */
+	private final Throwable	cause;
+	/**
+	 * Indicate if this event is a replay event or not.
+	 * 
+	 * @see #isReplay()
+	 */
+	private final boolean	replay;
+
+	/**
+	 * Create a simple <code>BlueprintEvent</code> object.
+	 * 
+	 * @param type The type of this event.
+	 * @param bundle The Blueprint bundle associated with this event. This
+	 *        parameter must not be <code>null</code>.
+	 * @param extenderBundle The Blueprint extender bundle that is generating
+	 *        this event. This parameter must not be <code>null</code>.
+	 */
+	public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle) {
+		this(type, bundle, extenderBundle, null, null);
+	}
+
+	/**
+	 * Create a <code>BlueprintEvent</code> object associated with a set of
+	 * dependencies.
+	 * 
+	 * @param type The type of this event.
+	 * @param bundle The Blueprint bundle associated with this event. This
+	 *        parameter must not be <code>null</code>.
+	 * @param extenderBundle The Blueprint extender bundle that is generating
+	 *        this event. This parameter must not be <code>null</code>.
+	 * @param dependencies An array of <code>String</code> filters for each
+	 *        dependency associated with this event. Must be a non-empty array
+	 *        for event types {@link #GRACE_PERIOD} and {@link #WAITING}. It is
+	 *        optional for event type {@link #FAILURE}. Must be
+	 *        <code>null</code> for other event types.
+	 */
+	public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
+			String[] dependencies) {
+		this(type, bundle, extenderBundle, dependencies, null);
+	}
+
+	/**
+	 * Create a <code>BlueprintEvent</code> object associated with a failure
+	 * cause.
+	 * 
+	 * @param type The type of this event.
+	 * @param bundle The Blueprint bundle associated with this event. This
+	 *        parameter must not be <code>null</code>.
+	 * @param extenderBundle The Blueprint extender bundle that is generating
+	 *        this event. This parameter must not be <code>null</code>.
+	 * @param cause A <code>Throwable</code> object describing the root cause of
+	 *        the event. May be <code>null</code>.
+	 */
+	public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
+			Throwable cause) {
+		this(type, bundle, extenderBundle, null, cause);
+	}
+
+	/**
+	 * Create a <code>BlueprintEvent</code> object associated with a failure
+	 * cause and a set of dependencies.
+	 * 
+	 * @param type The type of this event.
+	 * @param bundle The Blueprint bundle associated with this event. This
+	 *        parameter must not be <code>null</code>.
+	 * @param extenderBundle The Blueprint extender bundle that is generating
+	 *        this event. This parameter must not be <code>null</code>.
+	 * @param dependencies An array of <code>String</code> filters for each
+	 *        dependency associated with this event. Must be a non-empty array
+	 *        for event types {@link #GRACE_PERIOD} and {@link #WAITING}. It is
+	 *        optional for event type {@link #FAILURE}. Must be
+	 *        <code>null</code> for other event types.
+	 * @param cause A <code>Throwable</code> object describing the root cause of
+	 *        this event. May be <code>null</code>.
+	 */
+	public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
+			String[] dependencies, Throwable cause) {
+		this.type = type;
+		this.timestamp = System.currentTimeMillis();
+		this.bundle = bundle;
+		this.extenderBundle = extenderBundle;
+		this.dependencies = dependencies;
+		this.cause = cause;
+		this.replay = false;
+		if (bundle == null) {
+			throw new NullPointerException("bundle must not be null");
+		}
+		if (extenderBundle == null) {
+			throw new NullPointerException("extenderBundle must not be null");
+		}
+		switch (type) {
+			case WAITING :
+			case GRACE_PERIOD :
+				if (dependencies == null) {
+					throw new NullPointerException(
+							"dependencies must not be null");
+				}
+				if (dependencies.length == 0) {
+					throw new IllegalArgumentException(
+							"dependencies must not be length zero");
+				}
+				break;
+			case FAILURE :
+				if ((dependencies != null) && (dependencies.length == 0)) {
+					throw new IllegalArgumentException(
+							"dependencies must not be length zero");
+				}
+				break;
+			default :
+				if (dependencies != null) {
+					throw new IllegalArgumentException(
+							"dependencies must be null");
+				}
+				break;
+		}
+	}
+
+	/**
+	 * Create a new <code>BlueprintEvent</code> from the specified
+	 * <code>BlueprintEvent</code>. The <code>timestamp</code> property will be
+	 * copied from the original event and only the replay property will be
+	 * overridden with the given value.
+	 * 
+	 * @param event The original <code>BlueprintEvent</code> to copy. Must not
+	 *        be <code>null</code>.
+	 * @param replay <code>true</code> if this event should be used as a replay
+	 *        event.
+	 */
+	public BlueprintEvent(BlueprintEvent event, boolean replay) {
+		this.type = event.type;
+		this.timestamp = event.timestamp;
+		this.bundle = event.bundle;
+		this.extenderBundle = event.extenderBundle;
+		this.dependencies = event.dependencies;
+		this.cause = event.cause;
+		this.replay = replay;
+	}
+
+	/**
+	 * Return the type of this event.
+	 * <p>
+	 * The type values are:
+	 * <ul>
+	 * <li>{@link #CREATING}</li>
+	 * <li>{@link #CREATED}</li>
+	 * <li>{@link #DESTROYING}</li>
+	 * <li>{@link #DESTROYED}</li>
+	 * <li>{@link #FAILURE}</li>
+	 * <li>{@link #GRACE_PERIOD}</li>
+	 * <li>{@link #WAITING}</li>
+	 * </ul>
+	 * 
+	 * @return The type of this event.
+	 */
+	public int getType() {
+		return type;
+	}
+
+	/**
+	 * Return the time at which this event was created.
+	 * 
+	 * @return The time at which this event was created.
+	 */
+	public long getTimestamp() {
+		return timestamp;
+	}
+
+	/**
+	 * Return the Blueprint bundle associated with this event.
+	 * 
+	 * @return The Blueprint bundle associated with this event.
+	 */
+	public Bundle getBundle() {
+		return bundle;
+	}
+
+	/**
+	 * Return the Blueprint extender bundle that is generating this event.
+	 * 
+	 * @return The Blueprint extender bundle that is generating this event.
+	 */
+	public Bundle getExtenderBundle() {
+		return extenderBundle;
+	}
+
+	/**
+	 * Return the filters identifying the missing dependencies that caused this
+	 * event.
+	 * 
+	 * @return The filters identifying the missing dependencies that caused this
+	 *         event if the event type is one of {@link #WAITING},
+	 *         {@link #GRACE_PERIOD} or {@link #FAILURE} or <code>null</code>
+	 *         for the other event types.
+	 */
+	public String[] getDependencies() {
+		return dependencies == null ? null : (String[]) dependencies.clone();
+	}
+
+	/**
+	 * Return the cause for this {@link #FAILURE} event.
+	 * 
+	 * @return The cause of the failure for this event. May be <code>null</code>
+	 *         .
+	 */
+	public Throwable getCause() {
+		return cause;
+	}
+
+	/**
+	 * Return whether this event is a replay event.
+	 * 
+	 * @return <code>true</code> if this event is a replay event and
+	 *         <code>false</code> otherwise.
+	 */
+	public boolean isReplay() {
+		return replay;
+	}
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintListener.java
new file mode 100644
index 0000000..937898e
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/BlueprintListener.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.container;
+
+/**
+ * A <code>BlueprintEvent</code> Listener.
+ * 
+ * <p>
+ * To receive Blueprint Events, a bundle must register a Blueprint Listener
+ * service.
+ * 
+ * After a Blueprint Listener is registered, the Blueprint extender must
+ * synchronously send to this Blueprint Listener the last Blueprint Event for
+ * each ready Blueprint bundle managed by this extender. This replay of
+ * Blueprint Events is designed so that the new Blueprint Listener can be
+ * informed of the state of each Blueprint bundle. Blueprint Events sent during
+ * this replay will have the {@link BlueprintEvent#isReplay() isReplay()} flag
+ * set. The Blueprint extender must ensure that this replay phase does not
+ * interfere with new Blueprint Events so that the chronological order of all
+ * Blueprint Events received by the Blueprint Listener is preserved. If the last
+ * Blueprint Event for a given Blueprint bundle is
+ * {@link BlueprintEvent#DESTROYED DESTROYED}, the extender must not send it
+ * during this replay phase.
+ * 
+ * @see BlueprintEvent
+ * @ThreadSafe
+ * @version $Revision: 7564 $
+ */
+public interface BlueprintListener {
+
+	/**
+	 * Receives notifications of a Blueprint Event.
+	 * 
+	 * Implementers should quickly process the event and return.
+	 * 
+	 * @param event The {@link BlueprintEvent}.
+	 */
+	void blueprintEvent(BlueprintEvent event);
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ComponentDefinitionException.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ComponentDefinitionException.java
new file mode 100644
index 0000000..0e29850
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ComponentDefinitionException.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.container;
+
+/**
+ * A Blueprint exception indicating that a component definition is in error.
+ * 
+ * This exception is thrown when a configuration-related error occurs during
+ * creation of a Blueprint Container.
+ * 
+ * @version $Revision: 7556 $
+ */
+public class ComponentDefinitionException extends RuntimeException {
+	private static final long	serialVersionUID	= 1L;
+
+	/**
+	 * Creates a Component Definition Exception with no message or exception
+	 * cause.
+	 */
+	public ComponentDefinitionException() {
+		super();
+	}
+
+	/**
+	 * Creates a Component Definition Exception with the specified message
+	 * 
+	 * @param explanation The associated message.
+	 */
+	public ComponentDefinitionException(String explanation) {
+		super(explanation);
+	}
+
+	/**
+	 * Creates a Component Definition Exception with the specified message and
+	 * exception cause.
+	 * 
+	 * @param explanation The associated message.
+	 * @param cause The cause of this exception.
+	 */
+	public ComponentDefinitionException(String explanation, Throwable cause) {
+		super(explanation, cause);
+	}
+
+	/**
+	 * Creates a Component Definition Exception with the exception cause.
+	 * 
+	 * @param cause The cause of this exception.
+	 */
+	public ComponentDefinitionException(Throwable cause) {
+		super(cause);
+	}
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/Converter.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/Converter.java
new file mode 100644
index 0000000..ca6517b
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/Converter.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.container;
+
+/**
+ * Type converter to convert an object to a target type.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7564 $
+ */
+public interface Converter {
+
+	/**
+	 * Return if this converter is able to convert the specified object to the
+	 * specified type.
+	 * 
+	 * @param sourceObject The source object <code>s</code> to convert.
+	 * @param targetType The target type <code>T</code>.
+	 * 
+	 * @return <code>true</code> if the conversion is possible,
+	 *         <code>false</code> otherwise.
+	 */
+	boolean canConvert(Object sourceObject, ReifiedType targetType);
+
+	/**
+	 * Convert the specified object to an instance of the specified type.
+	 * 
+	 * @param sourceObject The source object <code>s</code> to convert.
+	 * @param targetType The target type <code>T</code>.
+	 * @return An instance with a type that is assignable from targetType's raw
+	 *         class
+	 * @throws Exception If the conversion cannot succeed. This exception should
+	 *         not be thrown when the {@link #canConvert canConvert} method has
+	 *         returned <code>true</code>.
+	 */
+	Object convert(Object sourceObject, ReifiedType targetType)
+			throws Exception;
+}
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/EventConstants.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/EventConstants.java
new file mode 100644
index 0000000..d149ab0
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/EventConstants.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.container;
+
+/**
+ * Event property names used in Event Admin events published by a Blueprint
+ * Container.
+ * 
+ * <p>
+ * Each type of event is sent to a different topic:
+ * 
+ * <p>
+ * <code>org/osgi/service/blueprint/container/</code><em>&lt;event-type&gt;</em>
+ * 
+ * <p>
+ * where <em>&lt;event-type&gt;</em> can have the values
+ * {@link BlueprintEvent#CREATING CREATING}, {@link BlueprintEvent#CREATED
+ * CREATED}, {@link BlueprintEvent#DESTROYING DESTROYING},
+ * {@link BlueprintEvent#DESTROYED DESTROYED}, {@link BlueprintEvent#FAILURE
+ * FAILURE}, {@link BlueprintEvent#GRACE_PERIOD GRACE_PERIOD}, or
+ * {@link BlueprintEvent#WAITING WAITING}.
+ * 
+ * <p>
+ * Such events have the following properties:
+ * <ul>
+ * <li>{@link #TYPE type}</li>
+ * <li>{@link #EVENT event}</li>
+ * <li>{@link #TIMESTAMP timestamp}</li>
+ * <li>{@link #BUNDLE bundle}</li>
+ * <li>{@link #BUNDLE_SYMBOLICNAME bundle.symbolicName}</li>
+ * <li>{@link #BUNDLE_ID bundle.id}</li>
+ * <li>{@link #BUNDLE_VERSION bundle.version}</li>
+ * <li>{@link #EXTENDER_BUNDLE_SYMBOLICNAME extender.bundle.symbolicName}</li>
+ * <li>{@link #EXTENDER_BUNDLE_ID extender.bundle.id}</li>
+ * <li>{@link #EXTENDER_BUNDLE_VERSION extender.bundle.version}</li>
+ * <li>{@link #DEPENDENCIES dependencies}</li>
+ * <li>{@link #CAUSE cause}</li>
+ * </ul>
+ * 
+ * @Immutable
+ * @version $Revision: 7564 $
+ */
+public class EventConstants {
+	private EventConstants() {
+		// non-instantiable class
+	}
+
+	/**
+	 * The type of the event that has been issued. This property is of type
+	 * <code>Integer</code> and can take one of the values defined in
+	 * {@link BlueprintEvent}.
+	 */
+	public static final String TYPE = "type";
+
+	/**
+	 * The <code>BlueprintEvent</code> object that caused this event. This
+	 * property is of type {@link BlueprintEvent}.
+	 */
+	public static final String EVENT = "event";
+
+	/**
+	 * The time the event was created. This property is of type
+	 * <code>Long</code>.
+	 */
+	public static final String TIMESTAMP = "timestamp";
+
+	/**
+	 * The Blueprint bundle associated with this event. This property is of type
+	 * <code>Bundle</code>.
+	 */
+	public static final String BUNDLE = "bundle";
+
+	/**
+	 * The bundle id of the Blueprint bundle associated with this event. This
+	 * property is of type <code>Long</code>.
+	 */
+	public static final String BUNDLE_ID = "bundle.id";
+
+	/**
+	 * The bundle symbolic name of the Blueprint bundle associated with this
+	 * event. This property is of type <code>String</code>.
+	 */
+	public static final String BUNDLE_SYMBOLICNAME = "bundle.symbolicName";
+
+	/**
+	 * The bundle version of the Blueprint bundle associated with this event.
+	 * This property is of type <code>Version</code>.
+	 */
+	public static final String BUNDLE_VERSION = "bundle.version";
+
+	/**
+	 * The Blueprint extender bundle that is generating this event. This
+	 * property is of type <code>Bundle</code>.
+	 */
+	public static final String EXTENDER_BUNDLE = "extender.bundle";
+
+	/**
+	 * The bundle id of the Blueprint extender bundle that is generating this
+	 * event. This property is of type <code>Long</code>.
+	 */
+	public static final String EXTENDER_BUNDLE_ID = "extender.bundle.id";
+
+	/**
+	 * The bundle symbolic of the Blueprint extender bundle that is generating
+	 * this event. This property is of type <code>String</code>.
+	 */
+	public static final String EXTENDER_BUNDLE_SYMBOLICNAME = "extender.bundle.symbolicName";
+
+	/**
+	 * The bundle version of the Blueprint extender bundle that is generating
+	 * this event. This property is of type <code>Version</code>.
+	 */
+	public static final String EXTENDER_BUNDLE_VERSION = "extender.bundle.version";
+
+	/**
+	 * The filters identifying the missing dependencies that caused this event
+	 * for a {@link BlueprintEvent#FAILURE FAILURE},
+	 * {@link BlueprintEvent#GRACE_PERIOD GRACE_PERIOD}, or
+	 * {@link BlueprintEvent#WAITING WAITING} event. This property type is an
+	 * array of <code>String</code>.
+	 */
+	public static final String DEPENDENCIES = "dependencies";
+
+	/**
+	 * The cause for a {@link BlueprintEvent#FAILURE FAILURE} event. This
+	 * property is of type <code>Throwable</code>.
+	 */
+	public static final String CAUSE = "cause";
+
+	/**
+	 * Topic prefix for all events issued by the Blueprint Container
+	 */
+	public static final String TOPIC_BLUEPRINT_EVENTS = "org/osgi/service/blueprint/container";
+
+	/**
+	 * Topic for Blueprint Container CREATING events
+	 */
+	public static final String TOPIC_CREATING = TOPIC_BLUEPRINT_EVENTS
+			+ "/CREATING";
+
+	/**
+	 * Topic for Blueprint Container CREATED events
+	 */
+	public static final String TOPIC_CREATED = TOPIC_BLUEPRINT_EVENTS
+			+ "/CREATED";
+
+	/**
+	 * Topic for Blueprint Container DESTROYING events
+	 */
+	public static final String TOPIC_DESTROYING = TOPIC_BLUEPRINT_EVENTS
+			+ "/DESTROYING";
+
+	/**
+	 * Topic for Blueprint Container DESTROYED events
+	 */
+	public static final String TOPIC_DESTROYED = TOPIC_BLUEPRINT_EVENTS
+			+ "/DESTROYED";
+
+	/**
+	 * Topic for Blueprint Container FAILURE events
+	 */
+	public static final String TOPIC_FAILURE = TOPIC_BLUEPRINT_EVENTS
+			+ "/FAILURE";
+
+	/**
+	 * Topic for Blueprint Container GRACE_PERIOD events
+	 */
+	public static final String TOPIC_GRACE_PERIOD = TOPIC_BLUEPRINT_EVENTS
+			+ "/GRACE_PERIOD";
+
+	/**
+	 * Topic for Blueprint Container WAITING events
+	 */
+	public static final String TOPIC_WAITING = TOPIC_BLUEPRINT_EVENTS
+			+ "/WAITING";
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/NoSuchComponentException.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/NoSuchComponentException.java
new file mode 100644
index 0000000..0ee9b30
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/NoSuchComponentException.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.container;
+
+/**
+ * A Blueprint exception indicating that a component does not exist in a
+ * Blueprint Container.
+ * 
+ * This exception is thrown when an attempt is made to create a component
+ * instance or lookup Component Metadata using a component id that does not
+ * exist in the Blueprint Container.
+ * 
+ * @version $Revision: 7556 $
+ */
+public class NoSuchComponentException extends RuntimeException {
+	private static final long	serialVersionUID	= 1L;
+	/**
+	 * The requested component id that generated the exception.
+	 */
+	private final String		componentId;
+
+	/**
+	 * Create a No Such Component Exception for a non-existent component.
+	 * 
+	 * @param msg The associated message.
+	 * @param id The id of the non-existent component.
+	 */
+	public NoSuchComponentException(String msg, String id) {
+		super(msg);
+		this.componentId = id;
+	}
+
+	/**
+	 * Create a No Such Component Exception for a non-existent component.
+	 * 
+	 * @param id The id of the non-existent component.
+	 */
+	public NoSuchComponentException(String id) {
+		super("No component with id '" + (id == null ? "<null>" : id)
+				+ "' could be found");
+		this.componentId = id;
+	}
+
+	/**
+	 * Returns the id of the non-existent component.
+	 * 
+	 * @return The id of the non-existent component.
+	 */
+	public String getComponentId() {
+		return componentId;
+	}
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ReifiedType.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ReifiedType.java
new file mode 100644
index 0000000..a923bcd
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ReifiedType.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.container;
+
+/**
+ * Provides access to a concrete type and its optional generic type parameters.
+ * 
+ * <p>
+ * Java 5 and later support generic types. These types consist of a raw class
+ * with type parameters. This class models such a <code>Type</code> class but
+ * ensures that the type is <em>reified</em>. Reification means that the Type
+ * graph associated with a Java 5 <code>Type</code> instance is traversed until
+ * the type becomes a concrete class. This class is available with the
+ * {@link #getRawClass()} method. The optional type parameters are recursively
+ * represented as Reified Types.
+ * 
+ * <p>
+ * In Java 1.4, a class has by definition no type parameters. This class
+ * implementation provides the Reified Type for Java 1.4 by making the raw class
+ * the Java 1.4 class and using a Reified Type based on the <code>Object</code>
+ * class for any requested type parameter.
+ * 
+ * <p>
+ * A Blueprint extender implementations can subclass this class and provide
+ * access to the generic type parameter graph for conversion. Such a subclass
+ * must <em>reify</em> the different Java 5 <code>Type</code> instances into the
+ * reified form. That is, a form where the raw Class is available with its
+ * optional type parameters as Reified Types.
+ * 
+ * @Immutable
+ * @version $Revision: 7564 $
+ */
+public class ReifiedType {
+	private final static ReifiedType	OBJECT	= new ReifiedType(Object.class);
+
+	private final Class					clazz;
+
+	/**
+	 * Create a Reified Type for a raw Java class without any generic type
+	 * parameters. Subclasses can provide the optional generic type parameter
+	 * information. Without subclassing, this instance has no type parameters.
+	 * 
+	 * @param clazz The raw class of the Reified Type.
+	 */
+	public ReifiedType(Class clazz) {
+		this.clazz = clazz;
+	}
+
+	/**
+	 * Return the raw class represented by this type.
+	 * 
+	 * The raw class represents the concrete class that is associated with a
+	 * type declaration. This class could have been deduced from the generics
+	 * type parameter graph of the declaration. For example, in the following
+	 * example:
+	 * 
+	 * <pre>
+	 * Map&lt;String, ? extends Metadata&gt;
+	 * </pre>
+	 * 
+	 * The raw class is the Map class.
+	 * 
+	 * @return The raw class represented by this type.
+	 */
+	public Class getRawClass() {
+		return clazz;
+	}
+
+	/**
+	 * Return a type parameter for this type.
+	 * 
+	 * The type parameter refers to a parameter in a generic type declaration
+	 * given by the zero-based index <code>i</code>.
+	 * 
+	 * For example, in the following example:
+	 * 
+	 * <pre>
+	 * Map&lt;String, ? extends Metadata&gt;
+	 * </pre>
+	 * 
+	 * type parameter 0 is <code>String</code>, and type parameter 1 is
+	 * <code>Metadata</code>.
+	 * 
+	 * <p>
+	 * This implementation returns a Reified Type that has <code>Object</code>
+	 * as class. Any object is assignable to Object and therefore no conversion
+	 * is then necessary. This is compatible with versions of Java language
+	 * prior to Java 5.
+	 * 
+	 * This method should be overridden by a subclass that provides access to
+	 * the generic type parameter information for Java 5 and later.
+	 * 
+	 * @param i The zero-based index of the requested type parameter.
+	 * @return The <code>ReifiedType</code> for the generic type parameter at
+	 *         the specified index.
+	 */
+	public ReifiedType getActualTypeArgument(int i) {
+		return OBJECT;
+	}
+
+	/**
+	 * Return the number of type parameters for this type.
+	 * 
+	 * <p>
+	 * This implementation returns <code>0</code>. This method should be
+	 * overridden by a subclass that provides access to the generic type
+	 * parameter information for Java 5 and later.
+	 * 
+	 * @return The number of type parameters for this type.
+	 */
+	public int size() {
+		return 0;
+	}
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ServiceUnavailableException.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ServiceUnavailableException.java
new file mode 100644
index 0000000..e0ef284
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/ServiceUnavailableException.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.container;
+
+import org.osgi.framework.ServiceException;
+
+/**
+ * A Blueprint exception indicating that a service is unavailable.
+ * 
+ * This exception is thrown when an invocation is made on a service reference
+ * and a backing service is not available.
+ * 
+ * @version $Revision: 7556 $
+ */
+public class ServiceUnavailableException extends ServiceException {
+	private static final long	serialVersionUID	= 1L;
+	/**
+	 * The filter string associated with the exception.
+	 */
+	private final String		filter;
+
+	/**
+	 * Creates a Service Unavailable Exception with the specified message.
+	 * 
+	 * @param message The associated message.
+	 * @param filter The filter used for the service lookup.
+	 */
+	public ServiceUnavailableException(String message, String filter) {
+		super(message, UNREGISTERED);
+		this.filter = filter;
+	}
+
+	/**
+	 * Creates a Service Unavailable Exception with the specified message and
+	 * exception cause.
+	 * 
+	 * @param message The associated message.
+	 * @param filter The filter used for the service lookup.
+	 * @param cause The cause of this exception.
+	 */
+	public ServiceUnavailableException(String message, String filter,
+			Throwable cause) {
+		super(message, UNREGISTERED, cause);
+		this.filter = filter;
+	}
+
+	/**
+	 * Returns the filter expression that a service would have needed to satisfy
+	 * in order for the invocation to proceed.
+	 * 
+	 * @return The failing filter.
+	 */
+	public String getFilter() {
+		return this.filter;
+	}
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/package.html
new file mode 100644
index 0000000..6b2fc92
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/package.html
@@ -0,0 +1,21 @@
+<!-- $Revision: 7556 $ -->
+<BODY>
+<p>Blueprint Container Package Version 1.0.</p>
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:</p>
+<pre>
+Import-Package: org.osgi.service.blueprint.container; version=&quot;[1.0,2.0)&quot;
+</pre>
+<p>
+	This package defines the primary interface to a Blueprint Container,
+	<code>BlueprintContainer</code>. An instance of this type is available
+        inside a Blueprint Container as an implicitly defined component with the name
+        &quot;blueprintContainer&quot;.
+</p>
+<p>
+	This package also declares the supporting exception types, listener, and constants for working with a Blueprint
+	Container.
+</p>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/container/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanArgument.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanArgument.java
new file mode 100644
index 0000000..9811a42
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanArgument.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a factory method or constructor argument of a bean. The
+ * arguments of a bean are obtained from {@link BeanMetadata#getArguments()}.
+ * 
+ * This is specified by the <code>argument</code> elements of a bean.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface BeanArgument {
+
+	/**
+	 * Return the Metadata for the argument value.
+	 * 
+	 * This is specified by the <code>value</code> attribute.
+	 * 
+	 * @return The Metadata for the argument value.
+	 */
+	Metadata getValue();
+
+	/**
+	 * Return the name of the value type to match the argument and convert the
+	 * value into when invoking the constructor or factory method.
+	 * 
+	 * This is specified by the <code>type</code> attribute.
+	 * 
+	 * @return The name of the value type to convert the value into, or
+	 *         <code>null</code> if no type is specified.
+	 */
+	String getValueType();
+
+	/**
+	 * Return the zero-based index into the parameter list of the factory method
+	 * or constructor to be invoked for this argument. This is determined by
+	 * specifying the <code>index</code> attribute for the bean. If not
+	 * explicitly set, this will return -1 and the initial ordering is defined
+	 * by its position in the {@link BeanMetadata#getArguments()} list.
+	 * 
+	 * This is specified by the <code>index</code> attribute.
+	 * 
+	 * @return The zero-based index of the parameter, or -1 if no index is
+	 *         specified.
+	 */
+	int getIndex();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanMetadata.java
new file mode 100644
index 0000000..83e30ee
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanMetadata.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+import java.util.List;
+
+/**
+ * Metadata for a Bean component.
+ * 
+ * <p>
+ * This is specified by the <code>bean</code> element.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface BeanMetadata extends Target, ComponentMetadata {
+
+	/**
+	 * The bean has <code>singleton</code> scope.
+	 * 
+	 * @see #getScope()
+	 */
+	static final String	SCOPE_SINGLETON	= "singleton";
+
+	/**
+	 * The bean has <code>prototype</code> scope.
+	 * 
+	 * @see #getScope()
+	 */
+	static final String	SCOPE_PROTOTYPE	= "prototype";
+
+	/**
+	 * Return the name of the class specified for the bean.
+	 * 
+	 * This is specified by the <code>class</code> attribute of the bean
+	 * definition.
+	 * 
+	 * @return The name of the class specified for the bean. If no class is
+	 *         specified in the bean definition, because the a factory component
+	 *         is used instead, then this method will return <code>null</code>.
+	 */
+	String getClassName();
+
+	/**
+	 * Return the name of the init method specified for the bean.
+	 * 
+	 * This is specified by the <code>init-method</code> attribute of the bean
+	 * definition.
+	 * 
+	 * @return The name of the init method specified for the bean, or
+	 *         <code>null</code> if no init method is specified.
+	 */
+	String getInitMethod();
+
+	/**
+	 * Return the name of the destroy method specified for the bean.
+	 * 
+	 * This is specified by the <code>destroy-method</code> attribute of the
+	 * bean definition.
+	 * 
+	 * @return The name of the destroy method specified for the bean, or
+	 *         <code>null</code> if no destroy method is specified.
+	 */
+	String getDestroyMethod();
+
+	/**
+	 * Return the arguments for the factory method or constructor of the bean.
+	 * 
+	 * This is specified by the child <code>argument<code> elements.
+	 * 
+	 * @return An immutable List of {@link BeanArgument} objects for the factory
+	 *         method or constructor of the bean. The List is empty if no
+	 *         arguments are specified for the bean.
+	 */
+	List/* <BeanArgument> */getArguments();
+
+	/**
+	 * Return the properties for the bean.
+	 * 
+	 * This is specified by the child <code>property</code> elements.
+	 * 
+	 * @return An immutable List of {@link BeanProperty} objects, with one entry
+	 *         for each property to be injected in the bean. The List is empty
+	 *         if no property injection is specified for the bean.
+	 * 
+	 */
+	List /* <BeanProperty> */getProperties();
+
+	/**
+	 * Return the name of the factory method for the bean.
+	 * 
+	 * This is specified by the <code>factory-method</code> attribute of the
+	 * bean.
+	 * 
+	 * @return The name of the factory method of the bean or <code>null</code>
+	 *         if no factory method is specified for the bean.
+	 */
+	String getFactoryMethod();
+
+	/**
+	 * Return the Metadata for the factory component on which to invoke the
+	 * factory method for the bean.
+	 * 
+	 * This is specified by the <code>factory-ref</code> attribute of the bean.
+	 * 
+	 * <p>
+	 * When a factory method and factory component have been specified for the
+	 * bean, this method returns the factory component on which to invoke the
+	 * factory method for the bean. When no factory component has been specified
+	 * this method will return <code>null</code>.
+	 * 
+	 * When a factory method has been specified for the bean but a factory
+	 * component has not been specified, the factory method must be invoked as a
+	 * static method on the bean's class.
+	 * 
+	 * @return The Metadata for the factory component on which to invoke the
+	 *         factory method for the bean or <code>null</code> if no factory
+	 *         component is specified.
+	 */
+	Target getFactoryComponent();
+
+	/**
+	 * Return the scope for the bean.
+	 * 
+	 * @return The scope for the bean.
+	 * @see #SCOPE_SINGLETON
+	 * @see #SCOPE_PROTOTYPE
+	 */
+	String getScope();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanProperty.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanProperty.java
new file mode 100644
index 0000000..c65077d
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/BeanProperty.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a property to be injected into a bean. The properties of a bean
+ * are obtained from {@link BeanMetadata#getProperties()}.
+ * 
+ * This is specified by the <code>property</code> elements of a bean. Properties
+ * are defined according to the Java Beans conventions.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface BeanProperty {
+
+	/**
+	 * Return the name of the property to be injected. The name follows Java
+	 * Beans conventions.
+	 * 
+	 * This is specified by the <code>name</code> attribute.
+	 * 
+	 * @return The name of the property to be injected.
+	 */
+	String getName();
+
+	/**
+	 * Return the Metadata for the value to be injected into a bean.
+	 * 
+	 * This is specified by the <code>value</code> attribute or in inlined text.
+	 * 
+	 * @return The Metadata for the value to be injected into a bean.
+	 */
+	Metadata getValue();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/CollectionMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/CollectionMetadata.java
new file mode 100644
index 0000000..ff493ca
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/CollectionMetadata.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+import java.util.List;
+
+/**
+ * Metadata for a collection based value. Values of the collection are defined
+ * by Metadata objects. This Collection Metadata can constrain the values of the
+ * collection to a specific type.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+
+public interface CollectionMetadata extends NonNullMetadata {
+
+	/**
+	 * Return the type of the collection.
+	 * 
+	 * The possible types are: array (<code>Object[]</code>), <code>Set</code>,
+	 * and <code>List</code>. This information is specified in the element name.
+	 * 
+	 * @return The type of the collection. <code>Object[]</code> is returned to
+	 *         indicate an array.
+	 */
+	Class/* <?> */getCollectionClass();
+
+	/**
+	 * Return the type specified for the values of the collection.
+	 * 
+	 * The <code>value-type</code> attribute specified this information.
+	 * 
+	 * @return The type specified for the values of the collection.
+	 */
+	String getValueType();
+
+	/**
+	 * Return Metadata for the values of the collection.
+	 * 
+	 * @return A List of Metadata for the values of the collection.
+	 */
+	List /* <Metadata> */getValues();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ComponentMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ComponentMetadata.java
new file mode 100644
index 0000000..ddfb3a6
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ComponentMetadata.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+import java.util.List;
+
+/**
+ * Metadata for managed components. This is the base type for
+ * {@link BeanMetadata}, {@link ServiceMetadata} and
+ * {@link ServiceReferenceMetadata}.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ComponentMetadata extends NonNullMetadata {
+
+	/**
+	 * The component's manager must eagerly activate the component.
+	 * 
+	 * @see #getActivation()
+	 */
+	static final int	ACTIVATION_EAGER	= 1;
+
+	/**
+	 * The component's manager must lazily activate the component.
+	 * 
+	 * @see #getActivation()
+	 */
+	static final int	ACTIVATION_LAZY		= 2;
+
+	/**
+	 * Return the id of the component.
+	 * 
+	 * @return The id of the component. The component id can be
+	 *         <code>null</code> if this is an anonymously defined and/or
+	 *         inlined component.
+	 */
+	String getId();
+
+	/**
+	 * Return the activation strategy for the component.
+	 * 
+	 * This is specified by the <code>activation</code> attribute of a component
+	 * definition. If this is not set, then the <code>default-activation</code>
+	 * in the <code>blueprint</code> element is used. If that is also not set,
+	 * then the activation strategy is {@link #ACTIVATION_EAGER}.
+	 * 
+	 * @return The activation strategy for the component.
+	 * @see #ACTIVATION_EAGER
+	 * @see #ACTIVATION_LAZY
+	 */
+	int getActivation();
+
+	/**
+	 * Return the ids of any components listed in a <code>depends-on</code>
+	 * attribute for the component.
+	 * 
+	 * @return An immutable List of component ids that are explicitly declared
+	 *         as a dependency, or an empty List if none.
+	 */
+	List/* <String> */getDependsOn();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/IdRefMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/IdRefMetadata.java
new file mode 100644
index 0000000..d362873
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/IdRefMetadata.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for the verified id of another component managed by the Blueprint
+ * Container. The id itself will be injected, not the component to which the id
+ * refers. No implicit dependency is created.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface IdRefMetadata extends NonNullMetadata {
+	/**
+	 * Return the id of the referenced component.
+	 * 
+	 * This is specified by the <code>component-id</code> attribute of a
+	 * component.
+	 * 
+	 * @return The id of the referenced component.
+	 */
+	String getComponentId();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapEntry.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapEntry.java
new file mode 100644
index 0000000..0635a74
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapEntry.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a map entry.
+ * 
+ * This type is used by {@link MapMetadata}, {@link PropsMetadata} and
+ * {@link ServiceMetadata}.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface MapEntry {
+	/**
+	 * Return the Metadata for the key of the map entry.
+	 * 
+	 * This is specified by the <code>key</code> attribute or element.
+	 * 
+	 * @return The Metadata for the key of the map entry. This must not be
+	 *         <code>null</code>.
+	 */
+	NonNullMetadata getKey();
+
+	/**
+	 * Return the Metadata for the value of the map entry.
+	 * 
+	 * This is specified by the <code>value</code> attribute or element.
+	 * 
+	 * @return The Metadata for the value of the map entry. This must not be
+	 *         <code>null</code>.
+	 */
+	Metadata getValue();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapMetadata.java
new file mode 100644
index 0000000..d6819ea
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/MapMetadata.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+import java.util.List;
+
+/**
+ * Metadata for a Map based value.
+ * 
+ * <p>
+ * This is specified by the <code>map</code> element.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface MapMetadata extends NonNullMetadata {
+	/**
+	 * Return the name of the type of the map keys.
+	 * 
+	 * This is specified by the <code>key-type</code> attribute of the map.
+	 * 
+	 * @return The name of the type of the map keys, or <code>null</code> if
+	 *         none is specified.
+	 */
+	String getKeyType();
+
+	/**
+	 * Return the name of the type of the map values.
+	 * 
+	 * This is specified by the <code>value-type</code> attribute of the map.
+	 * 
+	 * @return The name of the type of the map values, or <code>null</code> if
+	 *         none is specified.
+	 */
+	String getValueType();
+
+	/**
+	 * Return the entries for the map.
+	 * 
+	 * @return An immutable List of {@link MapEntry} objects for each entry in
+	 *         the map. The List is empty if no entries are specified for the
+	 *         map.
+	 */
+	List /* <MapEntry> */getEntries();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Metadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Metadata.java
new file mode 100644
index 0000000..b078993
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Metadata.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) OSGi Alliance (2009). 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.service.blueprint.reflect;
+
+/**
+ * Top level Metadata type. All Metdata types extends this base type.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface Metadata {
+	// marker interface
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NonNullMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NonNullMetadata.java
new file mode 100644
index 0000000..ea926e9
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NonNullMetadata.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a value that cannot <code>null</code>. All Metadata subtypes
+ * extend this type except for {@link NullMetadata}.
+ * 
+ * <p>
+ * This Metadata type is used for keys in Maps because they cannot be
+ * <code>null</code>.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface NonNullMetadata extends Metadata {
+	// marker interface
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NullMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NullMetadata.java
new file mode 100644
index 0000000..2a26dcc
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/NullMetadata.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a value specified to be <code>null</code> via the &lt;null&gt;
+ * element.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface NullMetadata extends Metadata {
+
+	/**
+	 * Singleton instance of <code>NullMetadata</code>.
+	 */
+	static final NullMetadata	NULL	= new NullMetadata() {
+											// empty body
+										};
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/PropsMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/PropsMetadata.java
new file mode 100644
index 0000000..7edb347
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/PropsMetadata.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+import java.util.List;
+
+/**
+ * Metadata for a <code>java.util.Properties</code> based value.
+ * 
+ * <p>
+ * The {@link MapEntry} objects of properties are defined with keys and values
+ * of type <code>String</code>.
+ * 
+ * <p>
+ * This is specified by the <code>props</code> element.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7564 $
+ */
+public interface PropsMetadata extends NonNullMetadata {
+
+	/**
+	 * Return the entries for the properties.
+	 * 
+	 * @return An immutable List of {@link MapEntry} objects for each entry in
+	 *         the properties. The List is empty if no entries are specified for
+	 *         the properties.
+	 */
+	List/* <MapEntry> */getEntries();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RefMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RefMetadata.java
new file mode 100644
index 0000000..8746b0f
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RefMetadata.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a reference to another component managed by the Blueprint
+ * Container.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface RefMetadata extends Target, NonNullMetadata {
+	/**
+	 * Return the id of the referenced component.
+	 * 
+	 * This is specified by the <code>component-id</code> attribute of a
+	 * component.
+	 * 
+	 * @return The id of the referenced component.
+	 */
+	String getComponentId();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListMetadata.java
new file mode 100644
index 0000000..a03618e
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListMetadata.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a list of service references.
+ * 
+ * <p>
+ * This is specified by the <code>reference-list</code> element.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ReferenceListMetadata extends ServiceReferenceMetadata {
+
+	/**
+	 * Reference list values must be proxies to the actual service objects.
+	 * 
+	 * @see #getMemberType()
+	 */
+	 static final int	USE_SERVICE_OBJECT		= 1;
+
+	/**
+	 * Reference list values must be <code>ServiceReference</code> objects.
+	 * 
+	 * @see #getMemberType()
+	 */
+	 static final int	USE_SERVICE_REFERENCE	= 2;
+
+	/**
+	 * Return whether the List will contain service object proxies or
+	 * <code>ServiceReference</code> objects.
+	 * 
+	 * This is specified by the <code>member-type</code> attribute of the
+	 * reference list.
+	 * 
+	 * @return Whether the List will contain service object proxies or
+	 *         <code>ServiceReference</code> objects.
+	 * @see #USE_SERVICE_OBJECT
+	 * @see #USE_SERVICE_REFERENCE
+	 */
+	int getMemberType();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListener.java
new file mode 100644
index 0000000..fa24577
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceListener.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a reference listener interested in the reference bind and unbind
+ * events for a service reference.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ReferenceListener {
+
+	/**
+	 * Return the Metadata for the component that will receive bind and unbind
+	 * events.
+	 * 
+	 * This is specified by the <code>ref</code> attribute or via an inlined
+	 * component.
+	 * 
+	 * @return The Metadata for the component that will receive bind and unbind
+	 *         events.
+	 */
+	Target getListenerComponent();
+
+	/**
+	 * Return the name of the bind method. The bind method will be invoked when
+	 * a matching service is bound to the reference.
+	 * 
+	 * This is specified by the <code>bind-method</code> attribute of the
+	 * reference listener.
+	 * 
+	 * @return The name of the bind method.
+	 */
+	String getBindMethod();
+
+	/**
+	 * Return the name of the unbind method. The unbind method will be invoked
+	 * when a matching service is unbound from the reference.
+	 * 
+	 * This is specified by the <code>unbind-method</code> attribute of the
+	 * reference listener.
+	 * 
+	 * @return The name of the unbind method.
+	 */
+	String getUnbindMethod();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceMetadata.java
new file mode 100644
index 0000000..55f2db7
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ReferenceMetadata.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a reference that will bind to a single matching service in the
+ * service registry.
+ * 
+ * <p>
+ * This is specified by the <code>reference</code> element.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ReferenceMetadata extends Target, ServiceReferenceMetadata {
+
+	/**
+	 * Return the timeout for service invocations when a backing service is is
+	 * unavailable.
+	 * 
+	 * This is specified by the <code>timeout</code> attribute of the reference.
+	 * 
+	 * @return The timeout, in milliseconds, for service invocations when a
+	 *         backing service is is unavailable.
+	 */
+	long getTimeout();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RegistrationListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RegistrationListener.java
new file mode 100644
index 0000000..77dc5fc
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/RegistrationListener.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a registration listener interested in service registration and
+ * unregistration events for a service.
+ * 
+ * <p>
+ * The registration listener is called with the initial state of the service
+ * when the registration listener is actuated.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface RegistrationListener {
+
+	/**
+	 * Return the Metadata for the component that will receive registration and
+	 * unregistration events.
+	 * 
+	 * This is specified by the <code>ref</code> attribute or via an inlined
+	 * component.
+	 * 
+	 * @return The Metadata for the component that will receive registration and
+	 *         unregistration events.
+	 */
+	Target getListenerComponent();
+
+	/**
+	 * Return the name of the registration method. The registration method will
+	 * be invoked when the associated service is registered with the service
+	 * registry.
+	 * 
+	 * This is specified by the <code>registration-method</code> attribute of
+	 * the registration listener.
+	 * 
+	 * @return The name of the registration method.
+	 */
+	String getRegistrationMethod();
+
+	/**
+	 * Return the name of the unregistration method. The unregistration method
+	 * will be invoked when the associated service is unregistered from the
+	 * service registry.
+	 * 
+	 * This is specified by the <code>unregistration-method</code> attribute of
+	 * the registration listener.
+	 * 
+	 * @return The name of the unregistration method.
+	 */
+	String getUnregistrationMethod();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceMetadata.java
new file mode 100644
index 0000000..86728b1
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceMetadata.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Metadata for a service to be registered by the Blueprint Container when
+ * enabled.
+ * 
+ * <p>
+ * This is specified by the <code>service</code> element.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ServiceMetadata extends ComponentMetadata {
+
+	/**
+	 * Do not auto-detect types for advertised service interfaces
+	 * 
+	 * @see #getAutoExport()
+	 */
+	static final int		AUTO_EXPORT_DISABLED		= 1;
+
+	/**
+	 * Advertise all Java interfaces implemented by the component instance type
+	 * as service interfaces.
+	 * 
+	 * @see #getAutoExport()
+	 */
+	static final int		AUTO_EXPORT_INTERFACES		= 2;
+
+	/**
+	 * Advertise all Java classes in the hierarchy of the component instance
+	 * type as service interfaces.
+	 * 
+	 * @see #getAutoExport()
+	 */
+	static final int		AUTO_EXPORT_CLASS_HIERARCHY	= 3;
+
+	/**
+	 * Advertise all Java classes and interfaces in the component instance type
+	 * as service interfaces.
+	 * 
+	 * @see #getAutoExport()
+	 */
+	static final int	AUTO_EXPORT_ALL_CLASSES		= 4;
+
+	/**
+	 * Return the Metadata for the component to be exported as a service.
+	 * 
+	 * This is specified inline or via the <code>ref</code> attribute of the
+	 * service.
+	 * 
+	 * @return The Metadata for the component to be exported as a service.
+	 */
+	Target getServiceComponent();
+
+	/**
+	 * Return the type names of the interfaces that the service should be
+	 * advertised as supporting.
+	 * 
+	 * This is specified in the <code>interface</code> attribute or child
+	 * <code>interfaces</code> element of the service.
+	 * 
+	 * @return An immutable List of <code>String</code> for the type names of
+	 *         the interfaces that the service should be advertised as
+	 *         supporting. The List is empty if using <code>auto-export</code>
+	 *         or no interface names are specified for the service.
+	 */
+	List/* <String> */getInterfaces();
+
+	/**
+	 * Return the auto-export mode for the service.
+	 * 
+	 * This is specified by the <code>auto-export</code> attribute of the
+	 * service.
+	 * 
+	 * @return The auto-export mode for the service.
+	 * @see #AUTO_EXPORT_DISABLED
+	 * @see #AUTO_EXPORT_INTERFACES
+	 * @see #AUTO_EXPORT_CLASS_HIERARCHY
+	 * @see #AUTO_EXPORT_ALL_CLASSES
+	 */
+	int getAutoExport();
+
+	/**
+	 * Return the user declared properties to be advertised with the service.
+	 * 
+	 * This is specified by the <code>service-properties</code> element of the
+	 * service.
+	 * 
+	 * @return An immutable List of {@link MapEntry} objects for the user
+	 *         declared properties to be advertised with the service. The List
+	 *         is empty if no service properties are specified for the service.
+	 */
+	List/* <MapEntry> */getServiceProperties();
+
+	/**
+	 * Return the ranking value to use when advertising the service. If the
+	 * ranking value is zero, the service must be registered without a
+	 * <code>service.ranking</code> service property.
+	 * 
+	 * This is specified by the <code>ranking</code> attribute of the service.
+	 * 
+	 * @return The ranking value to use when advertising the service.
+	 */
+	int getRanking();
+
+	/**
+	 * Return the registration listeners to be notified when the service is
+	 * registered and unregistered with the framework.
+	 * 
+	 * This is specified by the <code>registration-listener</code> elements of
+	 * the service.
+	 * 
+	 * @return An immutable Collection of {@link RegistrationListener} objects
+	 *         to be notified when the service is registered and unregistered
+	 *         with the framework. The Collection is empty if no registration
+	 *         listeners are specified for the service.
+	 */
+	Collection /* <RegistrationListener> */getRegistrationListeners();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceReferenceMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceReferenceMetadata.java
new file mode 100644
index 0000000..e57577e
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ServiceReferenceMetadata.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+import java.util.Collection;
+
+/**
+ * Metadata for a reference to an OSGi service. This is the base type for
+ * {@link ReferenceListMetadata} and {@link ReferenceMetadata}.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ServiceReferenceMetadata extends ComponentMetadata {
+
+	/**
+	 * A matching service is required at all times.
+	 * 
+	 * @see #getAvailability()
+	 */
+	static final int	AVAILABILITY_MANDATORY	= 1;
+
+	/**
+	 * A matching service is not required to be present.
+	 * 
+	 * @see #getAvailability()
+	 */
+	static final int	AVAILABILITY_OPTIONAL	= 2;
+
+	/**
+	 * Return whether or not a matching service is required at all times.
+	 * 
+	 * This is specified in the <code>availability</code> attribute of the
+	 * service reference.
+	 * 
+	 * @return Whether or not a matching service is required at all times.
+	 * @see #AVAILABILITY_MANDATORY
+	 * @see #AVAILABILITY_OPTIONAL
+	 */
+	int getAvailability();
+
+	/**
+	 * Return the name of the interface type that a matching service must
+	 * support.
+	 * 
+	 * This is specified in the <code>interface</code> attribute of the service
+	 * reference.
+	 * 
+	 * @return The name of the interface type that a matching service must
+	 *         support or <code>null</code> when no interface name is specified.
+	 */
+	String getInterface();
+
+	/**
+	 * Return the value of the <code>component-name</code> attribute of the
+	 * service reference. This specifies the id of a component that is
+	 * registered in the service registry. This will create an automatic filter,
+	 * appended with the filter if set, to select this component based on its
+	 * automatic <code>id</code> attribute.
+	 * 
+	 * @return The value of the <code>component-name</code> attribute of the
+	 *         service reference or <code>null</code> if the attribute is not
+	 *         specified.
+	 */
+	String getComponentName();
+
+	/**
+	 * Return the filter expression that a matching service must match.
+	 * 
+	 * This is specified by the <code>filter</code> attribute of the service
+	 * reference.
+	 * 
+	 * @return The filter expression that a matching service must match or
+	 *         <code>null</code> if a filter is not specified.
+	 */
+	String getFilter();
+
+	/**
+	 * Return the reference listeners to receive bind and unbind events.
+	 * 
+	 * This is specified by the <code>reference-listener</code> elements of the
+	 * service reference.
+	 * 
+	 * @return An immutable Collection of {@link ReferenceListener} objects to
+	 *         receive bind and unbind events. The Collection is empty if no
+	 *         reference listeners are specified for the service reference.
+	 */
+	Collection /* <ReferenceListener> */getReferenceListeners();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Target.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Target.java
new file mode 100644
index 0000000..a96a4b0
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/Target.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * A common interface for managed components that can be used as a direct target
+ * for method calls. These are <code>bean</code>, <code>reference</code>, and
+ * <code>ref</code>, where the <code>ref</code> must refer to a bean or
+ * reference component.
+ * 
+ * @see BeanMetadata
+ * @see ReferenceMetadata
+ * @see RefMetadata
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface Target extends NonNullMetadata {
+	// marker interface
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ValueMetadata.java b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ValueMetadata.java
new file mode 100644
index 0000000..7609234
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/ValueMetadata.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) OSGi Alliance (2008, 2009). 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.service.blueprint.reflect;
+
+/**
+ * Metadata for a simple <code>String</code> value that will be type-converted
+ * if necessary before injecting.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 7563 $
+ */
+public interface ValueMetadata extends NonNullMetadata {
+	/**
+	 * Return the unconverted string representation of the value.
+	 * 
+	 * This is specified by the <code>value</code> attribute or text part of the
+	 * <code>value</code> element.
+	 * 
+	 * @return The unconverted string representation of the value.
+	 */
+	String getStringValue();
+
+	/**
+	 * Return the name of the type to which the value should be converted.
+	 * 
+	 * This is specified by the <code>type</code> attribute.
+	 * 
+	 * @return The name of the type to which the value should be converted or
+	 *         <code>null</code> if no type is specified.
+	 */
+	String getType();
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/package.html
new file mode 100644
index 0000000..534999d
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/package.html
@@ -0,0 +1,14 @@
+<!-- $Revision: 7556 $ -->
+<BODY>
+<p>Blueprint Reflection Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.blueprint.reflect; version=&quot;[1.0,2.0)&quot;
+</pre>
+<p> This package provides a reflection-based view of the configuration information for a
+	Blueprint Container.
+</p>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/blueprint/reflect/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/Configuration.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/Configuration.java
index af6d739..7c17cf1 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/Configuration.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/Configuration.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/Configuration.java,v 1.17 2006/06/16 16:31:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -60,7 +58,7 @@
  * Managed Service Factory and a Managed Service. When it is important to
  * differentiate between these two the term "factory configuration" is used.
  * 
- * @version $Revision: 1.17 $
+ * @version $Revision: 5673 $
  */
 public interface Configuration {
 	/**
@@ -109,7 +107,7 @@
 	 * callback is delayed until aforementioned registration occurs.
 	 * 
 	 * <p>
-	 * Also intiates an asynchronous call to all
+	 * Also initiates an asynchronous call to all
 	 * <code>ConfigurationListener</code>s with a
 	 * <code>ConfigurationEvent.CM_UPDATED</code> event.
 	 * 
@@ -133,7 +131,7 @@
 	 * call to its <code>deleted</code> method.
 	 * 
 	 * <p>
-	 * Also intiates an asynchronous call to all
+	 * Also initiates an asynchronous call to all
 	 * <code>ConfigurationListener</code>s with a
 	 * <code>ConfigurationEvent.CM_DELETED</code> event.
 	 * 
@@ -160,7 +158,7 @@
 	 * 
 	 * <p>
 	 * This is the only way for a bundle that uses a Configuration Plugin
-	 * service to initate a callback. For example, when that bundle detects a
+	 * service to initiate a callback. For example, when that bundle detects a
 	 * change that requires an update of the Managed Service or Managed Service
 	 * Factory via its <code>ConfigurationPlugin</code> object.
 	 * 
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
index 131f863..066548f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationAdmin.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationAdmin.java,v 1.17 2006/09/26 13:33:09 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -50,27 +48,28 @@
  * <p>
  * Bundles that require configuration should register a Managed Service or a
  * Managed Service Factory in the service registry. A registration property
- * named <code>service.pid</code> (persistent identifier or PID) must be used
- * to identify this Managed Service or Managed Service Factory to the
- * Configuration Admin service.
+ * named <code>service.pid</code> (persistent identifier or PID) must be used to
+ * identify this Managed Service or Managed Service Factory to the Configuration
+ * Admin service.
  * 
  * <p>
  * When the ConfigurationAdmin detects the registration of a Managed Service, it
- * checks its persistent storage for a configuration object whose PID matches
- * the PID registration property (<code>service.pid</code>) of the Managed
- * Service. If found, it calls {@link ManagedService#updated} method with the
- * new properties. The implementation of a Configuration Admin service must run
- * these call-backs asynchronously to allow proper synchronization.
+ * checks its persistent storage for a configuration object whose
+ * <code>service.pid</code> property matches the PID service property (
+ * <code>service.pid</code>) of the Managed Service. If found, it calls
+ * {@link ManagedService#updated} method with the new properties. The
+ * implementation of a Configuration Admin service must run these call-backs
+ * asynchronously to allow proper synchronization.
  * 
  * <p>
  * When the Configuration Admin service detects a Managed Service Factory
  * registration, it checks its storage for configuration objects whose
- * <code>factoryPid</code> matches the PID of the Managed Service Factory. For
- * each such <code>Configuration</code> objects, it calls the
- * <code>ManagedServiceFactory.updated</code> method asynchronously with the
- * new properties. The calls to the <code>updated</code> method of a
- * <code>ManagedServiceFactory</code> must be executed sequentially and not
- * overlap in time.
+ * <code>service.factoryPid</code> property matches the PID service property of
+ * the Managed Service Factory. For each such <code>Configuration</code>
+ * objects, it calls the <code>ManagedServiceFactory.updated</code> method
+ * asynchronously with the new properties. The calls to the <code>updated</code>
+ * method of a <code>ManagedServiceFactory</code> must be executed sequentially
+ * and not overlap in time.
  * 
  * <p>
  * In general, bundles having permission to use the Configuration Admin service
@@ -79,16 +78,16 @@
  * <code>ConfigurationPermission[*,CONFIGURE]</code>.
  * 
  * <p>
- * <code>Configuration</code> objects can be <i>bound </i> to a specified
- * bundle location. In this case, if a matching Managed Service or Managed
- * Service Factory is registered by a bundle with a different location, then the
+ * <code>Configuration</code> objects can be <i>bound </i> to a specified bundle
+ * location. In this case, if a matching Managed Service or Managed Service
+ * Factory is registered by a bundle with a different location, then the
  * Configuration Admin service must not do the normal callback, and it should
  * log an error. In the case where a <code>Configuration</code> object is not
  * bound, its location field is <code>null</code>, the Configuration Admin
  * service will bind it to the location of the bundle that registers the first
  * Managed Service or Managed Service Factory that has a corresponding PID
  * property. When a <code>Configuration</code> object is bound to a bundle
- * location in this manner, the Confguration Admin service must detect if the
+ * location in this manner, the Configuration Admin service must detect if the
  * bundle corresponding to the location is uninstalled. If this occurs, the
  * <code>Configuration</code> object is unbound, that is its location field is
  * set back to <code>null</code>.
@@ -100,20 +99,20 @@
  * <code>ConfigurationAdmin</code> must use a
  * {@link org.osgi.framework.ServiceFactory} to support this concept.
  * 
- * @version $Revision: 1.17 $
+ * @version $Revision: 7356 $
  */
 public interface ConfigurationAdmin {
 	/**
-	 * Service property naming the Factory PID in the configuration dictionary.
-	 * The property's value is of type <code>String</code>.
+	 * Configuration property naming the Factory PID in the configuration
+	 * dictionary. The property's value is of type <code>String</code>.
 	 * 
 	 * @since 1.1
 	 */
 	public final static String	SERVICE_FACTORYPID		= "service.factoryPid";
 	/**
-	 * Service property naming the location of the bundle that is associated
-	 * with a a <code>Configuration</code> object. This property can be
-	 * searched for but must not appear in the configuration dictionary for
+	 * Configuration property naming the location of the bundle that is
+	 * associated with a a <code>Configuration</code> object. This property can
+	 * be searched for but must not appear in the configuration dictionary for
 	 * security reason. The property's value is of type <code>String</code>.
 	 * 
 	 * @since 1.1
@@ -226,26 +225,26 @@
 	 * 
 	 * <p>
 	 * Normally only <code>Configuration</code> objects that are bound to the
-	 * location of the calling bundle are returned, or all if the caller has 
+	 * location of the calling bundle are returned, or all if the caller has
 	 * <code>ConfigurationPermission[*,CONFIGURE]</code>.
 	 * 
 	 * <p>
-	 * The syntax of the filter string is as defined in the {@link org.osgi.framework.Filter}
-	 * class. The filter can test any configuration parameters including the
-	 * following system properties:
+	 * The syntax of the filter string is as defined in the
+	 * {@link org.osgi.framework.Filter} class. The filter can test any
+	 * configuration properties including the following:
 	 * <ul>
-	 * <li><code>service.pid</code>-<code>String</code>- the PID under
-	 * which this is registered</li>
-	 * <li><code>service.factoryPid</code>-<code>String</code>- the
-	 * factory if applicable</li>
-	 * <li><code>service.bundleLocation</code>-<code>String</code>- the
-	 * bundle location</li>
+	 * <li><code>service.pid</code>-<code>String</code>- the PID under which
+	 * this is registered</li>
+	 * <li><code>service.factoryPid</code>-<code>String</code>- the factory if
+	 * applicable</li>
+	 * <li><code>service.bundleLocation</code>-<code>String</code>- the bundle
+	 * location</li>
 	 * </ul>
 	 * The filter can also be <code>null</code>, meaning that all
 	 * <code>Configuration</code> objects should be returned.
 	 * 
-	 * @param filter A filter string, or <code>null</code> to
-	 *        retrieve all <code>Configuration</code> objects.
+	 * @param filter A filter string, or <code>null</code> to retrieve all
+	 *        <code>Configuration</code> objects.
 	 * @return All matching <code>Configuration</code> objects, or
 	 *         <code>null</code> if there aren't any.
 	 * @throws IOException if access to persistent storage fails
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationEvent.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
index 3e1b776..f17007f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationEvent.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationEvent.java,v 1.9 2006/06/16 16:31:28 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). 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 +15,8 @@
  */
 package org.osgi.service.cm;
 
+import java.util.Dictionary;
+
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -46,7 +46,7 @@
  * 
  * @see ConfigurationListener
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 6180 $
  * @since 1.2
  */
 public class ConfigurationEvent {
@@ -57,7 +57,7 @@
 	 * This <code>ConfigurationEvent</code> type that indicates that a
 	 * <code>Configuration</code> object has been updated with new properties.
 	 * 
-	 * An event is fired when a call to <code>Configuration.update</code>
+	 * An event is fired when a call to {@link Configuration#update(Dictionary)}
 	 * successfully changes a configuration.
 	 * 
 	 * <p>
@@ -71,7 +71,7 @@
 	 * This <code>ConfigurationEvent</code> type that indicates that a
 	 * <code>Configuration</code> object has been deleted.
 	 * 
-	 * An event is fired when a call to <code>Configuration.delete</code>
+	 * An event is fired when a call to {@link Configuration#delete()}
 	 * successfully deletes a configuration.
 	 * 
 	 * <p>
@@ -116,6 +116,9 @@
 		this.type = type;
 		this.factoryPid = factoryPid;
 		this.pid = pid;
+		if ((reference == null) || (pid == null)) {
+			throw new NullPointerException("reference and pid must not be null");
+		}
 	}
 
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationException.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationException.java
index dbbf216..300f5c8 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationException.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationException.java,v 1.13 2006/07/11 13:15:52 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +19,7 @@
  * An <code>Exception</code> class to inform the Configuration Admin service
  * of problems with configuration data.
  * 
- * @version $Revision: 1.13 $
+ * @version $Revision: 6083 $
  */
 public class ConfigurationException extends Exception {
 	static final long	serialVersionUID	= -1690090413441769377L;
@@ -30,11 +28,6 @@
 	private final String		reason;
 
 	/**
-	 * Nested exception.
-	 */
-	private final Throwable	cause;
-
-	/**
 	 * Create a <code>ConfigurationException</code> object.
 	 * 
 	 * @param property name of the property that caused the problem,
@@ -45,7 +38,6 @@
 		super(property + " : " + reason);
 		this.property = property;
 		this.reason = reason;
-		this.cause = null;
 	}
 
 	/**
@@ -59,10 +51,9 @@
 	 */
 	public ConfigurationException(String property, String reason,
 			Throwable cause) {
-		super(property + " : " + reason);
+		super(property + " : " + reason, cause);
 		this.property = property;
 		this.reason = reason;
-		this.cause = cause;
 	}
 
 	/**
@@ -83,30 +74,31 @@
 	public String getReason() {
 		return reason;
 	}
-
+	
 	/**
-	 * Returns the cause of this exception or <code>null</code> if no cause
-	 * was specified when this exception was created.
+	 * Returns the cause of this exception or <code>null</code> if no cause was
+	 * set.
 	 * 
-	 * @return The cause of this exception or <code>null</code> if no cause
-	 *         was specified.
+	 * @return The cause of this exception or <code>null</code> if no cause was
+	 *         set.
 	 * @since 1.2
 	 */
 	public Throwable getCause() {
-		return cause;
+		return super.getCause();
 	}
 
 	/**
-	 * The cause of this exception can only be set when constructed.
+	 * Initializes the cause of this exception to the specified value.
 	 * 
-	 * @param cause Cause of the exception.
-	 * @return This object.
-	 * @throws java.lang.IllegalStateException This method will always throw an
-	 *         <code>IllegalStateException</code> since the cause of this
-	 *         exception can only be set when constructed.
+	 * @param cause The cause of this exception.
+	 * @return This exception.
+	 * @throws IllegalArgumentException If the specified cause is this
+	 *         exception.
+	 * @throws IllegalStateException If the cause of this exception has already
+	 *         been set.
 	 * @since 1.2
 	 */
 	public Throwable initCause(Throwable cause) {
-		throw new IllegalStateException();
+		return super.initCause(cause);
 	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationListener.java
index a171f90..5d7793d 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationListener.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationListener.java,v 1.10 2006/06/16 16:31:28 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). 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.
@@ -37,7 +35,7 @@
  * require <code>ServicePermission[ConfigurationListener,REGISTER]</code> to
  * register a <code>ConfigurationListener</code> service.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  * @since 1.2
  */
 public interface ConfigurationListener {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
index f4901b8..3af9088 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPermission.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationPermission.java,v 1.22 2006/07/08 00:42:00 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +16,9 @@
 
 package org.osgi.service.cm;
 
-import java.security.*;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
 import java.util.Enumeration;
 import java.util.NoSuchElementException;
 
@@ -27,7 +27,8 @@
  * 
  * This permission has only a single action: CONFIGURE.
  * 
- * @version $Revision: 1.22 $
+ * @ThreadSafe
+ * @version $Revision: 6381 $
  * @since 1.2
  */
 
@@ -92,7 +93,9 @@
 	 */
 
 	public int hashCode() {
-		return getName().hashCode() ^ getActions().hashCode();
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		return h;
 	}
 
 	/**
@@ -135,7 +138,7 @@
 	 * 
 	 * @serial
 	 */
-	private boolean		hasElement;
+	private volatile boolean	hasElement;
 
 	/**
 	 * Creates an empty <tt>ConfigurationPermissionCollection</tt> object.
@@ -214,5 +217,4 @@
 			}
 		};
 	}
-
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
index d3206f8..574466e 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ConfigurationPlugin.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ConfigurationPlugin.java,v 1.11 2006/06/16 16:31:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -34,7 +32,7 @@
  * <code>ManagedServiceFactory</code>
  * <code>updated</code> method. The
  * Configuration Plugin service thus has the opportunity to view and modify the
- * properties before they are passed to the ManagedS ervice or Managed Service
+ * properties before they are passed to the Managed Service or Managed Service
  * Factory.
  * 
  * <p>
@@ -71,12 +69,12 @@
  * A plugin may optionally specify a <code>cm.target</code> registration
  * property whose value is the PID of the Managed Service or Managed Service
  * Factory whose configuration updates the plugin is intended to intercept. The
- * plugin will then only be called with configuration updates that are targetted
+ * plugin will then only be called with configuration updates that are targeted
  * at the Managed Service or Managed Service Factory with the specified PID.
  * Omitting the <code>cm.target</code> registration property means that the
  * plugin is called for all configuration updates.
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
  */
 public interface ConfigurationPlugin {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedService.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedService.java
index d4e30a2..6812434 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedService.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ManagedService.java,v 1.12 2006/06/16 16:31:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,7 +24,7 @@
  * <p>
  * A Managed Service is a service that needs configuration data. Such an object
  * should be registered with the Framework registry with the
- * <code>service.pid</code> property set to some unique identitifier called a
+ * <code>service.pid</code> property set to some unique identifier called a
  * PID.
  * 
  * <p>
@@ -107,7 +105,7 @@
  * registration properties. This will allow the Configuration Admin service to
  * set properties on services which can then be used by other applications.
  * 
- * @version $Revision: 1.12 $
+ * @version $Revision: 5673 $
  */
 public interface ManagedService {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java
index 838df68..8c334c0 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/ManagedServiceFactory.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.cm/src/org/osgi/service/cm/ManagedServiceFactory.java,v 1.12 2006/07/11 00:54:03 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -94,7 +92,7 @@
  *   
  * </pre>
  * 
- * @version $Revision: 1.12 $
+ * @version $Revision: 5673 $
  */
 public interface ManagedServiceFactory {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/cm/package.html
new file mode 100644
index 0000000..0234320
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 7356 $ -->
+<BODY>
+<p>Configuration Admin Package Version 1.3.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.cm; version=&quot;[1.3,2.0)&quot;
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/cm/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/cm/packageinfo
new file mode 100644
index 0000000..0117a56
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/cm/packageinfo
@@ -0,0 +1 @@
+version 1.3
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentConstants.java b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentConstants.java
index 34b0388..2f9d089 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentConstants.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentConstants.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.component/src/org/osgi/service/component/ComponentConstants.java,v 1.14 2006/06/16 16:31:26 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,13 +19,12 @@
 /**
  * Defines standard names for Service Component constants.
  * 
- * @version $Revision: 1.14 $
+ * @version $Revision: 6454 $
  */
 public interface ComponentConstants {
 	/**
-	 * Manifest header (named &quot;Service-Component&quot;) specifying the XML
-	 * documents within a bundle that contain the bundle's Service Component
-	 * descriptions.
+	 * Manifest header specifying the XML documents within a bundle that contain
+	 * the bundle's Service Component descriptions.
 	 * <p>
 	 * The attribute value may be retrieved from the <code>Dictionary</code>
 	 * object returned by the <code>Bundle.getHeaders</code> method.
@@ -37,14 +34,15 @@
 	/**
 	 * A component property for a component configuration that contains the name
 	 * of the component as specified in the <code>name</code> attribute of the
-	 * <code>component</code> element. The type of this property must be
-	 * <code>String</code>.
+	 * <code>component</code> element. The value of this property must be of
+	 * type <code>String</code>.
 	 */
 	public final static String	COMPONENT_NAME			= "component.name";
 
 	/**
 	 * A component property that contains the generated id for a component
-	 * configuration. The type of this property must be <code>Long</code>.
+	 * configuration. The value of this property must be of type
+	 * <code>Long</code>.
 	 * 
 	 * <p>
 	 * The value of this property is assigned by the Service Component Runtime
@@ -57,15 +55,64 @@
 
 	/**
 	 * A service registration property for a Component Factory that contains the
-	 * value of the <code>factory</code> attribute. The type of this property
-	 * must be <code>String</code>.
+	 * value of the <code>factory</code> attribute. The value of this property
+	 * must be of type <code>String</code>.
 	 */
 	public final static String	COMPONENT_FACTORY		= "component.factory";
 
 	/**
 	 * The suffix for reference target properties. These properties contain the
-	 * filter to select the target services for a reference. The type of this
-	 * property must be <code>String</code>.
+	 * filter to select the target services for a reference. The value of this
+	 * property must be of type <code>String</code>.
 	 */
 	public final static String	REFERENCE_TARGET_SUFFIX	= ".target";
+	
+	/**
+	 * The reason the component configuration was deactivated is unspecified.
+	 *  
+	 * @since 1.1
+	 */
+	public static final int DEACTIVATION_REASON_UNSPECIFIED = 0;
+	
+	/**
+	 * The component configuration was deactivated because the component was disabled.
+	 *  
+	 * @since 1.1
+	 */
+	public static final int DEACTIVATION_REASON_DISABLED = 1;
+	
+	/**
+	 * The component configuration was deactivated because a reference became unsatisfied.
+	 *  
+	 * @since 1.1
+	 */
+	public static final int DEACTIVATION_REASON_REFERENCE = 2;
+	
+	/**
+	 * The component configuration was deactivated because its configuration was changed.
+	 *  
+	 * @since 1.1
+	 */
+	public static final int DEACTIVATION_REASON_CONFIGURATION_MODIFIED = 3;
+	
+	/**
+	 * The component configuration was deactivated because its configuration was deleted.
+	 *  
+	 * @since 1.1
+	 */
+	public static final int DEACTIVATION_REASON_CONFIGURATION_DELETED = 4;
+	
+	/**
+	 * The component configuration was deactivated because the component was disposed.
+	 *  
+	 * @since 1.1
+	 */
+	public static final int DEACTIVATION_REASON_DISPOSED = 5;
+
+	/**
+	 * The component configuration was deactivated because the bundle was stopped.
+	 *  
+	 * @since 1.1
+	 */
+	public static final int DEACTIVATION_REASON_BUNDLE_STOPPED = 6;
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentContext.java b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentContext.java
index c763293..aad348c 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentContext.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentContext.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.component/src/org/osgi/service/component/ComponentContext.java,v 1.20 2006/06/16 16:31:26 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). 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,7 +18,9 @@
 
 import java.util.Dictionary;
 
-import org.osgi.framework.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
 
 /**
  * A Component Context object is used by a component instance to interact with
@@ -28,38 +28,31 @@
  * component instance has a unique Component Context.
  * 
  * <p>
- * A component's implementation class may optionaly implement an activate
- * method:
- * 
- * <pre>
- * protected void activate(ComponentContext context);
- * </pre>
- * 
- * If a component implements this method, this method will be called when a
- * component configuration is activated to provide the component instance's
- * Component Context object.
+ * A component instance may have an activate method. If a component instance has
+ * a suitable and accessible activate method, this method will be called when a
+ * component configuration is activated. If the activate method takes a
+ * <code>ComponentContext</code> argument, it will be passed the component
+ * instance's Component Context object. If the activate method takes a
+ * <code>BundleContext</code> argument, it will be passed the component
+ * instance's Bundle Context object. If the activate method takes a
+ * <code>Map</code> argument, it will be passed an unmodifiable Map containing
+ * the component properties.
  * 
  * <p>
- * A component's implementation class may optionaly implement a deactivate
- * method:
+ * A component instance may have a deactivate method. If a component instance
+ * has a suitable and accessible deactivate method, this method will be called
+ * when the component configuration is deactivated. If the deactivate method
+ * takes a <code>ComponentContext</code> argument, it will be passed the
+ * component instance's Component Context object. If the deactivate method takes
+ * a <code>BundleContext</code> argument, it will be passed the component
+ * instance's Bundle Context object. If the deactivate method takes a
+ * <code>Map</code> argument, it will be passed an unmodifiable Map containing
+ * the component properties. If the deactivate method takes an <code>int</code>
+ * or <code>Integer</code> argument, it will be passed the reason code for the
+ * component instance's deactivation.
  * 
- * <pre>
- * protected void deactivate(ComponentContext context);
- * </pre>
- * 
- * If a component implements this method, this method will be called when the
- * component configuration is deactivated.
- * 
- * <p>
- * The activate and deactivate methods will be called using reflection and must
- * be protected or public accessible. These methods should not be public methods
- * so that they do not appear as public methods on the component instance when
- * used as a service object. These methods will be located by looking through
- * the component's implementation class hierarchy for the first declaration of
- * the method. If the method is found, if it is declared protected or public,
- * the method will be called. Otherwise, the method will not be called.
- * 
- * @version $Revision: 1.20 $
+ * @ThreadSafe
+ * @version $Revision: 6462 $
  */
 public interface ComponentContext {
 	/**
@@ -77,10 +70,10 @@
 	 * If the cardinality of the reference is <code>0..n</code> or
 	 * <code>1..n</code> and multiple services are bound to the reference, the
 	 * service with the highest ranking (as specified in its
-	 * <code>Constants.SERVICE_RANKING</code> property) is returned. If there
-	 * is a tie in ranking, the service with the lowest service ID (as specified
-	 * in its <code>Constants.SERVICE_ID</code> property); that is, the
-	 * service that was registered first is returned.
+	 * <code>Constants.SERVICE_RANKING</code> property) is returned. If there is
+	 * a tie in ranking, the service with the lowest service ID (as specified in
+	 * its <code>Constants.SERVICE_ID</code> property); that is, the service
+	 * that was registered first is returned.
 	 * 
 	 * @param name The name of a reference as specified in a
 	 *        <code>reference</code> element in this component's description.
@@ -117,16 +110,18 @@
 	 *        <code>reference</code> element in this component's description.
 	 * @return An array of service objects for the referenced service or
 	 *         <code>null</code> if the reference cardinality is
-	 *         <code>0..1</code> or <code>0..n</code> and no bound service
-	 *         is available.
+	 *         <code>0..1</code> or <code>0..n</code> and no bound service is
+	 *         available. If the reference cardinality is <code>0..1</code> or
+	 *         <code>1..1</code> and a bound service is available, the array
+	 *         will have exactly one element.
 	 * @throws ComponentException If the Service Component Runtime catches an
 	 *         exception while activating a bound service.
 	 */
 	public Object[] locateServices(String name);
 
 	/**
-	 * Returns the <code>BundleContext</code> of the bundle which contains
-	 * this component.
+	 * Returns the <code>BundleContext</code> of the bundle which contains this
+	 * component.
 	 * 
 	 * @return The <code>BundleContext</code> of the bundle containing this
 	 *         component.
@@ -135,20 +130,19 @@
 
 	/**
 	 * If the component instance is registered as a service using the
-	 * <code>servicefactory=&quot;true&quot;</code> attribute, then this
-	 * method returns the bundle using the service provided by the component
-	 * instance.
+	 * <code>servicefactory=&quot;true&quot;</code> attribute, then this method
+	 * returns the bundle using the service provided by the component instance.
 	 * <p>
 	 * This method will return <code>null</code> if:
 	 * <ul>
 	 * <li>The component instance is not a service, then no bundle can be using
 	 * it as a service.
 	 * <li>The component instance is a service but did not specify the
-	 * <code>servicefactory=&quot;true&quot;</code> attribute, then all
-	 * bundles using the service provided by the component instance will share
-	 * the same component instance.
-	 * <li>The service provided by the component instance is not currently
-	 * being used by any bundle.
+	 * <code>servicefactory=&quot;true&quot;</code> attribute, then all bundles
+	 * using the service provided by the component instance will share the same
+	 * component instance.
+	 * <li>The service provided by the component instance is not currently being
+	 * used by any bundle.
 	 * </ul>
 	 * 
 	 * @return The bundle using the component instance as a service or
@@ -168,8 +162,8 @@
 	 * Enables the specified component name. The specified component name must
 	 * be in the same bundle as this component.
 	 * 
-	 * @param name The name of a component or <code>null</code> to indicate
-	 *        all components in the bundle.
+	 * @param name The name of a component or <code>null</code> to indicate all
+	 *        components in the bundle.
 	 */
 	public void enableComponent(String name);
 
@@ -194,5 +188,4 @@
 	 *         registered as a service.
 	 */
 	public ServiceReference getServiceReference();
-
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentException.java b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentException.java
index be539a9..0aee948 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentException.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.component/src/org/osgi/service/component/ComponentException.java,v 1.13 2006/07/11 13:15:56 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,14 +19,10 @@
 /**
  * Unchecked exception which may be thrown by the Service Component Runtime.
  * 
- * @version $Revision: 1.13 $
+ * @version $Revision: 6083 $
  */
 public class ComponentException extends RuntimeException {
 	static final long	serialVersionUID	= -7438212656298726924L;
-	/**
-	 * Nested exception.
-	 */
-	private final Throwable	cause;
 
 	/**
 	 * Construct a new ComponentException with the specified message and cause.
@@ -37,8 +31,7 @@
 	 * @param cause The cause of the exception. May be <code>null</code>.
 	 */
 	public ComponentException(String message, Throwable cause) {
-		super(message);
-		this.cause = cause;
+		super(message, cause);
 	}
 
 	/**
@@ -48,7 +41,6 @@
 	 */
 	public ComponentException(String message) {
 		super(message);
-		this.cause = null;
 	}
 
 	/**
@@ -57,31 +49,31 @@
 	 * @param cause The cause of the exception. May be <code>null</code>.
 	 */
 	public ComponentException(Throwable cause) {
-		super();
-		this.cause = cause;
+		super(cause);
 	}
-
+	
 	/**
-	 * Returns the cause of this exception or <code>null</code> if no cause
-	 * was specified when this exception was created.
+	 * Returns the cause of this exception or <code>null</code> if no cause was
+	 * set.
 	 * 
-	 * @return The cause of this exception or <code>null</code> if no cause
-	 *         was specified.
+	 * @return The cause of this exception or <code>null</code> if no cause was
+	 *         set.
 	 */
 	public Throwable getCause() {
-		return cause;
+		return super.getCause();
 	}
 
 	/**
-	 * The cause of this exception can only be set when constructed.
+	 * Initializes the cause of this exception to the specified value.
 	 * 
-	 * @param cause Cause of the exception.
-	 * @return This object.
-	 * @throws java.lang.IllegalStateException This method will always throw an
-	 *         <code>IllegalStateException</code> since the cause of this
-	 *         exception can only be set when constructed.
+	 * @param cause The cause of this exception.
+	 * @return This exception.
+	 * @throws IllegalArgumentException If the specified cause is this
+	 *         exception.
+	 * @throws IllegalStateException If the cause of this exception has already
+	 *         been set.
 	 */
 	public Throwable initCause(Throwable cause) {
-		throw new IllegalStateException();
+		return super.initCause(cause);
 	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentFactory.java b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentFactory.java
index 8dc522a..1c77177 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentFactory.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentFactory.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.component/src/org/osgi/service/component/ComponentFactory.java,v 1.19 2006/06/16 16:31:26 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). 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.
@@ -27,7 +25,8 @@
  * created and activated rather than automatically creating and activating
  * component configuration as necessary.
  * 
- * @version $Revision: 1.19 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
  */
 public interface ComponentFactory {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentInstance.java b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentInstance.java
index 9f2d9f5..f2bd2cb 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentInstance.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/ComponentInstance.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.component/src/org/osgi/service/component/ComponentInstance.java,v 1.13 2006/06/16 16:31:26 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). 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.
@@ -27,7 +25,8 @@
  * ComponentInstances are never reused. A new ComponentInstance object will be
  * created when the component configuration is activated again.
  * 
- * @version $Revision: 1.13 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
  */
 public interface ComponentInstance {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/component/package.html
new file mode 100644
index 0000000..2e7717e
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Service Component Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.component; version=&quot;[1.1,2.0)&quot;
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/component/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/component/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/component/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/BundleInfo.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/BundleInfo.java
index 9bd31fb..f945e6a 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/BundleInfo.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/BundleInfo.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/BundleInfo.java,v 1.3 2006/06/16 16:31:39 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdmin.java
index 9376d14..0415c68 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdmin.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentAdmin.java,v 1.28 2007/02/07 18:53:07 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2007). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java
index 34509cf..f329e77 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentAdminPermission.java,v 1.40 2006/07/12 21:22:10 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +19,10 @@
 import java.io.InputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.security.*;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
 
 import org.osgi.framework.Bundle;
 
@@ -191,7 +192,7 @@
                     return c.getConstructor(new Class[] {String.class, String.class});    
                 }
                 catch (Exception e) {
-                    throw new RuntimeException(e.getMessage());
+                    throw new RuntimeException(e);
                 }
             }});
     }
@@ -224,7 +225,7 @@
 			throw e;
 		}
 		catch (Throwable e) {
-			throw new RuntimeException(e.toString());
+			throw new RuntimeException(e);
 		}
     }
 
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentException.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentException.java
index bf5c6e6..4cda326 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentException.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentException.java,v 1.20 2006/07/12 21:22:10 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
@@ -203,8 +201,6 @@
 	public static final int	CODE_TIMEOUT					= 465;
 
 	private final int				code;
-	private final String			message;
-	private final Throwable		cause;
 
 	/**
 	 * Create an instance of the exception.
@@ -215,9 +211,8 @@
 	 * @param cause the originating exception
 	 */
 	public DeploymentException(int code, String message, Throwable cause) {
+		super(message, cause);
 		this.code = code;
-		this.message = message;
-		this.cause = cause;
 	}
 
 	/**
@@ -229,7 +224,8 @@
 	 * @param message Message associated with the exception
 	 */
 	public DeploymentException(int code, String message) {
-		this(code, message, null);
+		super(message);
+		this.code = code;
 	}
 
 	/**
@@ -240,14 +236,34 @@
 	 *        predefined integer values (<code>CODE_X</code>).
 	 */
 	public DeploymentException(int code) {
-		this(code, null, null);
+		super();
+		this.code = code;
 	}
 
 	/**
-	 * @return Returns the cause.
+	 * Returns the cause of this exception or <code>null</code> if no cause was
+	 * set.
+	 * 
+	 * @return The cause of this exception or <code>null</code> if no cause was
+	 *         set.
 	 */
 	public Throwable getCause() {
-		return cause;
+		return super.getCause();
+	}
+
+	/**
+	 * Initializes the cause of this exception to the specified value.
+	 * 
+	 * @param cause The cause of this exception.
+	 * @return This exception.
+	 * @throws IllegalArgumentException If the specified cause is this
+	 *         exception.
+	 * @throws IllegalStateException If the cause of this exception has already
+	 *         been set.
+	 * @since 1.1
+	 */
+	public Throwable initCause(Throwable cause) {
+		return super.initCause(cause);
 	}
 
 	/**
@@ -256,11 +272,4 @@
 	public int getCode() {
 		return code;
 	}
-
-	/**
-	 * @return Returns the message.
-	 */
-	public String getMessage() {
-	    return message;
-	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentPackage.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentPackage.java
index 0155771..6b3e54f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentPackage.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/DeploymentPackage.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/DeploymentPackage.java,v 1.26 2006/07/12 21:22:10 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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,223 +16,347 @@
 
 package org.osgi.service.deploymentadmin;
 
-import org.osgi.framework.*;
+import java.net.URL;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
 
 /**
-  * The <code>DeploymentPackage</code> object represents a deployment package (already installed
-  * or being currently processed). A Deployment Package groups resources as a unit 
-  * of management. A deployment package is something that can be installed, updated, 
-  * and uninstalled as a unit. A deployment package is a reified concept, like a bundle, 
-  * in an OSGi Service Platform. It is not known by the OSGi Framework, but it is managed 
-  * by the Deployment Admin service. A deployment package is a stream of resources 
-  * (including bundles) which, once processed, will result in new artifacts (effects on 
-  * the system) being added to the OSGi platform.  These new artifacts can include 
-  * installed Bundles, new configuration objects added to the Configuration Admin service, 
-  * new Wire objects added to the Wire Admin service, or changed system properties, etc. All 
-  * the changes caused by the processing of a deployment package are persistently 
-  * associated with the deployment package, so that they can be appropriately cleaned 
-  * up when the deployment package is uninstalled. There is a strict no overlap rule 
-  * imposed on deployment packages. Two deployment packages are not allowed to create or 
-  * manipulate the same artifact. Obviously, this means that a bundle cannot be in two 
-  * different deployment packagess. Any violation of this no overlap rule is considered 
-  * an error and the install or update of the offending deployment package must be aborted.<p>
-  * 
-  * The Deployment Admin service should do as much as possible to ensure transactionality. 
-  * It means that if a deployment package installation, update or removal (uninstall) fails 
-  * all the side effects caused by the process should be disappeared  and the system 
-  * should be in the state in which it was before the process.<p>
-  * 
-  * If a deployment package is being updated the old version is visible through the 
-  * <code>DeploymentPackage</code> interface until the update process ends. After the 
-  * package is updated the updated version is visible and the old one is not accessible 
-  * any more.
-  */
+ * The <code>DeploymentPackage</code> object represents a deployment package
+ * (already installed or being currently processed). A Deployment Package groups
+ * resources as a unit of management. A deployment package is something that can
+ * be installed, updated, and uninstalled as a unit. A deployment package is a
+ * reified concept, like a bundle, in an OSGi Service Platform. It is not known
+ * by the OSGi Framework, but it is managed by the Deployment Admin service. A
+ * deployment package is a stream of resources (including bundles) which, once
+ * processed, will result in new artifacts (effects on the system) being added
+ * to the OSGi platform. These new artifacts can include installed Bundles, new
+ * configuration objects added to the Configuration Admin service, new Wire
+ * objects added to the Wire Admin service, or changed system properties, etc.
+ * All the changes caused by the processing of a deployment package are
+ * persistently associated with the deployment package, so that they can be
+ * appropriately cleaned up when the deployment package is uninstalled. There is
+ * a strict no overlap rule imposed on deployment packages. Two deployment
+ * packages are not allowed to create or manipulate the same artifact.
+ * Obviously, this means that a bundle cannot be in two different deployment
+ * packages. Any violation of this no overlap rule is considered an error and
+ * the install or update of the offending deployment package must be aborted.
+ * <p>
+ * 
+ * The Deployment Admin service should do as much as possible to ensure
+ * transactionality. It means that if a deployment package installation, update
+ * or removal (uninstall) fails all the side effects caused by the process
+ * should be disappeared and the system should be in the state in which it was
+ * before the process.
+ * <p>
+ * 
+ * If a deployment package is being updated the old version is visible through
+ * the <code>DeploymentPackage</code> interface until the update process ends.
+ * After the package is updated the updated version is visible and the old one
+ * is not accessible any more.
+ */
 public interface DeploymentPackage {
- 
 	/**
-	 * Gives back the state of the deployment package whether it is stale or not).
-     * After uninstall of a deployment package it becomes stale. Any active method calls to a 
-     * stale deployment package raise {@link IllegalStateException}.
-     * Active methods are the following:<p>
-     * 
-     * <ul>
-     * 		<li>{@link #getBundle(String)}</li>
-     * 		<li>{@link #getResourceProcessor(String)}</li>
-     * 		<li>{@link #uninstall()}</li>
-     * 		<li>{@link #uninstallForced()}</li>
-     * </ul>
-     * 
-	 * @return <code>true</code> if the deployment package is stale. <code>false</code>
-	 *         otherwise
-     * @see #uninstall
-     * @see #uninstallForced
+	 * The name of the Deployment Package. This name is the same name as that
+	 * specified in the DeploymentPackage-SymbolicName Manifest header.
+	 * 
+	 * @since 1.1
 	 */
-    boolean isStale();
-	  
+	String EVENT_DEPLOYMENTPACKAGE_NAME = "deploymentpackage.name";
+
 	/**
-	 * Returns the Deployment Pacakage Symbolic Name of the package.
+	 * The human readable name of the DP localized to the default locale.
+	 * 
+	 * @since 1.1
+	 */
+	String EVENT_DEPLOYMENTPACKAGE_READABLENAME = "deploymentpackage.readablename";
+
+	/**
+	 * The currently installed version of the Deployment Package. The attribute
+	 * is not present, if no version is installed:
+	 * <ul>
+	 * <li>in the INSTALL event, when an installDeploymentPackage was called and
+	 * no earlier version is present
+	 * <li>in the COMPLETE event after the _successfully_ completing an
+	 * uninstallDeploymentPackage call
+	 * </ul>
+	 * The value for this event must be a Version object.
+	 * 
+	 * @since 1.1
+	 */
+	String EVENT_DEPLOYMENTPACKAGE_CURRENTVERSION = "deploymentpackage.currentversion";
+
+	/**
+	 * The version of DP after the successful completion of the install
+	 * operation (used in INSTALL event only).
+	 * 
+	 * The value for this event must be a Version object.
+	 * 
+	 * @since 1.1
+	 */
+	String EVENT_DEPLOYMENTPACKAGE_NEXTVERSION = "deploymentpackage.nextversion";
+
+	/**
+	 * Gives back the state of the deployment package whether it is stale or
+	 * not). After uninstall of a deployment package it becomes stale. Any
+	 * active method calls to a stale deployment package raise
+	 * {@link IllegalStateException}. Active methods are the following:
+	 * <p>
+	 * 
+	 * <ul>
+	 * <li>{@link #getBundle(String)}</li>
+	 * <li>{@link #getResourceProcessor(String)}</li>
+	 * <li>{@link #uninstall()}</li>
+	 * <li>{@link #uninstallForced()}</li>
+	 * </ul>
+	 * 
+	 * @return <code>true</code> if the deployment package is stale.
+	 *         <code>false</code> otherwise
+	 * @see #uninstall
+	 * @see #uninstallForced
+	 */
+	boolean isStale();
+
+	/**
+	 * Returns the Deployment Package Symbolic Name of the package.
 	 * 
 	 * @return The name of the deployment package. It cannot be null.
 	 */
 	String getName();
-	  
+
+	/**
+	 * Returns the Deployment Package human readable name.
+	 * 
+	 * This method returns the localized human readable name as set with the
+	 * <code>DeploymentPackage-Name</code> manifest header using the default
+	 * locale. If no header is set, this method will return <code>null</code>.
+	 * 
+	 * @return The human readable name of the deployment package or
+	 *         <code>null</code> if header is not set.
+	 * @since 1.1
+	 */
+	String getDisplayName();
+
 	/**
 	 * Returns the version of the deployment package.
+	 * 
 	 * @return version of the deployment package. It cannot be null.
 	 */
 	Version getVersion();
-	  
+
 	/**
-	 * Returns an array of {@link BundleInfo} objects representing the bundles specified in the manifest 
-	 * of this deployment package. Its size is equal to the number of the bundles in the deployment package. 
+	 * Returns an array of {@link BundleInfo} objects representing the bundles
+	 * specified in the manifest of this deployment package. Its size is equal
+	 * to the number of the bundles in the deployment package.
 	 * 
- 	 * @return array of <code>BundleInfo</code> objects 
-     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
-     *         with "metadata" action
+	 * @return array of <code>BundleInfo</code> objects
+	 * @throws SecurityException
+	 *             if the caller doesn't have the appropriate
+	 *             {@link DeploymentAdminPermission} with "metadata" action
 	 */
-	BundleInfo[] getBundleInfos();  
- 
-    /**
-     * Returns the bundle instance, which is part of this deployment package, that corresponds 
-     * to the bundle's symbolic name passed in the <code>symbolicName</code> parameter.
-     * This method will return null for request for bundles that are not part 
-     * of this deployment package.<p>
-     * 
-     * As this instance is transient (i.e. a bundle can be removed at any time because of the 
-     * dynamic nature of the OSGi platform), this method may also return null if the bundle
-     * is part of this deployment package, but is not currently defined to the framework.
-     * 
-     * @param symbolicName the symbolic name of the requested bundle
-     * @return The <code>Bundle</code> instance for a given bundle symbolic name.
-     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
-     *         with "metadata" action
-     * @throws IllegalStateException if the package is stale
-     */
-    Bundle getBundle(String symbolicName);
-    
-    /**
-     * Returns an array of strings representing the resources (including bundles) that 
-     * are specified in the  manifest of this deployment package. A string element of the 
-     * array is the same as the value of the "Name" attribute in the manifest. The array 
-     * contains the bundles as well.<p>
-     * 
-     * E.g. if the "Name" section of the resource (or individual-section as the 
-     * <a href="http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html#Manifest%20Specification">Manifest Specification</a> 
-     * calls it) in the manifest is the following
+	BundleInfo[] getBundleInfos();
 
-     * <pre>
-     *     Name: foo/readme.txt
-     *     Resource-Processor: foo.rp
-     * </pre>
-     * 
-     * then the corresponding array element is the "foo/readme.txt" string.<p>
-     * 
-     * @return The string array corresponding to resources. It cannot be null but its 
-     *         length can be zero.
-     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
-     *         with "metadata" action
-     */
-    String[] getResources();   
-    
-    /**
-     * At the time of deployment, resource processor service instances are located to 
-     * resources contained in a deployment package.<p> 
-     * 
-     * This call returns a service reference to the corresponding service instance.
-     * If the resource is not part of the deployment package or this call is made during 
-     * deployment, prior to the locating of the service to process a given resource, null will 
-     * be returned. Services can be updated after a deployment package has been deployed. 
-     * In this event, this call will return a reference to the updated service, not to the 
-     * instance that was used at deployment time.
-     * 
-     * @param resource the name of the resource (it is the same as the value of the "Name" 
-     *        attribute in the deployment package's manifest) 
-     * @return resource processor for the resource or <code>null</cpde>.
-     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
-     *         with "metadata" action
-     * @throws IllegalStateException if the package is stale        
-     */
-    ServiceReference getResourceProcessor(String resource);    
-
-    /**
-     * Returns the requested deployment package manifest header from the main section. 
-     * Header names are case insensitive. If the header doesn't exist it returns null.<p>
-     * 
-     * If the header is localized then the localized value is returned (see OSGi Service Platform,
-     * Mobile Specification Release 4 - Localization related chapters).
-     * 
-     * @param header the requested header
-     * @return the value of the header or <code>null</code> if the header does not exist
-     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
-     *         with "metadata" action
-     */
-    String getHeader(String header);
-
-    /**
-     * Returns the requested deployment package manifest header from the name 
-     * section determined by the resource parameter. Header names are case insensitive. 
-     * If the resource or the header doesn't exist it returns null.<p>
-     * 
-     * If the header is localized then the localized value is returned (see OSGi Service Platform,
-     * Mobile Specification Release 4 - Localization related chapters).
-
-     * @param resource the name of the resource (it is the same as the value of the "Name" 
-     *        attribute in the deployment package's manifest)
-     * @param header the requested header
-     * @return the value of the header or <code>null</code> if the resource or the header doesn't exist
-     * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
-     *         with "metadata" action
-     */
-    String getResourceHeader(String resource, String header);
-    
 	/**
-	  * Uninstalls the deployment package. After uninstallation, the deployment package 
-	  * object becomes stale. This can be checked by using {@link #isStale()}, 
-	  * which will return <code>true</code> when stale.<p>
-	  * 
-	  * @throws DeploymentException if the deployment package could not be successfully uninstalled. 
-	  *         For detailed error code description see {@link DeploymentException}.
-	  * @throws SecurityException if the caller doesn't have the appropriate 
-	  * 		{@link DeploymentAdminPermission}("&lt;filter&gt;", "uninstall") permission.
-	  * @throws IllegalStateException if the package is stale 
-	  */
-    void uninstall() throws DeploymentException;
- 
-    /**
-     * This method is called to completely uninstall a deployment package, which couldn't be uninstalled
-     * using traditional means ({@link #uninstall()}) due to exceptions. After uninstallation, the deployment 
-     * package object becomes stale. This can be checked by using {@link #isStale()}, 
-     * which will return <code>true</code> when stale.<p>
-     *  
-     * The method forces removal of the Deployment Package from the repository maintained by the 
-     * Deployment Admin service. This method follows the same steps as {@link #uninstall}. However, 
-     * any errors or the absence of Resource Processor services are ignored, they must not cause a roll back.
-     * These errors should be logged.
-     * 
-     * @return true if the operation was successful
-     * @throws DeploymentException only {@link DeploymentException#CODE_TIMEOUT} and 
-     *         {@link DeploymentException#CODE_CANCELLED} can be thrown. For detailed error code description 
-	 *         see {@link DeploymentException}.
-     * @throws SecurityException if the caller doesn't have the appropriate 
-     *         {@link DeploymentAdminPermission}("&lt;filter&gt;", "uninstall_forced") permission.
-     * @throws IllegalStateException if the package is stale
-     */  
-    boolean uninstallForced() throws DeploymentException;  
- 
-    /**
-     * Returns a hash code value for the object.
-     * 
-     * @return a hash code value for this object
-     */
-    int hashCode();
-  
-    /**
-     * Indicates whether some other object is "equal to" this one. Two deployment packages 
-     * are equal if they have the same deployment package symbolicname and version.
-     * 
-     * @param other the reference object with which to compare.
-     * @return true if this object is the same as the obj argument; false otherwise.
-     */
-    boolean equals(Object other);
-  
+	 * Returns a URL pointing to an image that represents the icon for this
+	 * Deployment Package.
+	 * 
+	 * The <code>DeploymentPackage-Icon</code> header can set an icon for the
+	 * the deployment package. This method returns an absolute URL that is
+	 * defined by this header. The Deployment Admin service must provide this
+	 * icon as a local resource. That is, the Deployment Admin must make a local
+	 * copy of the specified icon. The returned <code>URL</code>'s must point to
+	 * a local resource.
+	 * 
+	 * @return An absolute URL to a local (device resident) image resource or
+	 *         <code>null</code> if not found
+	 * @since 1.1
+	 */
+	URL getIcon();
+
+	/**
+	 * Returns the bundle instance, which is part of this deployment package,
+	 * that corresponds to the bundle's symbolic name passed in the
+	 * <code>symbolicName</code> parameter. This method will return null for
+	 * request for bundles that are not part of this deployment package.
+	 * <p>
+	 * 
+	 * As this instance is transient (i.e. a bundle can be removed at any time
+	 * because of the dynamic nature of the OSGi platform), this method may also
+	 * return null if the bundle is part of this deployment package, but is not
+	 * currently defined to the framework.
+	 * 
+	 * @param symbolicName
+	 *            the symbolic name of the requested bundle
+	 * @return The <code>Bundle</code> instance for a given bundle symbolic
+	 *         name.
+	 * @throws SecurityException
+	 *             if the caller doesn't have the appropriate
+	 *             {@link DeploymentAdminPermission} with "metadata" action
+	 * @throws IllegalStateException
+	 *             if the package is stale
+	 */
+	Bundle getBundle(String symbolicName);
+
+	/**
+	 * Returns an array of strings representing the resources (including
+	 * bundles) that are specified in the manifest of this deployment package. A
+	 * string element of the array is the same as the value of the "Name"
+	 * attribute in the manifest. The array contains the bundles as well.
+	 * <p>
+	 * 
+	 * E.g. if the "Name" section of the resource (or individual-section as the
+	 * <a
+	 * href="http://java.sun.com/j2se/1.4.2/docs/guide/jar/jar.html#Manifest%20Specification">Manifest
+	 * Specification</a> calls it) in the manifest is the following
+	 * 
+	 * <pre>
+	 *     Name: foo/readme.txt
+	 *     Resource-Processor: foo.rp
+	 * </pre>
+	 * 
+	 * then the corresponding array element is the "foo/readme.txt" string.
+	 * <p>
+	 * 
+	 * @return The string array corresponding to resources. It cannot be null
+	 *         but its length can be zero.
+	 * @throws SecurityException
+	 *             if the caller doesn't have the appropriate
+	 *             {@link DeploymentAdminPermission} with "metadata" action
+	 */
+	String[] getResources();
+
+	/**
+	 * At the time of deployment, resource processor service instances are
+	 * located to resources contained in a deployment package.
+	 * <p>
+	 * 
+	 * This call returns a service reference to the corresponding service
+	 * instance. If the resource is not part of the deployment package or this
+	 * call is made during deployment, prior to the locating of the service to
+	 * process a given resource, null will be returned. Services can be updated
+	 * after a deployment package has been deployed. In this event, this call
+	 * will return a reference to the updated service, not to the instance that
+	 * was used at deployment time.
+	 * 
+	 * @param resource
+	 *            the name of the resource (it is the same as the value of the
+	 *            "Name" attribute in the deployment package's manifest)
+	 * @return resource processor for the resource or <code>null</cpde>.
+	 * @throws SecurityException if the caller doesn't have the appropriate {@link DeploymentAdminPermission} 
+	 *         with "metadata" action
+	 * @throws IllegalStateException if the package is stale
+	 */
+	ServiceReference getResourceProcessor(String resource);
+
+	/**
+	 * Returns the requested deployment package manifest header from the main
+	 * section. Header names are case insensitive. If the header doesn't exist
+	 * it returns null.
+	 * <p>
+	 * 
+	 * If the header is localized then the localized value is returned (see OSGi
+	 * Service Platform, Mobile Specification Release 4 - Localization related
+	 * chapters).
+	 * 
+	 * @param header
+	 *            the requested header
+	 * @return the value of the header or <code>null</code> if the header does
+	 *         not exist
+	 * @throws SecurityException
+	 *             if the caller doesn't have the appropriate
+	 *             {@link DeploymentAdminPermission} with "metadata" action
+	 */
+	String getHeader(String header);
+
+	/**
+	 * Returns the requested deployment package manifest header from the name
+	 * section determined by the resource parameter. Header names are case
+	 * insensitive. If the resource or the header doesn't exist it returns null.
+	 * <p>
+	 * 
+	 * If the header is localized then the localized value is returned (see OSGi
+	 * Service Platform, Mobile Specification Release 4 - Localization related
+	 * chapters).
+	 * 
+	 * @param resource
+	 *            the name of the resource (it is the same as the value of the
+	 *            "Name" attribute in the deployment package's manifest)
+	 * @param header
+	 *            the requested header
+	 * @return the value of the header or <code>null</code> if the resource or
+	 *         the header doesn't exist
+	 * @throws SecurityException
+	 *             if the caller doesn't have the appropriate
+	 *             {@link DeploymentAdminPermission} with "metadata" action
+	 */
+	String getResourceHeader(String resource, String header);
+
+	/**
+	 * Uninstalls the deployment package. After uninstallation, the deployment
+	 * package object becomes stale. This can be checked by using
+	 * {@link #isStale()}, which will return <code>true</code> when stale.
+	 * <p>
+	 * 
+	 * @throws DeploymentException
+	 *             if the deployment package could not be successfully
+	 *             uninstalled. For detailed error code description see
+	 *             {@link DeploymentException}.
+	 * @throws SecurityException
+	 *             if the caller doesn't have the appropriate
+	 *             {@link DeploymentAdminPermission}("&lt;filter&gt;",
+	 *             "uninstall") permission.
+	 * @throws IllegalStateException
+	 *             if the package is stale
+	 */
+	void uninstall() throws DeploymentException;
+
+	/**
+	 * This method is called to completely uninstall a deployment package, which
+	 * couldn't be uninstalled using traditional means ({@link #uninstall()})
+	 * due to exceptions. After uninstallation, the deployment package object
+	 * becomes stale. This can be checked by using {@link #isStale()}, which
+	 * will return <code>true</code> when stale.
+	 * <p>
+	 * 
+	 * The method forces removal of the Deployment Package from the repository
+	 * maintained by the Deployment Admin service. This method follows the same
+	 * steps as {@link #uninstall}. However, any errors or the absence of
+	 * Resource Processor services are ignored, they must not cause a roll back.
+	 * These errors should be logged.
+	 * 
+	 * @return true if the operation was successful
+	 * @throws DeploymentException
+	 *             only {@link DeploymentException#CODE_TIMEOUT} and
+	 *             {@link DeploymentException#CODE_CANCELLED} can be thrown. For
+	 *             detailed error code description see
+	 *             {@link DeploymentException}.
+	 * @throws SecurityException
+	 *             if the caller doesn't have the appropriate
+	 *             {@link DeploymentAdminPermission}("&lt;filter&gt;",
+	 *             "uninstall_forced") permission.
+	 * @throws IllegalStateException
+	 *             if the package is stale
+	 */
+	boolean uninstallForced() throws DeploymentException;
+
+	/**
+	 * Returns a hash code value for the object.
+	 * 
+	 * @return a hash code value for this object
+	 */
+	int hashCode();
+
+	/**
+	 * Indicates whether some other object is "equal to" this one. Two
+	 * deployment packages are equal if they have the same deployment package
+	 * symbolicname and version.
+	 * 
+	 * @param other
+	 *            the reference object with which to compare.
+	 * @return true if this object is the same as the obj argument; false
+	 *         otherwise.
+	 */
+	boolean equals(Object other);
+
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/package.html
new file mode 100644
index 0000000..5ba69e3
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Deployment Admin Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.deploymentadmin; version=&quot;[1.1,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java
index 681329e..fa4534f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java
@@ -1,8 +1,6 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/spi/DeploymentCustomizerPermission.java,v 1.6 2006/06/21 15:16:13 hargrave Exp $
  * 
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +19,10 @@
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import java.security.*;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
 
 import org.osgi.service.deploymentadmin.DeploymentAdminPermission;
 
@@ -65,7 +66,7 @@
                     return c.getConstructor(new Class[] {String.class, String.class});    
                 }
                 catch (Exception e) {
-                    throw new RuntimeException(e.getMessage());
+                    throw new RuntimeException(e);
                 }
             }});
     }
@@ -112,7 +113,7 @@
 			throw e;
 		}
 		catch (Throwable e) {
-			throw new RuntimeException(e.toString());
+			throw new RuntimeException(e);
 		}
     }
 
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentSession.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentSession.java
index 87a5b1f..be2877c 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentSession.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/DeploymentSession.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/spi/DeploymentSession.java,v 1.6 2006/06/16 16:31:39 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java
index ec5a5fd..9951c13 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/spi/ResourceProcessor.java,v 1.6 2006/07/11 13:19:02 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java
index eb9c3dc..f677801 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.deploymentadmin/src/org/osgi/service/deploymentadmin/spi/ResourceProcessorException.java,v 1.7 2006/07/12 21:22:10 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
@@ -60,8 +58,6 @@
 	public static final int	CODE_OTHER_ERROR				= 463;
 
 	private final int				code;
-	private final String			message;
-	private final Throwable		cause;
 
 	/**
 	 * Create an instance of the exception.
@@ -72,9 +68,8 @@
 	 * @param cause the originating exception
 	 */
 	public ResourceProcessorException(int code, String message, Throwable cause) {
+		super(message, cause);
 		this.code = code;
-		this.message = message;
-		this.cause = cause;
 	}
 
 	/**
@@ -86,7 +81,8 @@
 	 * @param message Message associated with the exception
 	 */
 	public ResourceProcessorException(int code, String message) {
-		this(code, message, null);
+		super(message);
+		this.code = code;
 	}
 
 	/**
@@ -97,14 +93,34 @@
 	 *        predefined integer values (<code>CODE_X</code>).
 	 */
 	public ResourceProcessorException(int code) {
-		this(code, null, null);
+		super();
+		this.code = code;
 	}
 
 	/**
-	 * @return Returns the cause.
+	 * Returns the cause of this exception or <code>null</code> if no cause was
+	 * set.
+	 * 
+	 * @return The cause of this exception or <code>null</code> if no cause was
+	 *         set.
 	 */
 	public Throwable getCause() {
-		return cause;
+		return super.getCause();
+	}
+
+	/**
+	 * Initializes the cause of this exception to the specified value.
+	 * 
+	 * @param cause The cause of this exception.
+	 * @return This exception.
+	 * @throws IllegalArgumentException If the specified cause is this
+	 *         exception.
+	 * @throws IllegalStateException If the cause of this exception has already
+	 *         been set.
+	 * @since 1.0.1
+	 */
+	public Throwable initCause(Throwable cause) {
+		return super.initCause(cause);
 	}
 
 	/**
@@ -113,11 +129,4 @@
 	public int getCode() {
 		return code;
 	}
-
-	/**
-	 * @return Returns the message.
-	 */
-	public String getMessage() {
-	    return message;
-	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/package.html
new file mode 100644
index 0000000..cfa5e3f
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/package.html
@@ -0,0 +1,12 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Deployment Admin SPI Package Version 1.0.
+The SPI is used by Resource Processors.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.deploymentadmin.spi; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/packageinfo
new file mode 100644
index 0000000..b3d1f97
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/deploymentadmin/spi/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/Constants.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/Constants.java
index 6c108dd..8787256 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/Constants.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/Constants.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/Constants.java,v 1.9 2006/07/11 00:54:08 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). 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,7 +23,7 @@
  * The values associated with these keys are of type <code>java.lang.String</code>,
  * unless otherwise stated.
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
  * @since 1.1
  * @see Device
  * @see Driver
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/Device.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/Device.java
index 80e7d3f..2af0330 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/Device.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/Device.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/Device.java,v 1.10 2006/07/11 00:54:08 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). 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,7 +23,8 @@
  * A service must implement this interface or use the
  * {@link Constants#DEVICE_CATEGORY} registration property to indicate that it
  * is a device. Any services implementing this interface or registered with the
- * <code>DEVICE_CATEGORY</code> property will be discovered by the device manager.
+ * <code>DEVICE_CATEGORY</code> property will be discovered by the device
+ * manager.
  * 
  * <p>
  * Device services implementing this interface give the device manager the
@@ -37,8 +36,9 @@
  * Specialized device implementations will extend this interface by adding
  * methods appropriate to their device category to it.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5654 $
  * @see Driver
+ * @ThreadSafe
  */
 public interface Device {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/Driver.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/Driver.java
index 9d19a6a..98e3617 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/Driver.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/Driver.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/Driver.java,v 1.11 2006/07/11 00:54:08 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). 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.
@@ -27,9 +25,10 @@
  * highest for a particular <code>Device</code> object will be instructed by the
  * device manager to attach to the <code>Device</code> object.
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 5654 $
  * @see Device
  * @see DriverLocator
+ * @ThreadSafe
  */
 public interface Driver {
 	/**
@@ -43,8 +42,8 @@
 	 * <p>
 	 * The return value must be one of the possible match values defined in the
 	 * device category definition for the given Device service, or
-	 * <code>Device.MATCH_NONE</code> if the category of the Device service is not
-	 * recognized.
+	 * <code>Device.MATCH_NONE</code> if the category of the Device service is
+	 * not recognized.
 	 * 
 	 * <p>
 	 * In order to make its decision, this Driver service may examine the
@@ -61,15 +60,15 @@
 	 * The match function is called by the device manager during the matching
 	 * process.
 	 * 
-	 * @param reference the <code>ServiceReference</code> object of the device to
-	 *        match
+	 * @param reference the <code>ServiceReference</code> object of the device
+	 *        to match
 	 * 
 	 * @return value indicating how well this driver can support the given
 	 *         Device service, or <code>Device.MATCH_NONE</code> if it cannot
 	 *         support the Device service at all
 	 * 
 	 * @throws java.lang.Exception if this Driver service cannot examine the
-	 *            Device service
+	 *         Device service
 	 */
 	public int match(ServiceReference reference) throws Exception;
 
@@ -78,13 +77,13 @@
 	 * given <code>ServiceReference</code> object.
 	 * 
 	 * <p>
-	 * A return value of <code>null</code> indicates that this Driver service has
-	 * successfully attached to the given Device service. If this Driver service
-	 * is unable to attach to the given Device service, but knows of a more
-	 * suitable Driver service, it must return the <code>DRIVER_ID</code> of that
-	 * Driver service. This allows for the implementation of referring drivers
-	 * whose only purpose is to refer to other drivers capable of handling a
-	 * given Device service.
+	 * A return value of <code>null</code> indicates that this Driver service
+	 * has successfully attached to the given Device service. If this Driver
+	 * service is unable to attach to the given Device service, but knows of a
+	 * more suitable Driver service, it must return the <code>DRIVER_ID</code>
+	 * of that Driver service. This allows for the implementation of referring
+	 * drivers whose only purpose is to refer to other drivers capable of
+	 * handling a given Device service.
 	 * 
 	 * <p>
 	 * After having attached to the Device service, this driver may register the
@@ -94,15 +93,15 @@
 	 * <p>
 	 * This method is called by the device manager.
 	 * 
-	 * @param reference the <code>ServiceReference</code> object of the device to
-	 *        attach to
+	 * @param reference the <code>ServiceReference</code> object of the device
+	 *        to attach to
 	 * 
-	 * @return <code>null</code> if this Driver service has successfully attached
-	 *         to the given Device service, or the <code>DRIVER_ID</code> of a
-	 *         more suitable driver
+	 * @return <code>null</code> if this Driver service has successfully
+	 *         attached to the given Device service, or the
+	 *         <code>DRIVER_ID</code> of a more suitable driver
 	 * 
 	 * @throws java.lang.Exception if the driver cannot attach to the given
-	 *            device and does not know of a more suitable driver
+	 *         device and does not know of a more suitable driver
 	 */
 	public String attach(ServiceReference reference) throws Exception;
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverLocator.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverLocator.java
index ec1a3d9..2726b99 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverLocator.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverLocator.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/DriverLocator.java,v 1.10 2006/07/12 21:22:12 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). 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,8 +28,9 @@
  * providers and encapsulate all provider-specific details related to the
  * location and acquisition of driver bundles.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5654 $
  * @see Driver
+ * @ThreadSafe
  */
 public interface DriverLocator {
 	/**
@@ -56,9 +55,9 @@
 	 * 
 	 * @param id the <code>DRIVER_ID</code> of the driver that needs to be
 	 *        installed.
-	 * @return An <code>InputStream</code> object from which the driver bundle can
-	 *         be installed or <code>null</code> if the driver with the given ID
-	 *         cannot be located
+	 * @return An <code>InputStream</code> object from which the driver bundle
+	 *         can be installed or <code>null</code> if the driver with the
+	 *         given ID cannot be located
 	 * @throws java.io.IOException the input stream for the bundle cannot be
 	 *         created
 	 */
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverSelector.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverSelector.java
index dcda453..59fd0b9 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverSelector.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/DriverSelector.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/DriverSelector.java,v 1.9 2006/06/16 16:31:29 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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,16 +23,18 @@
  * least one Driver service matches, the device manager must choose one. If
  * there is a Driver Selector service registered with the Framework, the device
  * manager will ask it to make the selection. If there is no Driver Selector
- * service, or if it returns an invalid result, or throws an <code>Exception</code>,
- * the device manager uses the default selection strategy.
+ * service, or if it returns an invalid result, or throws an
+ * <code>Exception</code>, the device manager uses the default selection
+ * strategy.
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5654 $
  * @since 1.1
+ * @ThreadSafe
  */
 public interface DriverSelector {
 	/**
-	 * Return value from <code>DriverSelector.select</code>, if no Driver service
-	 * should be attached to the Device service. The value is -1.
+	 * Return value from <code>DriverSelector.select</code>, if no Driver
+	 * service should be attached to the Device service. The value is -1.
 	 */
 	public static final int	SELECT_NONE	= -1;
 
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/Match.java b/org.osgi.compendium/src/main/java/org/osgi/service/device/Match.java
index e666cda..6410659 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/device/Match.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/Match.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.device/src/org/osgi/service/device/Match.java,v 1.9 2006/06/16 16:31:29 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,9 +21,10 @@
  * Instances of <code>Match</code> are used in the {@link DriverSelector#select}
  * method to identify Driver services matching a Device service.
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5654 $
  * @since 1.1
  * @see DriverSelector
+ * @ThreadSafe
  */
 public interface Match {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/device/package.html
new file mode 100644
index 0000000..7647c20
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Device Access Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.device; version=&quot;[1.1,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/device/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/device/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/device/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/Event.java b/org.osgi.compendium/src/main/java/org/osgi/service/event/Event.java
index b0df6ee..42cdb1b 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/event/Event.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/Event.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.event/src/org/osgi/service/event/Event.java,v 1.8 2006/07/12 13:17:04 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2009). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +16,12 @@
 
 package org.osgi.service.event;
 
-import java.util.*;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
 
 import org.osgi.framework.Filter;
 
@@ -26,48 +29,81 @@
  * An event.
  * 
  * <code>Event</code> objects are delivered to <code>EventHandler</code>
- * services which subsrcibe to the topic of the event.
+ * services which subscribe to the topic of the event.
  * 
- * @version $Revision: 1.8 $
+ * @Immutable
+ * @version $Revision: 7003 $
  */
 public class Event {
 	/**
 	 * The topic of this event.
 	 */
-	String	topic;
+	private final String	topic;
 	/**
 	 * The properties carried by this event. Keys are strings and values are
 	 * objects
 	 */
-	Hashtable	properties;
+	private final Map		/* <String,Object> */properties;
 
 	/**
 	 * Constructs an event.
 	 * 
 	 * @param topic The topic of the event.
-	 * @param properties The event's properties (may be <code>null</code>).
-	 * 
+	 * @param properties The event's properties (may be <code>null</code>). A
+	 *        property whose key is not of type <code>String</code> will be
+	 *        ignored.
 	 * @throws IllegalArgumentException If topic is not a valid topic name.
+	 * @since 1.2
 	 */
-	public Event(String topic, Dictionary properties) {
+	public Event(String topic, Map/* <String,Object> */properties) {
+		validateTopicName(topic);
 		this.topic = topic;
-		validateTopicName();
-		this.properties = new Hashtable();
+		int size = (properties == null) ? 1 : (properties.size() + 1);
+		Map p = new HashMap(size);
 		if (properties != null) {
-			for (Enumeration e = properties.keys(); e.hasMoreElements();) {
-				String key = (String) e.nextElement();
-				Object value = properties.get(key);
-				this.properties.put(key, value);
+			for (Iterator iter = properties.keySet().iterator(); iter.hasNext();) {
+				Object key = iter.next();
+				if (key instanceof String) {
+					Object value = properties.get(key);
+					p.put(key, value);
+				}
 			}
 		}
-		this.properties.put(EventConstants.EVENT_TOPIC, topic);
+		p.put(EventConstants.EVENT_TOPIC, topic);
+		this.properties = p; // safely publish the map
+	}
+
+	/**
+	 * Constructs an event.
+	 * 
+	 * @param topic The topic of the event.
+	 * @param properties The event's properties (may be <code>null</code>). A
+	 *        property whose key is not of type <code>String</code> will be
+	 *        ignored.
+	 * @throws IllegalArgumentException If topic is not a valid topic name.
+	 */
+	public Event(String topic, Dictionary/* <String,Object> */properties) {
+		validateTopicName(topic);
+		this.topic = topic;
+		int size = (properties == null) ? 1 : (properties.size() + 1);
+		Map p = new HashMap(size);
+		if (properties != null) {
+			for (Enumeration e = properties.keys(); e.hasMoreElements();) {
+				Object key = e.nextElement();
+				if (key instanceof String) {
+					Object value = properties.get(key);
+					p.put(key, value);
+				}
+			}
+		}
+		p.put(EventConstants.EVENT_TOPIC, topic);
+		this.properties = p; // safely publish the map
 	}
 
 	/**
 	 * Retrieves a property.
 	 * 
 	 * @param name the name of the property to retrieve
-	 * 
 	 * @return The value of the property, or <code>null</code> if not found.
 	 */
 	public final Object getProperty(String name) {
@@ -80,12 +116,8 @@
 	 * @return A non-empty array with one element per property.
 	 */
 	public final String[] getPropertyNames() {
-		String[] names = new String[properties.size()];
-		Enumeration keys = properties.keys();
-		for (int i = 0; keys.hasMoreElements(); i++) {
-			names[i] = (String) keys.nextElement();
-		}
-		return names;
+		return (String[]) properties.keySet().toArray(
+				new String[properties.size()]);
 	}
 
 	/**
@@ -98,31 +130,30 @@
 	}
 
 	/**
-	 * Tests this event's properties against the given filter.
+	 * Tests this event's properties against the given filter using a case
+	 * sensitive match.
 	 * 
 	 * @param filter The filter to test.
-	 * 
 	 * @return true If this event's properties match the filter, false
 	 *         otherwise.
 	 */
 	public final boolean matches(Filter filter) {
-		return filter.matchCase(properties);
+		return filter.matchCase(new UnmodifiableDictionary(properties));
 	}
 
 	/**
 	 * Compares this <code>Event</code> object to another object.
 	 * 
 	 * <p>
-	 * An event is considered to be <b>equal to </b> another
-	 * event if the topic is equal and the properties are equal.
+	 * An event is considered to be <b>equal to</b> another event if the topic
+	 * is equal and the properties are equal.
 	 * 
 	 * @param object The <code>Event</code> object to be compared.
-	 * @return <code>true</code> if <code>object</code> is a
-	 *         <code>Event</code> and is equal to this object;
-	 *         <code>false</code> otherwise.
+	 * @return <code>true</code> if <code>object</code> is a <code>Event</code>
+	 *         and is equal to this object; <code>false</code> otherwise.
 	 */
 	public boolean equals(Object object) {
-		if (object == this) { // quicktest
+		if (object == this) { // quick test
 			return true;
 		}
 
@@ -140,7 +171,9 @@
 	 * @return An integer which is a hash code value for this object.
 	 */
 	public int hashCode() {
-		return topic.hashCode() ^ properties.hashCode();
+		int h = 31 * 17 + topic.hashCode();
+		h = 31 * h + properties.hashCode();
+		return h;
 	}
 
 	/**
@@ -149,47 +182,82 @@
 	 * @return The string representation of this event.
 	 */
 	public String toString() {
-		return getClass().getName() + " [topic=" + topic + "]"; //$NON-NLS-1$ //$NON-NLS-2$
+		return getClass().getName() + " [topic=" + topic + "]";  
 	}
 
-	private static final String	SEPARATOR	= "/"; //$NON-NLS-1$
-
 	/**
 	 * Called by the constructor to validate the topic name.
 	 * 
+	 * @param topic The topic name to validate.
 	 * @throws IllegalArgumentException If the topic name is invalid.
 	 */
-	private void validateTopicName() {
-		try {
-			StringTokenizer st = new StringTokenizer(topic, SEPARATOR, true);
-			validateToken(st.nextToken());
-
-			while (st.hasMoreTokens()) {
-				st.nextToken(); // consume delimiter
-				validateToken(st.nextToken());
-			}
+	private static void validateTopicName(String topic) {
+	    char[] chars = topic.toCharArray();
+	    int length = chars.length;
+	    if (length == 0) {
+			throw new IllegalArgumentException("empty topic");
 		}
-		catch (NoSuchElementException e) {
-			throw new IllegalArgumentException("invalid topic"); //$NON-NLS-1$
-		}
+		for (int i = 0; i < length; i++) {
+	        char ch = chars[i];
+	        if (ch == '/') {
+	        	// Can't start or end with a '/' but anywhere else is okay
+				if (i == 0 || (i == length - 1)) {
+	                throw new IllegalArgumentException(
+							"invalid topic: "
+							+ topic); 
+	            }
+	            // Can't have "//" as that implies empty token
+	            if (chars[i-1] == '/') {
+	                throw new IllegalArgumentException(
+							"invalid topic: "
+							+ topic); 
+	            }
+	            continue;
+	        }
+	        if (('A' <= ch) && (ch <= 'Z')) {
+	            continue;
+	        }
+	        if (('a' <= ch) && (ch <= 'z')) {
+	            continue;
+	        }
+	        if (('0' <= ch) && (ch <= '9')) {
+	            continue;
+	        }
+	        if ((ch == '_') || (ch == '-')) {
+	            continue;
+	        }
+	        throw new IllegalArgumentException("invalid topic: " + topic); 
+	    }
 	}
-
-	private static final String	tokenAlphabet	= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-"; //$NON-NLS-1$
-
+	
 	/**
-	 * Validate a token.
-	 * 
-	 * @throws IllegalArgumentException If the token is invalid.
+	 * Unmodifiable wrapper for Dictionary.
 	 */
-	private void validateToken(String token) {
-		int length = token.length();
-		if (length < 1) {	// token must contain at least one character
-			throw new IllegalArgumentException("invalid topic"); //$NON-NLS-1$
+	private static class UnmodifiableDictionary extends Dictionary {
+		private final Map	wrapped;
+		UnmodifiableDictionary(Map wrapped) {
+			this.wrapped = wrapped;
 		}
-		for (int i = 0; i < length; i++) { // each character in the token must be from the token alphabet
-			if (tokenAlphabet.indexOf(token.charAt(i)) == -1) { //$NON-NLS-1$
-				throw new IllegalArgumentException("invalid topic"); //$NON-NLS-1$
-			}
+		public Enumeration elements() {
+			return Collections.enumeration(wrapped.values());
+		}
+		public Object get(Object key) {
+			return wrapped.get(key);
+		}
+		public boolean isEmpty() {
+			return wrapped.isEmpty();
+		}
+		public Enumeration keys() {
+			return Collections.enumeration(wrapped.keySet());
+		}
+		public Object put(Object key, Object value) {
+			throw new UnsupportedOperationException();
+		}
+		public Object remove(Object key) {
+			throw new UnsupportedOperationException();
+		}
+		public int size() {
+			return wrapped.size();
 		}
 	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventAdmin.java
index 1683e7b..f48a10f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventAdmin.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.event/src/org/osgi/service/event/EventAdmin.java,v 1.6 2006/06/16 16:31:48 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,32 +20,33 @@
  * The Event Admin service. Bundles wishing to publish events must obtain the
  * Event Admin service and call one of the event delivery methods.
  * 
- * @version $Revision: 1.6 $
+ * @ThreadSafe
+ * @version $Revision: 5673 $
  */
 public interface EventAdmin {
 	/**
-	 * Initiate asynchronous delivery of an event. This method returns to
-	 * the caller before delivery of the event is completed.
+	 * Initiate asynchronous delivery of an event. This method returns to the
+	 * caller before delivery of the event is completed.
 	 * 
-	 * @param event The event to send to all listeners which subscribe
-	 *        to the topic of the event.
+	 * @param event The event to send to all listeners which subscribe to the
+	 *        topic of the event.
 	 * 
 	 * @throws SecurityException If the caller does not have
-	 *            <code>TopicPermission[topic,PUBLISH]</code> for the topic
-	 *            specified in the event.
+	 *         <code>TopicPermission[topic,PUBLISH]</code> for the topic
+	 *         specified in the event.
 	 */
 	void postEvent(Event event);
 
 	/**
-	 * Initiate synchronous delivery of an event. This method does not
-	 * return to the caller until delivery of the event is completed.
+	 * Initiate synchronous delivery of an event. This method does not return to
+	 * the caller until delivery of the event is completed.
 	 * 
-	 * @param event The event to send to all listeners which subscribe
-	 *        to the topic of the event.
+	 * @param event The event to send to all listeners which subscribe to the
+	 *        topic of the event.
 	 * 
 	 * @throws SecurityException If the caller does not have
-	 *            <code>TopicPermission[topic,PUBLISH]</code> for the topic
-	 *            specified in the event.
+	 *         <code>TopicPermission[topic,PUBLISH]</code> for the topic
+	 *         specified in the event.
 	 */
 	void sendEvent(Event event);
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventConstants.java b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventConstants.java
index e6768d0..ed3d5d0 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventConstants.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventConstants.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.event/src/org/osgi/service/event/EventConstants.java,v 1.14 2006/07/12 21:06:18 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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,31 +16,34 @@
 
 package org.osgi.service.event;
 
+import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
 
 /**
- * 
  * Defines standard names for <code>EventHandler</code> properties.
  * 
- * @version $Revision: 1.14 $
+ * @version $Revision: 7368 $
  */
 public interface EventConstants {
 
 	/**
-	 * Service registration property (named <code>event.topic</code>)
+	 * Service registration property (named <code>event.topics</code>)
 	 * specifying the <code>Event</code> topics of interest to a Event Handler
 	 * service.
 	 * <p>
 	 * Event handlers SHOULD be registered with this property. The value of the
-	 * property is an array of strings that describe the topics in which the
-	 * handler is interested. An asterisk ('*') may be used as a trailing
-	 * wildcard. Event Handlers which do not have a value for this property must
-	 * not receive events. More precisely, the value of each entry in the array
-	 * must conform to the following grammar:
+	 * property is a string or an array of strings that describe the topics in
+	 * which the handler is interested. An asterisk ('*') may be used as a
+	 * trailing wildcard. Event Handlers which do not have a value for this
+	 * property must not receive events. More precisely, the value of each
+	 * string must conform to the following grammar:
 	 * 
 	 * <pre>
-	 *            topic-description := '*' | topic ( '/*' )?
-	 *            topic := token ( '/' token )*
+	 *  topic-description := '*' | topic ( '/*' )?
+	 *  topic := token ( '/' token )*
 	 * </pre>
 	 * 
 	 * @see Event
@@ -51,8 +52,8 @@
 
 	/**
 	 * Service Registration property (named <code>event.filter</code>)
-	 * specifying a filter to further select <code>Event</code> s of interest
-	 * to a Event Handler service.
+	 * specifying a filter to further select <code>Event</code> s of interest to
+	 * a Event Handler service.
 	 * <p>
 	 * Event handlers MAY be registered with this property. The value of this
 	 * property is a string containing an LDAP-style filter specification. Any
@@ -67,94 +68,116 @@
 	 * and a warning should be logged.
 	 * 
 	 * @see Event
-	 * @see org.osgi.framework.Filter
+	 * @see Filter
 	 */
 	public static final String	EVENT_FILTER		= "event.filter";
 
 	/**
-	 * The Distinguished Name of the bundle relevant to the event.
+	 * The Distinguished Names of the signers of the bundle relevant to the
+	 * event. The type of the value for this event property is
+	 * <code>String</code> or <code>Collection</code> of <code>String</code>.
 	 */
 	public static final String	BUNDLE_SIGNER		= "bundle.signer";
 
 	/**
-	 * The Bundle Symbolic Name of the bundle relevant to the event.
+	 * The Bundle Symbolic Name of the bundle relevant to the event. The type of
+	 * the value for this event property is <code>String</code>.
 	 */
 	public static final String	BUNDLE_SYMBOLICNAME	= "bundle.symbolicName";
 
 	/**
-	 * The Bundle id of the bundle relevant to the event.
+	 * The Bundle id of the bundle relevant to the event. The type of the value
+	 * for this event property is <code>Long</code>.
 	 * 
 	 * @since 1.1
 	 */
 	public static final String	BUNDLE_ID			= "bundle.id";
 
 	/**
-	 * The Bundle object of the bundle relevant to the event.
+	 * The Bundle object of the bundle relevant to the event. The type of the
+	 * value for this event property is {@link Bundle}.
 	 * 
 	 * @since 1.1
 	 */
 	public static final String	BUNDLE				= "bundle";
 
 	/**
-	 * The actual event object. Used when rebroadcasting an event that was sent
-	 * via some other event mechanism.
+	 * The version of the bundle relevant to the event. The type of the value
+	 * for this event property is {@link Version}.
+	 * 
+	 * @since 1.2
+	 */
+	public static final String	BUNDLE_VERSION		= "bundle.version";
+
+	/**
+	 * The forwarded event object. Used when rebroadcasting an event that was
+	 * sent via some other event mechanism. The type of the value for this event
+	 * property is <code>Object</code>.
 	 */
 	public static final String	EVENT				= "event";
 
 	/**
-	 * An exception or error.
+	 * An exception or error. The type of the value for this event property is
+	 * <code>Throwable</code>.
 	 */
 	public static final String	EXCEPTION			= "exception";
 
 	/**
-	 * Must be equal to the name of the Exception class.
+	 * The name of the exception type. Must be equal to the name of the class of
+	 * the exception in the event property {@link #EXCEPTION}. The type of the
+	 * value for this event property is <code>String</code>.
 	 * 
 	 * @since 1.1
 	 */
 	public static final String	EXCEPTION_CLASS		= "exception.class";
 
 	/**
-	 * Must be equal to exception.getMessage()
+	 * The exception message. Must be equal to the result of calling
+	 * <code>getMessage()</code> on the exception in the event property
+	 * {@link #EXCEPTION}. The type of the value for this event property is
+	 * <code>String</code>.
 	 */
 	public static final String	EXCEPTION_MESSAGE	= "exception.message";
 
 	/**
-	 * A human-readable message that is usually not localized.
+	 * A human-readable message that is usually not localized. The type of the
+	 * value for this event property is <code>String</code>.
 	 */
 	public static final String	MESSAGE				= "message";
 
 	/**
-	 * A service
+	 * A service reference. The type of the value for this event property is
+	 * {@link ServiceReference}.
 	 */
-
 	public static final String	SERVICE				= "service";
 
 	/**
-	 * A service's id.
+	 * A service's id. The type of the value for this event property is
+	 * <code>Long</code>.
 	 */
 	public static final String	SERVICE_ID			= Constants.SERVICE_ID;
 
 	/**
-	 * 
-	 * A service's objectClass
+	 * A service's objectClass. The type of the value for this event property is
+	 * <code>String[]</code>.
 	 */
 	public static final String	SERVICE_OBJECTCLASS	= "service.objectClass";
 
 	/**
-	 * 
-	 * A service's persistent identity.
+	 * A service's persistent identity. The type of the value for this event
+	 * property is <code>String</code>.
 	 */
 	public static final String	SERVICE_PID			= Constants.SERVICE_PID;
 
 	/**
-	 * 
 	 * The time when the event occurred, as reported by
-	 * System.currentTimeMillis()
+	 * <code>System.currentTimeMillis()</code>. The type of the value for this
+	 * event property is <code>Long</code>.
 	 */
 	public static final String	TIMESTAMP			= "timestamp";
 
 	/**
-	 * This constant was released with an incorrect spelling. It has been
+	 * This constant was released with an incorrectly spelled name. It has been
 	 * replaced by {@link #EXCEPTION_CLASS}
 	 * 
 	 * @deprecated As of 1.1, replaced by EXCEPTION_CLASS
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventHandler.java b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventHandler.java
index 8073796..d25782f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/event/EventHandler.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/EventHandler.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.event/src/org/osgi/service/event/EventHandler.java,v 1.10 2006/07/11 16:43:59 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,43 +21,47 @@
  * 
  * <p>
  * <code>EventHandler</code> objects are registered with the Framework service
- * registry and are notified with an <code>Event</code> object when an
- * event is sent or posted.
+ * registry and are notified with an <code>Event</code> object when an event
+ * is sent or posted.
  * <p>
  * <code>EventHandler</code> objects can inspect the received
  * <code>Event</code> object to determine its topic and properties.
  * 
  * <p>
  * <code>EventHandler</code> objects must be registered with a service
- * property {@link EventConstants#EVENT_TOPIC} whose value is the list of
- * topics in which the event handler is interesed.
+ * property {@link EventConstants#EVENT_TOPIC} whose value is the list of topics
+ * in which the event handler is interested.
  * <p>
  * For example:
  * 
  * <pre>
- * String[] topics = new String[] {EventConstants.EVENT_TOPIC, &quot;com/isv/*&quot;};
+ * String[] topics = new String[] {&quot;com/isv/*&quot;};
  * Hashtable ht = new Hashtable();
- * ht.put(EVENT_TOPIC, topics);
+ * ht.put(EventConstants.EVENT_TOPIC, topics);
  * context.registerService(EventHandler.class.getName(), this, ht);
  * </pre>
- * Event Handler services can also be registered with an {@link EventConstants#EVENT_FILTER}
- * service propery to further filter the events. If the syntax of this filter is invalid,
- * then the Event Handler must be ignored by the Event Admin service. The Event Admin
- * service should log a warning.
+ * 
+ * Event Handler services can also be registered with an
+ * {@link EventConstants#EVENT_FILTER} service property to further filter the
+ * events. If the syntax of this filter is invalid, then the Event Handler must
+ * be ignored by the Event Admin service. The Event Admin service should log a
+ * warning.
  * <p>
  * Security Considerations. Bundles wishing to monitor <code>Event</code>
  * objects will require <code>ServicePermission[EventHandler,REGISTER]</code>
  * to register an <code>EventHandler</code> service. The bundle must also have
- * <code>TopicPermission[topic,SUBSCRIBE]</code> for the topic specified in the
- * event in order to receive the event.
+ * <code>TopicPermission[topic,SUBSCRIBE]</code> for the topic specified in
+ * the event in order to receive the event.
  * 
  * @see Event
  * 
- * @version $Revision: 1.10 $
+ * @ThreadSafe
+ * @version $Revision: 5673 $
  */
 public interface EventHandler {
 	/**
-	 * Called by the {@link EventAdmin} service to notify the listener of an event.
+	 * Called by the {@link EventAdmin} service to notify the listener of an
+	 * event.
 	 * 
 	 * @param event The event that occurred.
 	 */
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/TopicPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/event/TopicPermission.java
index 89591b6..ae0d190 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/event/TopicPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/TopicPermission.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.event/src/org/osgi/service/event/TopicPermission.java,v 1.11 2006/06/16 16:31:48 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2009). 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.
@@ -33,25 +31,26 @@
  * For example:
  * 
  * <pre>
- * org/osgi/service/foo/FooEvent/ACTION
+ * org / osgi / service / foo / FooEvent / ACTION
  * </pre>
  * 
  * <p>
  * <code>TopicPermission</code> has two actions: <code>publish</code> and
  * <code>subscribe</code>.
  * 
- * @version $Revision: 1.11 $
+ * @ThreadSafe
+ * @version $Revision: 6381 $
  */
 public final class TopicPermission extends Permission {
 	static final long			serialVersionUID	= -5855563886961618300L;
 	/**
 	 * The action string <code>publish</code>.
 	 */
-	public final static String	PUBLISH				= "publish";				//$NON-NLS-1$
+	public final static String	PUBLISH				= "publish";
 	/**
 	 * The action string <code>subscribe</code>.
 	 */
-	public final static String	SUBSCRIBE			= "subscribe";				//$NON-NLS-1$
+	public final static String	SUBSCRIBE			= "subscribe";
 	private final static int	ACTION_PUBLISH		= 0x00000001;
 	private final static int	ACTION_SUBSCRIBE	= 0x00000002;
 	private final static int	ACTION_ALL			= ACTION_PUBLISH
@@ -60,19 +59,19 @@
 	/**
 	 * The actions mask.
 	 */
-	private transient int		action_mask			= ACTION_NONE;
+	private transient int		action_mask;
 
 	/**
 	 * prefix if the name is wildcarded.
 	 */
-	private transient String	prefix;
+	private transient volatile String	prefix;
 
 	/**
 	 * The actions in canonical form.
 	 * 
 	 * @serial
 	 */
-	private String				actions				= null;
+	private volatile String		actions				= null;
 
 	/**
 	 * Defines the authority to publich and/or subscribe to a topic within the
@@ -95,11 +94,11 @@
 	 * <p>
 	 * 
 	 * @param name Topic name.
-	 * @param actions <code>publish</code>,<code>subscribe</code>
-	 *        (canonical order).
+	 * @param actions <code>publish</code>,<code>subscribe</code> (canonical
+	 *        order).
 	 */
 	public TopicPermission(String name, String actions) {
-		this(name, getMask(actions));
+		this(name, parseActions(actions));
 	}
 
 	/**
@@ -110,7 +109,7 @@
 	 */
 	TopicPermission(String name, int mask) {
 		super(name);
-		init(name, mask);
+		setTransients(mask);
 	}
 
 	/**
@@ -119,26 +118,39 @@
 	 * @param name topic name
 	 * @param mask action mask
 	 */
-	private void init(String name, int mask) {
+	private synchronized void setTransients(final int mask) {
+		final String name = getName();
 		if ((name == null) || name.length() == 0) {
-			throw new IllegalArgumentException("invalid name"); //$NON-NLS-1$
+			throw new IllegalArgumentException("invalid name");
 		}
 
+		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
+			throw new IllegalArgumentException("invalid action string");
+		}
+		action_mask = mask;
+
 		if (name.equals("*")) {
 			prefix = "";
 		}
-		else
+		else {
 			if (name.endsWith("/*")) {
 				prefix = name.substring(0, name.length() - 1);
 			}
 			else {
 				prefix = null;
 			}
-
-		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
-			throw new IllegalArgumentException("invalid action string"); //$NON-NLS-1$
 		}
-		action_mask = mask;
+	}
+
+	/**
+	 * Returns the current action mask.
+	 * <p>
+	 * Used by the TopicPermissionCollection class.
+	 * 
+	 * @return Current action mask.
+	 */
+	synchronized int getActionsMask() {
+		return action_mask;
 	}
 
 	/**
@@ -147,7 +159,7 @@
 	 * @param actions Action string.
 	 * @return action mask.
 	 */
-	private static int getMask(String actions) {
+	private static int parseActions(final String actions) {
 		boolean seencomma = false;
 		int mask = ACTION_NONE;
 		if (actions == null) {
@@ -191,7 +203,7 @@
 				}
 				else {
 					// parse error
-					throw new IllegalArgumentException("invalid permission: " //$NON-NLS-1$
+					throw new IllegalArgumentException("invalid permission: "
 							+ actions);
 				}
 			// make sure we didn't just match the tail of a word
@@ -201,7 +213,7 @@
 				switch (a[i - matchlen]) {
 					case ',' :
 						seencomma = true;
-					/* FALLTHROUGH */
+						/* FALLTHROUGH */
 					case ' ' :
 					case '\r' :
 					case '\n' :
@@ -210,7 +222,7 @@
 						break;
 					default :
 						throw new IllegalArgumentException(
-								"invalid permission: " + actions); //$NON-NLS-1$
+								"invalid permission: " + actions);
 				}
 				i--;
 			}
@@ -218,7 +230,7 @@
 			i -= matchlen;
 		}
 		if (seencomma) {
-			throw new IllegalArgumentException("invalid permission: " + actions); //$NON-NLS-1$
+			throw new IllegalArgumentException("invalid permission: " + actions);
 		}
 		return mask;
 	}
@@ -245,13 +257,16 @@
 	 */
 	public boolean implies(Permission p) {
 		if (p instanceof TopicPermission) {
-			TopicPermission target = (TopicPermission) p;
-			if ((action_mask & target.action_mask) == target.action_mask) {
-				if (prefix != null) {
-					return target.getName().startsWith(prefix);
+			TopicPermission requested = (TopicPermission) p;
+			int requestedMask = requested.getActionsMask();
+			if ((getActionsMask() & requestedMask) == requestedMask) {
+				String requestedName = requested.getName();
+				String pre = prefix;
+				if (pre != null) {
+					return requestedName.startsWith(pre);
 				}
 
-				return target.getName().equals(getName());
+				return requestedName.equals(getName());
 			}
 		}
 		return false;
@@ -269,21 +284,23 @@
 	 *         <code>TopicPermission</code> actions.
 	 */
 	public String getActions() {
-		if (actions == null) {
+		String result = actions;
+		if (result == null) {
 			StringBuffer sb = new StringBuffer();
 			boolean comma = false;
-			if ((action_mask & ACTION_PUBLISH) == ACTION_PUBLISH) {
+			int mask = getActionsMask();
+			if ((mask & ACTION_PUBLISH) == ACTION_PUBLISH) {
 				sb.append(PUBLISH);
 				comma = true;
 			}
-			if ((action_mask & ACTION_SUBSCRIBE) == ACTION_SUBSCRIBE) {
+			if ((mask & ACTION_SUBSCRIBE) == ACTION_SUBSCRIBE) {
 				if (comma)
 					sb.append(',');
 				sb.append(SUBSCRIBE);
 			}
-			actions = sb.toString();
+			actions = result = sb.toString();
 		}
-		return actions;
+		return result;
 	}
 
 	/**
@@ -299,9 +316,8 @@
 	/**
 	 * Determines the equality of two <code>TopicPermission</code> objects.
 	 * 
-	 * This method checks that specified <code>TopicPermission</code> has the same topic name and
-	 * actions as this
-	 * <code>TopicPermission</code> object.
+	 * This method checks that specified <code>TopicPermission</code> has the
+	 * same topic name and actions as this <code>TopicPermission</code> object.
 	 * 
 	 * @param obj The object to test for equality with this
 	 *        <code>TopicPermission</code> object.
@@ -317,8 +333,9 @@
 		if (!(obj instanceof TopicPermission)) {
 			return false;
 		}
-		TopicPermission p = (TopicPermission) obj;
-		return (action_mask == p.action_mask) && getName().equals(p.getName());
+		TopicPermission tp = (TopicPermission) obj;
+		return (getActionsMask() == tp.getActionsMask())
+				&& getName().equals(tp.getName());
 	}
 
 	/**
@@ -327,18 +344,9 @@
 	 * @return A hash code value for this object.
 	 */
 	public int hashCode() {
-		return getName().hashCode() ^ getActions().hashCode();
-	}
-
-	/**
-	 * Returns the current action mask.
-	 * <p>
-	 * Used by the TopicPermissionCollection class.
-	 * 
-	 * @return Current action mask.
-	 */
-	int getMask() {
-		return action_mask;
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		return h;
 	}
 
 	/**
@@ -363,7 +371,7 @@
 			throws IOException, ClassNotFoundException {
 		// Read in the action, then initialize the rest
 		s.defaultReadObject();
-		init(getName(), getMask(actions));
+		setTransients(parseActions(actions));
 	}
 }
 
@@ -375,19 +383,21 @@
  * @see java.security.PermissionCollection
  */
 final class TopicPermissionCollection extends PermissionCollection {
-	static final long	serialVersionUID	= -614647783533924048L;
+	static final long		serialVersionUID	= -614647783533924048L;
 	/**
 	 * Table of permissions.
 	 * 
 	 * @serial
+	 * @GuardedBy this
 	 */
-	private Hashtable	permissions;
+	private final Hashtable	permissions;
 	/**
 	 * Boolean saying if "*" is in the collection.
 	 * 
 	 * @serial
+	 * @GuardedBy this
 	 */
-	private boolean		all_allowed;
+	private boolean			all_allowed;
 
 	/**
 	 * Create an empty TopicPermissions object.
@@ -405,36 +415,41 @@
 	 * @param permission The <code>TopicPermission</code> object to add.
 	 * 
 	 * @throws IllegalArgumentException If the permission is not a
-	 *            <code>TopicPermission</code> instance.
+	 *         <code>TopicPermission</code> instance.
 	 * 
-	 * @throws SecurityException If this
-	 *            <code>TopicPermissionCollection</code> object has been
-	 *            marked read-only.
+	 * @throws SecurityException If this <code>TopicPermissionCollection</code>
+	 *         object has been marked read-only.
 	 */
-	public void add(Permission permission) {
-		if (!(permission instanceof TopicPermission))
-			throw new IllegalArgumentException("invalid permission: " //$NON-NLS-1$
+	public void add(final Permission permission) {
+		if (!(permission instanceof TopicPermission)) {
+			throw new IllegalArgumentException("invalid permission: "
 					+ permission);
-		if (isReadOnly())
-			throw new SecurityException("attempt to add a Permission to a " //$NON-NLS-1$
-					+ "readonly PermissionCollection"); //$NON-NLS-1$
-		TopicPermission pp = (TopicPermission) permission;
-		String name = pp.getName();
-		TopicPermission existing = (TopicPermission) permissions.get(name);
-		if (existing != null) {
-			int oldMask = existing.getMask();
-			int newMask = pp.getMask();
-			if (oldMask != newMask) {
-				permissions.put(name, new TopicPermission(name, oldMask
-						| newMask));
+		}
+		if (isReadOnly()) {
+			throw new SecurityException("attempt to add a Permission to a "
+					+ "readonly PermissionCollection");
+		}
+		final TopicPermission tp = (TopicPermission) permission;
+		final String name = tp.getName();
+		final int newMask = tp.getActionsMask();
+
+		synchronized (this) {
+			final TopicPermission existing = (TopicPermission) permissions
+					.get(name);
+			if (existing != null) {
+				final int oldMask = existing.getActionsMask();
+				if (oldMask != newMask) {
+					permissions.put(name, new TopicPermission(name, oldMask
+							| newMask));
+				}
 			}
-		}
-		else {
-			permissions.put(name, permission);
-		}
-		if (!all_allowed) {
-			if (name.equals("*")) //$NON-NLS-1$
-				all_allowed = true;
+			else {
+				permissions.put(name, tp);
+			}
+			if (!all_allowed) {
+				if (name.equals("*"))
+					all_allowed = true;
+			}
 		}
 	}
 
@@ -445,47 +460,55 @@
 	 * @param permission The Permission object to compare with this
 	 *        <code>TopicPermission</code> object.
 	 * 
-	 * @return <code>true</code> if <code>permission</code> is a proper
-	 *         subset of a permission in the set; <code>false</code>
-	 *         otherwise.
+	 * @return <code>true</code> if <code>permission</code> is a proper subset
+	 *         of a permission in the set; <code>false</code> otherwise.
 	 */
-	public boolean implies(Permission permission) {
-		if (!(permission instanceof TopicPermission))
+	public boolean implies(final Permission permission) {
+		if (!(permission instanceof TopicPermission)) {
 			return false;
-		TopicPermission pp = (TopicPermission) permission;
-		TopicPermission x;
-		int desired = pp.getMask();
+		}
+		final TopicPermission requested = (TopicPermission) permission;
+		String name = requested.getName();
+		final int desired = requested.getActionsMask();
 		int effective = 0;
+
+		TopicPermission x;
 		// short circuit if the "*" Permission was added
-		if (all_allowed) {
-			x = (TopicPermission) permissions.get("*"); //$NON-NLS-1$
-			if (x != null) {
-				effective |= x.getMask();
-				if ((effective & desired) == desired)
-					return true;
+		synchronized (this) {
+			if (all_allowed) {
+				x = (TopicPermission) permissions.get("*");
+				if (x != null) {
+					effective |= x.getActionsMask();
+					if ((effective & desired) == desired) {
+						return true;
+					}
+				}
 			}
+			x = (TopicPermission) permissions.get(name);
 		}
 		// strategy:
 		// Check for full match first. Then work our way up the
 		// name looking for matches on a/b/*
-		String name = pp.getName();
-		x = (TopicPermission) permissions.get(name);
 		if (x != null) {
 			// we have a direct hit!
-			effective |= x.getMask();
-			if ((effective & desired) == desired)
+			effective |= x.getActionsMask();
+			if ((effective & desired) == desired) {
 				return true;
+			}
 		}
 		// work our way up the tree...
-		int last, offset;
-		offset = name.length() - 1;
-		while ((last = name.lastIndexOf("/", offset)) != -1) { //$NON-NLS-1$
-			name = name.substring(0, last + 1) + "*"; //$NON-NLS-1$
-			x = (TopicPermission) permissions.get(name);
+		int last;
+		int offset = name.length() - 1;
+		while ((last = name.lastIndexOf("/", offset)) != -1) {
+			name = name.substring(0, last + 1) + "*";
+			synchronized (this) {
+				x = (TopicPermission) permissions.get(name);
+			}
 			if (x != null) {
-				effective |= x.getMask();
-				if ((effective & desired) == desired)
+				effective |= x.getActionsMask();
+				if ((effective & desired) == desired) {
 					return true;
+				}
 			}
 			offset = last - 1;
 		}
@@ -495,8 +518,8 @@
 	}
 
 	/**
-	 * Returns an enumeration of all <code>TopicPermission</code> objects in
-	 * the container.
+	 * Returns an enumeration of all <code>TopicPermission</code> objects in the
+	 * container.
 	 * 
 	 * @return Enumeration of all <code>TopicPermission</code> objects.
 	 */
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/event/package.html
new file mode 100644
index 0000000..0d9d0bf
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Event Admin Package Version 1.2.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.event; version=&quot;[1.2,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/event/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/event/packageinfo
new file mode 100644
index 0000000..ef7df68
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/event/packageinfo
@@ -0,0 +1 @@
+version 1.2
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpContext.java b/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpContext.java
index abeb95b..e39cd17 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpContext.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpContext.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.http/src/org/osgi/service/http/HttpContext.java,v 1.12 2006/07/12 21:22:13 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). 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.
@@ -37,7 +35,7 @@
  * <p>
  * This interface is implemented by users of the <code>HttpService</code>.
  * 
- * @version $Revision: 1.12 $
+ * @version $Revision: 5673 $
  */
 public interface HttpContext {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpService.java b/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpService.java
index 2047328..c578a93 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/http/HttpService.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.http/src/org/osgi/service/http/HttpService.java,v 1.13 2006/07/12 21:22:13 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). 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.
@@ -27,7 +25,7 @@
  * register resources and servlets into the URI namespace of Http Service. A
  * bundle may later unregister its resources or servlets.
  * 
- * @version $Revision: 1.13 $
+ * @version $Revision: 5673 $
  * @see HttpContext
  */
 public interface HttpService {
@@ -90,9 +88,10 @@
 	 * the registration will be mapped. An alias must begin with slash ('/') and
 	 * must not end with slash ('/'), with the exception that an alias of the
 	 * form &quot;/&quot; is used to denote the root alias. The name parameter
-	 * must also not end with slash ('/'). See the specification text for
-	 * details on how HTTP requests are mapped to servlet and resource
-	 * registrations.
+	 * must also not end with slash ('/') with the exception that a name of the
+	 * form &quot;/&quot; is used to denote the root of the bundle. See the
+	 * specification text for details on how HTTP requests are mapped to servlet
+	 * and resource registrations.
 	 * <p>
 	 * For example, suppose the resource name /tmp is registered to the alias
 	 * /files. A request for /files/foo.txt will map to the resource name
@@ -104,20 +103,20 @@
 	 * 
 	 * The Http Service will call the <code>HttpContext</code> argument to map
 	 * resource names to URLs and MIME types and to handle security for
-	 * requests. If the <code>HttpContext</code> argument is <code>null</code>, a
-	 * default <code>HttpContext</code> is used (see
+	 * requests. If the <code>HttpContext</code> argument is <code>null</code>,
+	 * a default <code>HttpContext</code> is used (see
 	 * {@link #createDefaultHttpContext}).
 	 * 
 	 * @param alias name in the URI namespace at which the resources are
 	 *        registered
 	 * @param name the base name of the resources that will be registered
 	 * @param context the <code>HttpContext</code> object for the registered
-	 *        resources, or <code>null</code> if a default <code>HttpContext</code>
-	 *        is to be created and used.
-	 * @throws NamespaceException if the registration fails because the alias
-	 *            is already in use.
-	 * @throws java.lang.IllegalArgumentException if any of the parameters
-	 *            are invalid
+	 *        resources, or <code>null</code> if a default
+	 *        <code>HttpContext</code> is to be created and used.
+	 * @throws NamespaceException if the registration fails because the alias is
+	 *         already in use.
+	 * @throws java.lang.IllegalArgumentException if any of the parameters are
+	 *         invalid
 	 */
 	public void registerResources(String alias, String name,
 			HttpContext context) throws NamespaceException;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/http/NamespaceException.java b/org.osgi.compendium/src/main/java/org/osgi/service/http/NamespaceException.java
index 478d2ea..dce2ba8 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/http/NamespaceException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/http/NamespaceException.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.http/src/org/osgi/service/http/NamespaceException.java,v 1.11 2006/07/11 13:15:56 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,15 +20,11 @@
  * to register a servlet or resources into the URI namespace of the Http
  * Service. This exception indicates that the requested alias already is in use.
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 6083 $
  */
 public class NamespaceException extends Exception {
     static final long serialVersionUID = 7235606031147877747L;
-	/**
-	 * Nested exception.
-	 */
-	private final Throwable	cause;
-
+    
 	/**
 	 * Construct a <code>NamespaceException</code> object with a detail message.
 	 * 
@@ -38,7 +32,6 @@
 	 */
 	public NamespaceException(String message) {
 		super(message);
-		cause = null;
 	}
 
 	/**
@@ -49,47 +42,47 @@
 	 * @param cause The nested exception.
 	 */
 	public NamespaceException(String message, Throwable cause) {
-		super(message);
-		this.cause = cause;
+		super(message, cause);
 	}
 
 	/**
 	 * Returns the nested exception.
-	 *
-     * <p>This method predates the general purpose exception chaining mechanism.
-     * The {@link #getCause()} method is now the preferred means of
-     * obtaining this information.
 	 * 
-	 * @return the nested exception or <code>null</code> if there is no nested
-	 *         exception.
+	 * <p>
+	 * This method predates the general purpose exception chaining mechanism.
+	 * The <code>getCause()</code> method is now the preferred means of
+	 * obtaining this information.
+	 * 
+	 * @return The result of calling <code>getCause()</code>.
 	 */
 	public Throwable getException() {
-		return cause;
+		return getCause();
 	}
-
+	
 	/**
-	 * Returns the cause of this exception or <code>null</code> if no
-	 * cause was specified when this exception was created.
-	 *
-	 * @return  The cause of this exception or <code>null</code> if no
-	 * cause was specified.
-	 * @since 1.2 
+	 * Returns the cause of this exception or <code>null</code> if no cause was
+	 * set.
+	 * 
+	 * @return The cause of this exception or <code>null</code> if no cause was
+	 *         set.
+	 * @since 1.2
 	 */
 	public Throwable getCause() {
-	    return cause;
+		return super.getCause();
 	}
 
 	/**
-	 * The cause of this exception can only be set when constructed.
-	 *
-	 * @param cause Cause of the exception.
-	 * @return This object.
-	 * @throws java.lang.IllegalStateException
-	 * This method will always throw an <code>IllegalStateException</code>
-	 * since the cause of this exception can only be set when constructed.
-	 * @since 1.2 
+	 * Initializes the cause of this exception to the specified value.
+	 * 
+	 * @param cause The cause of this exception.
+	 * @return This exception.
+	 * @throws IllegalArgumentException If the specified cause is this
+	 *         exception.
+	 * @throws IllegalStateException If the cause of this exception has already
+	 *         been set.
+	 * @since 1.2
 	 */
 	public Throwable initCause(Throwable cause) {
-		throw new IllegalStateException();
+		return super.initCause(cause);
 	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/http/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/http/package.html
new file mode 100644
index 0000000..21f5fed
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/http/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Http Service Package Version 1.2.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.http; version=&quot;[1.2,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/http/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/http/packageinfo
new file mode 100644
index 0000000..6ebb891
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/http/packageinfo
@@ -0,0 +1 @@
+version 1.2.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectionFactory.java b/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectionFactory.java
index 03f812e..3939512 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectionFactory.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectionFactory.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.io/src/org/osgi/service/io/ConnectionFactory.java,v 1.9 2006/07/12 21:22:12 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -34,7 +32,7 @@
  * Factory will then be called to create the actual <code>Connection</code>
  * object.
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 7337 $
  */
 public interface ConnectionFactory {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectorService.java b/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectorService.java
index 45d1f87..dbfc04a 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectorService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/io/ConnectorService.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.io/src/org/osgi/service/io/ConnectorService.java,v 1.9 2006/07/12 21:22:12 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -42,7 +40,7 @@
  * first, is called. This is the same algorithm used by
  * <code>BundleContext.getServiceReference</code>.
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
  */
 public interface ConnectorService {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/io/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/io/package.html
new file mode 100644
index 0000000..cecc3c3
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/io/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>IO Connector Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.io; version=&quot;[1.0,2.0)&quot;, javax.microedition.io
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/io/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/io/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/io/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogEntry.java b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogEntry.java
index 12e6c8d..8130cf8 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogEntry.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogEntry.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogEntry.java,v 1.9 2006/06/16 16:31:49 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,7 +27,8 @@
  * <code>LogReaderService.getLog</code> method or by registering a
  * <code>LogListener</code> object.
  * 
- * @version $Revision: 1.9 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
  * @see LogReaderService#getLog
  * @see LogListener
  */
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogListener.java
index 3731c28..de29a56 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogListener.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogListener.java,v 1.9 2006/06/16 16:31:49 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). 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,7 +28,8 @@
  * unregistered by calling the <code>LogReaderService.removeLogListener</code>
  * method.
  * 
- * @version $Revision: 1.9 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
  * @see LogReaderService
  * @see LogEntry
  * @see LogReaderService#addLogListener(LogListener)
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogReaderService.java b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogReaderService.java
index 4176ebc..b3753e4 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogReaderService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogReaderService.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogReaderService.java,v 1.10 2006/06/16 16:31:49 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). 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 +29,8 @@
  * method can be called which will return an <code>Enumeration</code> of all
  * <code>LogEntry</code> objects in the log.
  * 
- * @version $Revision: 1.10 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
  * @see LogEntry
  * @see LogListener
  * @see LogListener#logged(LogEntry)
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogService.java b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogService.java
index 4858c58..1889355 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/log/LogService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/LogService.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.log/src/org/osgi/service/log/LogService.java,v 1.9 2006/06/16 16:31:49 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2000, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). 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.
@@ -36,7 +34,8 @@
  * <li>{@link #LOG_DEBUG}
  * </ol>
  * 
- * @version $Revision: 1.9 $
+ * @ThreadSafe
+ * @version $Revision: 5654 $
  */
 public interface LogService {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/log/package.html
new file mode 100644
index 0000000..02312bb
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Log Service Package Version 1.3.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.log; version=&quot;[1.3,2.0)&quot;
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/log/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/log/packageinfo
new file mode 100644
index 0000000..0117a56
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/log/packageinfo
@@ -0,0 +1 @@
+version 1.3
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/AttributeDefinition.java b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/AttributeDefinition.java
index 3f3f053..d427163 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/AttributeDefinition.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/AttributeDefinition.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.metatype/src/org/osgi/service/metatype/AttributeDefinition.java,v 1.13 2006/06/16 16:31:23 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -24,7 +22,7 @@
  * An <code>AttributeDefinition</code> object defines a description of the data
  * type of a property/attribute.
  * 
- * @version $Revision: 1.13 $
+ * @version $Revision: 5673 $
  */
 public interface AttributeDefinition {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeInformation.java b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeInformation.java
index ce544e3..8b336dc 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeInformation.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeInformation.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.metatype/src/org/osgi/service/metatype/MetaTypeInformation.java,v 1.8 2006/06/16 16:31:23 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,7 +21,7 @@
  * A MetaType Information object is created by the MetaTypeService to return
  * meta type information for a specific bundle.
  * 
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
  * @since 1.1
  */
 public interface MetaTypeInformation extends MetaTypeProvider {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeProvider.java b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeProvider.java
index a21f617..b2385b2 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeProvider.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeProvider.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.metatype/src/org/osgi/service/metatype/MetaTypeProvider.java,v 1.11 2006/06/16 16:31:23 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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,7 +18,7 @@
 /**
  * Provides access to metatypes.
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
  */
 public interface MetaTypeProvider {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeService.java b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeService.java
index ea1b1b2..d8f77a3 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/MetaTypeService.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.metatype/src/org/osgi/service/metatype/MetaTypeService.java,v 1.10 2006/06/16 16:31:23 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
@@ -33,7 +31,7 @@
  * retrieve meta type information for bundles which contain a meta type
  * documents or which provide their own <code>MetaTypeProvider</code> objects.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  * @since 1.1
  */
 public interface MetaTypeService {
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/ObjectClassDefinition.java b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/ObjectClassDefinition.java
index 754b636..5c6687e 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/ObjectClassDefinition.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/ObjectClassDefinition.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.metatype/src/org/osgi/service/metatype/ObjectClassDefinition.java,v 1.11 2006/06/16 16:31:23 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,7 +21,7 @@
 /**
  * Description for the data type information of an objectclass.
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
  */
 public interface ObjectClassDefinition {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/package.html
new file mode 100644
index 0000000..0b2b533
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Metatype Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.metatype; version=&quot;[1.1,2.0)&quot;
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/metatype/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/metatype/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorAdmin.java
index c9377c8..6ab860e 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorAdmin.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/MonitorAdmin.java,v 1.25 2006/06/16 16:31:25 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,14 +27,14 @@
  * <code>Monitorable</code> services from the service registry and then query
  * the list of <code>StatusVariable</code> names from the
  * <code>Monitorable</code> services. This way all services which publish
- * <code>StatusVariable</code>s will be returned regardless of whether they
- * do or do not hold the necessary <code>MonitorPermission</code> for
- * publishing <code>StatusVariable</code>s. By using the
- * <code>MonitorAdmin</code> to obtain the <code>StatusVariable</code>s it
- * is guaranteed that only those <code>Monitorable</code> services will be
- * accessed who are authorized to publish <code>StatusVariable</code>s. It is
- * the responsibility of the <code>MonitorAdmin</code> implementation to check
- * the required permissions and show only those variables which pass this check.
+ * <code>StatusVariable</code>s will be returned regardless of whether they do
+ * or do not hold the necessary <code>MonitorPermission</code> for publishing
+ * <code>StatusVariable</code>s. By using the <code>MonitorAdmin</code> to
+ * obtain the <code>StatusVariable</code>s it is guaranteed that only those
+ * <code>Monitorable</code> services will be accessed who are authorized to
+ * publish <code>StatusVariable</code>s. It is the responsibility of the
+ * <code>MonitorAdmin</code> implementation to check the required permissions
+ * and show only those variables which pass this check.
  * <p>
  * The events posted by <code>MonitorAdmin</code> contain the following
  * properties:
@@ -53,11 +51,13 @@
  * </ul>
  * <p>
  * Most of the methods require either a Monitorable ID or a Status Variable path
- * parameter, the latter in [Monitorable_ID]/[StatusVariable_ID] format.  These
+ * parameter, the latter in [Monitorable_ID]/[StatusVariable_ID] format. These
  * parameters must not be <code>null</code>, and the IDs they contain must
  * conform to their respective definitions in {@link Monitorable} and
- * {@link StatusVariable}.  If any of the restrictions are violated, the method
+ * {@link StatusVariable}. If any of the restrictions are violated, the method
  * must throw an <code>IllegalArgumentException</code>.
+ * 
+ * @version $Revision: 5673 $
  */
 public interface MonitorAdmin {
 
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorListener.java
index 44fa845..694bcd7 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorListener.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/MonitorListener.java,v 1.11 2006/06/16 16:31:25 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). 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,11 +17,13 @@
 package org.osgi.service.monitor;
 
 /**
- * The <code>MonitorListener</code> is used by <code>Monitorable</code>
- * services to send notifications when a <code>StatusVariable</code> value is
- * changed. The <code>MonitorListener</code> should register itself as a
- * service at the OSGi Service Registry. This interface must (only) be 
- * implemented by the Monitor Admin component.
+ * The <code>MonitorListener</code> is used by <code>Monitorable</code> services
+ * to send notifications when a <code>StatusVariable</code> value is changed.
+ * The <code>MonitorListener</code> should register itself as a service at the
+ * OSGi Service Registry. This interface must (only) be implemented by the
+ * Monitor Admin component.
+ * 
+ * @version $Revision: 5673 $
  */
 public interface MonitorListener {
     /**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorPermission.java
index b0ca12d..c02797e 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitorPermission.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/MonitorPermission.java,v 1.17 2006/06/21 15:17:16 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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.
@@ -24,18 +22,20 @@
 
 /**
  * Indicates the callers authority to publish, read or reset
- * <code>StatusVariable</code>s, to switch event sending on or off or to
- * start monitoring jobs. The target of the permission is the identifier of the
+ * <code>StatusVariable</code>s, to switch event sending on or off or to start
+ * monitoring jobs. The target of the permission is the identifier of the
  * <code>StatusVariable</code>, the action can be <code>read</code>,
  * <code>publish</code>, <code>reset</code>, <code>startjob</code>,
- * <code>switchevents</code>, or the combination of these separated by
- * commas.  Action names are interpreted case-insensitively, but the canonical 
- * action string returned by {@link #getActions} uses the forms defined by the 
- * action constants.
+ * <code>switchevents</code>, or the combination of these separated by commas.
+ * Action names are interpreted case-insensitively, but the canonical action
+ * string returned by {@link #getActions} uses the forms defined by the action
+ * constants.
  * <p>
- * If the wildcard <code>*</code> appears in the actions field, all legal 
- * monitoring commands are allowed on the designated target(s) by the owner of 
+ * If the wildcard <code>*</code> appears in the actions field, all legal
+ * monitoring commands are allowed on the designated target(s) by the owner of
  * the permission.
+ * 
+ * @version $Revision: 5673 $
  */
 public class MonitorPermission extends Permission {
 
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/Monitorable.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/Monitorable.java
index 8203ddd..5fceb98 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/Monitorable.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/Monitorable.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/Monitorable.java,v 1.17 2006/06/16 16:31:25 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). 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,11 +18,11 @@
 
 /**
  * A <code>Monitorable</code> can provide information about itself in the form
- * of <code>StatusVariables</code>. Instances of this interface should
- * register themselves at the OSGi Service Registry. The
- * <code>MonitorAdmin</code> listens to the registration of
- * <code>Monitorable</code> services, and makes the information they provide
- * available also through the Device Management Tree (DMT) for remote access.
+ * of <code>StatusVariables</code>. Instances of this interface should register
+ * themselves at the OSGi Service Registry. The <code>MonitorAdmin</code>
+ * listens to the registration of <code>Monitorable</code> services, and makes
+ * the information they provide available also through the Device Management
+ * Tree (DMT) for remote access.
  * <p>
  * The monitorable service is identified by its PID string which must be a non-
  * <code>null</code>, non-empty string that conforms to the "symbolic-name"
@@ -32,17 +30,19 @@
  * characters [-_.a-zA-Z0-9] may be used. The length of the PID must not exceed
  * 20 characters.
  * <p>
- * A <code>Monitorable</code> may optionally support sending notifications
- * when the status of its <code>StatusVariables</code> change. Support for
- * change notifications can be defined per <code>StatusVariable</code>.
+ * A <code>Monitorable</code> may optionally support sending notifications when
+ * the status of its <code>StatusVariables</code> change. Support for change
+ * notifications can be defined per <code>StatusVariable</code>.
  * <p>
  * Publishing <code>StatusVariables</code> requires the presence of the
- * <code>MonitorPermission</code> with the <code>publish</code> action
- * string. This permission, however, is not checked during registration of the
+ * <code>MonitorPermission</code> with the <code>publish</code> action string.
+ * This permission, however, is not checked during registration of the
  * <code>Monitorable</code> service. Instead, the <code>MonitorAdmin</code>
  * implemenatation must make sure that when a <code>StatusVariable</code> is
  * queried, it is shown only if the <code>Monitorable</code> is authorized to
  * publish the given <code>StatusVariable</code>.
+ * 
+ * @version $Revision: 5673 $
  */
 public interface Monitorable {
     /**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitoringJob.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitoringJob.java
index 75b9d2e..43d3bf2 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitoringJob.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/MonitoringJob.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/MonitoringJob.java,v 1.14 2006/06/16 16:31:25 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). 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,28 +18,29 @@
 
 /**
  * A Monitoring Job is a request for scheduled or event based notifications on
- * update of a set of <code>StatusVariable</code>s. The job is a data
- * structure that holds a non-empty list of <code>StatusVariable</code> names,
- * an identification of the initiator of the job, and the sampling parameters.
+ * update of a set of <code>StatusVariable</code>s. The job is a data structure
+ * that holds a non-empty list of <code>StatusVariable</code> names, an
+ * identification of the initiator of the job, and the sampling parameters.
  * There are two kinds of monitoring jobs: time based and change based. Time
- * based jobs take samples of all <code>StatusVariable</code>s with a
- * specified frequency. The number of samples to be taken before the job
- * finishes may be specified. Change based jobs are only interested in the
- * changes of the monitored <code>StatusVariable</code>s. In this case, the
- * number of changes that must take place between two notifications can be
- * specified.
+ * based jobs take samples of all <code>StatusVariable</code>s with a specified
+ * frequency. The number of samples to be taken before the job finishes may be
+ * specified. Change based jobs are only interested in the changes of the
+ * monitored <code>StatusVariable</code>s. In this case, the number of changes
+ * that must take place between two notifications can be specified.
  * <p>
  * The job can be started on the <code>MonitorAdmin</code> interface. Running
- * the job (querying the <code>StatusVariable</code>s, listening to changes,
- * and sending out notifications on updates) is the task of the
+ * the job (querying the <code>StatusVariable</code>s, listening to changes, and
+ * sending out notifications on updates) is the task of the
  * <code>MonitorAdmin</code> implementation.
  * <p>
  * Whether a monitoring job keeps track dynamically of the
- * <code>StatusVariable</code>s it monitors is not specified. This means that
- * if we monitor a <code>StatusVariable</code> of a <code>Monitorable</code>
+ * <code>StatusVariable</code>s it monitors is not specified. This means that if
+ * we monitor a <code>StatusVariable</code> of a <code>Monitorable</code>
  * service which disappears and later reappears then it is implementation
  * specific whether we still receive updates of the <code>StatusVariable</code>
  * changes or not.
+ * 
+ * @version $Revision: 5673 $
  */
 public interface MonitoringJob {
     /**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/StatusVariable.java b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/StatusVariable.java
index 74ff9df..927e7ec 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/StatusVariable.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/StatusVariable.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.monitor/src/org/osgi/service/monitor/StatusVariable.java,v 1.14 2006/06/16 16:31:25 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). 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.
@@ -33,6 +31,8 @@
  * definition in the OSGi core specification. This means that only the
  * characters [-_.a-zA-Z0-9] may be used. The length of the ID must not exceed
  * 32 bytes when UTF-8 encoded.
+ * 
+ * @version $Revision: 5673 $
  */
 public final class StatusVariable {
     //----- Public constants -----//
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/package.html
new file mode 100644
index 0000000..5350310
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Monitor Admin Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.monitor; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/monitor/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/monitor/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/BackingStoreException.java b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/BackingStoreException.java
index 7a182d7..0f15919 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/BackingStoreException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/BackingStoreException.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.prefs/src/org/osgi/service/prefs/BackingStoreException.java,v 1.12 2006/07/11 13:15:55 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,63 +19,57 @@
  * Thrown to indicate that a preferences operation could not complete because of
  * a failure in the backing store, or a failure to contact the backing store.
  * 
- * @version $Revision: 1.12 $
+ * @version $Revision: 6083 $
  */
 public class BackingStoreException extends Exception {
     static final long serialVersionUID = -1415637364122829574L;
-	/**
-	 * Nested exception.
-	 */
-	private final Throwable	cause;
 
 	/**
 	 * Constructs a <code>BackingStoreException</code> with the specified detail
 	 * message.
 	 * 
-	 * @param s The detail message.
+	 * @param message The detail message.
 	 */
-	public BackingStoreException(String s) {
-		super(s);
-		this.cause = null;
+	public BackingStoreException(String message) {
+		super(message);
 	}
 	
 	/**
 	 * Constructs a <code>BackingStoreException</code> with the specified detail
 	 * message.
 	 * 
-	 * @param s The detail message.
+	 * @param message The detail message.
 	 * @param cause The cause of the exception. May be <code>null</code>.
 	 * @since 1.1 
 	 */
-	public BackingStoreException(String s, Throwable cause) {
-		super(s);
-		this.cause = cause;
+	public BackingStoreException(String message, Throwable cause) {
+		super(message, cause);
 	}
-	
+
 	/**
 	 * Returns the cause of this exception or <code>null</code> if no cause was
-	 * specified when this exception was created.
+	 * set.
 	 * 
 	 * @return The cause of this exception or <code>null</code> if no cause was
-	 *         specified.
-	 * @since 1.1 
+	 *         set.
+	 * @since 1.1
 	 */
 	public Throwable getCause() {
-		return cause;
+		return super.getCause();
 	}
 
 	/**
-	 * The cause of this exception can only be set when constructed.
+	 * Initializes the cause of this exception to the specified value.
 	 * 
-	 * @param cause Cause of the exception.
-	 * @return This object.
-	 * @throws java.lang.IllegalStateException This method will always throw an
-	 *         <code>IllegalStateException</code> since the cause of this
-	 *         exception can only be set when constructed.
-	 * @since 1.1 
+	 * @param cause The cause of this exception.
+	 * @return This exception.
+	 * @throws IllegalArgumentException If the specified cause is this
+	 *         exception.
+	 * @throws IllegalStateException If the cause of this exception has already
+	 *         been set.
+	 * @since 1.1
 	 */
 	public Throwable initCause(Throwable cause) {
-		throw new IllegalStateException();
+		return super.initCause(cause);
 	}
-
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/Preferences.java b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/Preferences.java
index c3a6cd0..8ffad3f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/Preferences.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/Preferences.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.prefs/src/org/osgi/service/prefs/Preferences.java,v 1.11 2006/07/11 00:54:04 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -110,7 +108,7 @@
  * preference data.
  * 
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
  */
 public interface Preferences {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/PreferencesService.java b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/PreferencesService.java
index 19c1e34..a9d99a4 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/PreferencesService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/PreferencesService.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.prefs/src/org/osgi/service/prefs/PreferencesService.java,v 1.10 2006/06/16 16:31:30 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/package.html
new file mode 100644
index 0000000..9bbffe2
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Preferences Service Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.prefs; version=&quot;[1.1,2.0)&quot;
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/prefs/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/packageinfo
new file mode 100644
index 0000000..bb27c60
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/prefs/packageinfo
@@ -0,0 +1 @@
+version 1.1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/ProvisioningService.java b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/ProvisioningService.java
index 00ec9e0..5ca31a5 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/ProvisioningService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/ProvisioningService.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.provisioning/src/org/osgi/service/provisioning/ProvisioningService.java,v 1.11 2006/07/12 21:21:31 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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,14 +29,15 @@
  * these bundles to exchange information. It also provides a means for the
  * initial Management Bundle to get its initial configuration information.
  * <p>
- * The provisioning information is collected in a <code>Dictionary</code> object,
- * called the Provisioning Dictionary. Any bundle that can access the service
- * can get a reference to this object and read and update provisioning
- * information. The key of the dictionary is a <code>String</code> object and the
- * value is a <code>String</code> or <code>byte[]</code> object. The single
- * exception is the PROVISIONING_UPDATE_COUNT value which is an Integer. The
- * <code>provisioning</code> prefix is reserved for keys defined by OSGi, other
- * key names may be used for implementation dependent provisioning systems.
+ * The provisioning information is collected in a <code>Dictionary</code>
+ * object, called the Provisioning Dictionary. Any bundle that can access the
+ * service can get a reference to this object and read and update provisioning
+ * information. The key of the dictionary is a <code>String</code> object and
+ * the value is a <code>String</code> or <code>byte[]</code> object. The
+ * single exception is the PROVISIONING_UPDATE_COUNT value which is an Integer.
+ * The <code>provisioning</code> prefix is reserved for keys defined by OSGi,
+ * other key names may be used for implementation dependent provisioning
+ * systems.
  * <p>
  * Any changes to the provisioning information will be reflected immediately in
  * all the dictionary objects obtained from the Provisioning Service.
@@ -54,11 +53,11 @@
  * drastic consequences. Thus, only trusted bundles should be allowed to
  * register and get the Provisioning Service. The <code>ServicePermission</code>
  * is used to limit the bundles that can gain access to the Provisioning
- * Service. There is no check of <code>Permission</code> objects to read or modify
- * the provisioning information, so care must be taken not to leak the
+ * Service. There is no check of <code>Permission</code> objects to read or
+ * modify the provisioning information, so care must be taken not to leak the
  * Provisioning Dictionary received from <code>getInformation</code> method.
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 7347 $
  */
 public interface ProvisioningService {
 	/**
@@ -66,17 +65,20 @@
 	 * Service Platform. The value must be of type <code>String</code>.
 	 */
 	public final static String	PROVISIONING_SPID			= "provisioning.spid";
+
 	/**
 	 * The key to the provisioning information that contains the location of the
 	 * provision data provider. The value must be of type <code>String</code>.
 	 */
 	public final static String	PROVISIONING_REFERENCE		= "provisioning.reference";
+	
 	/**
 	 * The key to the provisioning information that contains the initial
 	 * configuration information of the initial Management Agent. The value will
 	 * be of type <code>byte[]</code>.
 	 */
 	public final static String	PROVISIONING_AGENT_CONFIG	= "provisioning.agent.config";
+	
 	/**
 	 * The key to the provisioning information that contains the update count of
 	 * the info data. Each set of changes to the provisioning information must
@@ -85,39 +87,59 @@
 	 * properties of the ProvisioningService in the service registry.
 	 */
 	public final static String	PROVISIONING_UPDATE_COUNT	= "provisioning.update.count";
+	
 	/**
 	 * The key to the provisioning information that contains the location of the
-	 * bundle to start with <code>AllPermission</code>. The bundle must have be
-	 * previously installed for this entry to have any effect.
+	 * bundle to start with <code>AllPermission</code>. The bundle must have
+	 * be previously installed for this entry to have any effect.
 	 */
 	public final static String	PROVISIONING_START_BUNDLE	= "provisioning.start.bundle";
+	
 	/**
 	 * The key to the provisioning information that contains the root X509
-	 * certificate used to esatblish trust with operator when using HTTPS.
+	 * certificate used to establish trust with operator when using HTTPS.
 	 */
 	public final static String	PROVISIONING_ROOTX509		= "provisioning.rootx509";
+	
 	/**
 	 * The key to the provisioning information that contains the shared secret
 	 * used in conjunction with the RSH protocol.
 	 */
 	public final static String	PROVISIONING_RSH_SECRET		= "provisioning.rsh.secret";
+
 	/**
-	 * MIME type to be stored in the extra field of a <code>ZipEntry</code> object
-	 * for String data.
+	 * MIME type to be stored in the extra field of a <code>ZipEntry</code>
+	 * object for String data.
 	 */
 	public final static String	MIME_STRING					= "text/plain;charset=utf-8";
+
 	/**
-	 * MIME type to be stored in the extra field of a <code>ZipEntry</code> object
-	 * for <code>byte[]</code> data.
+	 * MIME type to be stored stored in the extra field of a
+	 * <code>ZipEntry</code> object for <code>byte[]</code> data.
 	 */
 	public final static String	MIME_BYTE_ARRAY				= "application/octet-stream";
+
 	/**
-	 * MIME type to be stored in the extra field of a <code>ZipEntry</code> object
-	 * for an installable bundle file. Zip entries of this type will be
+	 * MIME type to be stored in the extra field of a <code>ZipEntry</code>
+	 * object for an installable bundle file. Zip entries of this type will be
 	 * installed in the framework, but not started. The entry will also not be
 	 * put into the information dictionary.
 	 */
-	public final static String	MIME_BUNDLE					= "application/x-osgi-bundle";
+	public final static String	MIME_BUNDLE					= "application/vnd.osgi.bundle";
+
+	/**
+	 * Alternative MIME type to be stored in the extra field of a
+	 * <code>ZipEntry</code> object for an installable bundle file. Zip entries
+	 * of this type will be installed in the framework, but not started. The
+	 * entry will also not be put into the information dictionary. This
+	 * alternative entry is only for backward compatibility, new applications
+	 * are recommended to use <code>MIME_BUNDLE</code>, which is an official
+	 * IANA MIME type.
+	 * 
+	 * @since 1.2
+	 */
+	public final static String	MIME_BUNDLE_ALT				= "application/x-osgi-bundle";
+
 	/**
 	 * MIME type to be stored in the extra field of a ZipEntry for a String that
 	 * represents a URL for a bundle. Zip entries of this type will be used to
@@ -127,20 +149,30 @@
 	public final static String	MIME_BUNDLE_URL				= "text/x-osgi-bundle-url";
 
 	/**
+	 * Name of the header that specifies the type information for the ZIP file
+	 * entries.
+	 * 
+	 * @since 1.2
+	 */	
+	public final static String INITIALPROVISIONING_ENTRIES = "InitialProvisioning-Entries";
+	
+	/**
 	 * Returns a reference to the Provisioning Dictionary. Any change operations
 	 * (put and remove) to the dictionary will cause an
-	 * <code>UnsupportedOperationException</code> to be thrown. Changes must be
-	 * done using the <code>setInformation</code> and <code>addInformation</code>
-	 * methods of this service.
+	 * <code>UnsupportedOperationException</code> to be thrown. Changes must
+	 * be done using the <code>setInformation</code> and
+	 * <code>addInformation</code> methods of this service.
+	 * 
 	 * @return A reference to the Provisioning Dictionary.
 	 */
 	public Dictionary getInformation();
 
 	/**
 	 * Replaces the Provisioning Information dictionary with the key/value pairs
-	 * contained in <code>info</code>. Any key/value pairs not in <code>info</code>
-	 * will be removed from the Provisioning Information dictionary. This method
-	 * causes the <code>PROVISIONING_UPDATE_COUNT</code> to be incremented.
+	 * contained in <code>info</code>. Any key/value pairs not in
+	 * <code>info</code> will be removed from the Provisioning Information
+	 * dictionary. This method causes the <code>PROVISIONING_UPDATE_COUNT</code>
+	 * to be incremented.
 	 * 
 	 * @param info the new set of Provisioning Information key/value pairs. Any
 	 *        keys are values that are of an invalid type will be silently
@@ -149,8 +181,8 @@
 	public void setInformation(Dictionary info);
 
 	/**
-	 * Adds the key/value pairs contained in <code>info</code> to the Provisioning
-	 * Information dictionary. This method causes the
+	 * Adds the key/value pairs contained in <code>info</code> to the
+	 * Provisioning Information dictionary. This method causes the
 	 * <code>PROVISIONING_UPDATE_COUNT</code> to be incremented.
 	 * 
 	 * @param info the set of Provisioning Information key/value pairs to add to
@@ -160,22 +192,22 @@
 	public void addInformation(Dictionary info);
 
 	/**
-	 * Processes the <code>ZipInputStream</code> and extracts information to add
-	 * to the Provisioning Information dictionary, as well as, install/update
-	 * and start bundles. This method causes the
+	 * Processes the <code>ZipInputStream</code> and extracts information to
+	 * add to the Provisioning Information dictionary, as well as,
+	 * install/update and start bundles. This method causes the
 	 * <code>PROVISIONING_UPDATE_COUNT</code> to be incremented.
 	 * 
 	 * @param zis the <code>ZipInputStream</code> that will be used to add
 	 *        key/value pairs to the Provisioning Information dictionary and
-	 *        install and start bundles. If a <code>ZipEntry</code> does not have
-	 *        an <code>Extra</code> field that corresponds to one of the four
-	 *        defined MIME types (<code>MIME_STRING</code>,
+	 *        install and start bundles. If a <code>ZipEntry</code> does not
+	 *        have an <code>Extra</code> field that corresponds to one of the
+	 *        four defined MIME types (<code>MIME_STRING</code>,
 	 *        <code>MIME_BYTE_ARRAY</code>,<code>MIME_BUNDLE</code>, and
 	 *        <code>MIME_BUNDLE_URL</code>) in will be silently ignored.
 	 * @throws IOException if an error occurs while processing the
-	 *            ZipInputStream. No additions will be made to the Provisioning
-	 *            Information dictionary and no bundles must be started or
-	 *            installed.
+	 *         ZipInputStream. No additions will be made to the Provisioning
+	 *         Information dictionary and no bundles must be started or
+	 *         installed.
 	 */
 	public void addInformation(ZipInputStream zis) throws IOException;
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/package.html
new file mode 100644
index 0000000..8c28950
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Provisioning Package Version 1.2.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.provisioning; version=&quot;[1.2,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/packageinfo
new file mode 100644
index 0000000..ef7df68
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/provisioning/packageinfo
@@ -0,0 +1 @@
+version 1.2
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPAction.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPAction.java
index 2d16666..742673f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPAction.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPAction.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPAction.java,v 1.10 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -24,7 +22,8 @@
  * 
  * Each UPnP service contains zero or more actions. Each action may have zero or
  * more UPnP state variables as arguments.
- *  
+ * 
+ * @version $Revision: 5673 $
  */
 public interface UPnPAction {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPDevice.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPDevice.java
index 72f017b..24ce178 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPDevice.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPDevice.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPDevice.java,v 1.9 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -36,7 +34,8 @@
  * <p>
  * If an application wants to query for a set of localized property values, it
  * has to use the method <code>UPnPDevice.getDescriptions(String locale)</code>.
- *  
+ * 
+ * @version $Revision: 5673 $
  */
 public interface UPnPDevice {
 	/*
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPEventListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPEventListener.java
index 4c1641c..80d4455 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPEventListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPEventListener.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPEventListener.java,v 1.8 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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,9 +23,9 @@
  * generated by a particular UPnP Device registers a service extending this
  * interface.
  * <p>
- * The notification call from the UPnP Service to any <code>UPnPEventListener</code>
- * object must be done asynchronous with respect to the originator (in a
- * separate thread).
+ * The notification call from the UPnP Service to any
+ * <code>UPnPEventListener</code> object must be done asynchronous with respect
+ * to the originator (in a separate thread).
  * <p>
  * Upon registration of the UPnP Event Listener service with the Framework, the
  * service is notified for each variable which it listens for with an initial
@@ -56,6 +54,8 @@
  * <li><code>UPnPService.ID</code>-- The ID of a specific service to listen for
  * events.</li>
  * </ul>
+ * 
+ * @version $Revision: 5673 $
  */
 public interface UPnPEventListener {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPException.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPException.java
index 61dc481..172c995 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPException.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPException.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPException.java,v 1.14 2006/07/12 21:21:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). 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,12 +15,12 @@
  */
 package org.osgi.service.upnp;
 
-
 /**
  * There are several defined error situations describing UPnP problems while a
  * control point invokes actions to UPnPDevices.
  * 
  * @since 1.1
+ * @version $Revision: 5673 $
  */
 public class UPnPException extends Exception {
 	static final long		serialVersionUID		= -262013318122195146L;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPIcon.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPIcon.java
index 36a3db7..8b99be9 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPIcon.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPIcon.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPIcon.java,v 1.12 2006/07/12 21:21:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -24,6 +22,8 @@
  * A UPnP icon representation.
  * 
  * Each UPnP device can contain zero or more icons.
+ * 
+ * @version $Revision: 5673 $
  */
 public interface UPnPIcon {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPLocalStateVariable.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPLocalStateVariable.java
index bdc0b8a..241fb8a 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPLocalStateVariable.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPLocalStateVariable.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPLocalStateVariable.java,v 1.12 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2005, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2005, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,6 +27,8 @@
  * be queried.
  * 
  * @since 1.1
+ * 
+ * @version $Revision: 5673 $
  */
 public interface UPnPLocalStateVariable extends UPnPStateVariable {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java
index 4eafb32..64b5894 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPService.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPService.java,v 1.8 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,6 +20,8 @@
  * 
  * Each UPnP device contains zero or more services. The UPnP description for a
  * service defines actions, their arguments, and event characteristics.
+ * 
+ * @version $Revision: 5673 $
  */
 public interface UPnPService {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java
index c758c88..27b7241 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/UPnPStateVariable.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.upnp/src/org/osgi/service/upnp/UPnPStateVariable.java,v 1.8 2006/06/16 16:31:46 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,13 +19,15 @@
  * The meta-information of a UPnP state variable as declared in the device's
  * service state table (SST).
  * <p>
- * Method calls to interact with a device (e.g. <code>UPnPAction.invoke(...);</code>)
- * use this class to encapsulate meta information about the input and output
- * arguments.
+ * Method calls to interact with a device (e.g.
+ * <code>UPnPAction.invoke(...);</code>) use this class to encapsulate meta
+ * information about the input and output arguments.
  * <p>
  * The actual values of the arguments are passed as Java objects. The mapping of
  * types from UPnP data types to Java data types is described with the field
  * definitions.
+ * 
+ * @version $Revision: 5673 $
  */
 public interface UPnPStateVariable {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html
new file mode 100644
index 0000000..5422e04
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>UPnP Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.upnp; version=&quot;[1.1,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/upnp/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java
index 618a0f1..94289f7 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Authorization.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Authorization.java,v 1.11 2007/02/07 18:53:08 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2007). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -60,7 +58,7 @@
  * <code>Authorization</code> object), the service explicitly checks that the
  * calling bundle has permission to make the call.
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
  */
 public interface Authorization {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java
index 92671ca..4016a43 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Group.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Group.java,v 1.8 2006/06/16 16:31:41 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -87,7 +85,7 @@
  *  
  * </pre>
  * 
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
  */
 public interface Group extends User {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java
index 72b021b..e33d559 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/Role.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/Role.java,v 1.10 2006/07/11 00:54:01 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -47,7 +45,7 @@
  * <code>UserAdminPermission</code> in the same way that properties for other
  * <code>Role</code> objects are.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface Role {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java
index 9baa0b3..b9103fd 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/User.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/User.java,v 1.9 2006/07/11 00:54:01 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -39,7 +37,7 @@
  * Credentials are <code>Dictionary</code> objects and have semantics that are
  * similar to the properties in the <code>Role</code> class.
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
  */
 public interface User extends Role {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java
index 49248bc..2e4b096 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdmin.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdmin.java,v 1.12 2006/07/12 21:21:33 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -45,7 +43,7 @@
  * <code>Role</code> objects, in which each <code>Role</code> object has a unique
  * name.
  * 
- * @version $Revision: 1.12 $
+ * @version $Revision: 5673 $
  */
 public interface UserAdmin {
 	/**
@@ -74,7 +72,7 @@
 
 	/**
 	 * Removes the <code>Role</code> object with the given name from this User
-	 * Admin service.
+	 * Admin service and all groups it is a member of.
 	 * 
 	 * <p>
 	 * If the <code>Role</code> object was removed, a <code>UserAdminEvent</code>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java
index 0cb16a7..88ef8fb 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminEvent.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminEvent.java,v 1.9 2006/07/11 00:54:01 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -35,7 +33,7 @@
  * @see UserAdmin
  * @see UserAdminListener
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
  */
 public class UserAdminEvent {
 	private ServiceReference	ref;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java
index d0ab85e..a301b92 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminListener.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminListener.java,v 1.8 2006/06/16 16:31:41 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2008). 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.
@@ -32,7 +30,7 @@
  * @see UserAdmin
  * @see UserAdminEvent
  * 
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
  */
 public interface UserAdminListener {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java
index a281a13..52be194 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/UserAdminPermission.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.useradmin/src/org/osgi/service/useradmin/UserAdminPermission.java,v 1.13 2006/07/12 21:21:33 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2001, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2001, 2009). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,7 +16,9 @@
 package org.osgi.service.useradmin;
 
 import java.io.IOException;
-import java.security.*;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
 import java.util.Enumeration;
 import java.util.Hashtable;
 
@@ -27,8 +27,8 @@
  * Admin service.
  * 
  * <p>
- * This class represents access to the <code>Role</code> objects managed by a User
- * Admin service and their properties and credentials (in the case of
+ * This class represents access to the <code>Role</code> objects managed by a
+ * User Admin service and their properties and credentials (in the case of
  * {@link User} objects).
  * <p>
  * The permission name is the name (or name prefix) of a property or credential.
@@ -40,10 +40,11 @@
  * 
  * <p>
  * The <code>UserAdminPermission</code> with the reserved name &quot;admin&quot;
- * represents the permission required for creating and removing <code>Role</code>
- * objects in the User Admin service, as well as adding and removing members in
- * a <code>Group</code> object. This <code>UserAdminPermission</code> does not have
- * any actions associated with it.
+ * represents the permission required for creating and removing
+ * <code>Role</code> objects in the User Admin service, as well as adding and
+ * removing members in a <code>Group</code> object. This
+ * <code>UserAdminPermission</code> does not have any actions associated with
+ * it.
  * 
  * <p>
  * The actions to be granted are passed to the constructor in a string
@@ -64,7 +65,7 @@
  *                    existence of User object credentials whose names
  *                    start with the name argument specified in the
  *                    constructor.
- *  
+ * 
  * </pre>
  * 
  * The action string is converted to lowercase before processing.
@@ -78,7 +79,7 @@
  *  (org.osgi.service.useradmin.UserAdminPermission &quot;admin&quot;)
  *  (org.osgi.service.useradmin.UserAdminPermission &quot;com.foo.*&quot; &quot;changeProperty,getCredential,changeCredential&quot;)
  *  (org.osgi.service.useradmin.UserAdminPermission &quot;user.*&quot;, &quot;changeProperty,changeCredential&quot;)
- *  
+ * 
  * </pre>
  * 
  * The first permission statement grants the bundle the permission to perform
@@ -106,7 +107,7 @@
  *    permission org.osgi.service.useradmin.UserAdminPermission
  *      &quot;user.password&quot;, &quot;getCredential&quot;;
  *  };
- *  
+ * 
  * </pre>
  * 
  * <p>
@@ -114,10 +115,11 @@
  * validate any password credentials (for authentication purposes), but the
  * bundle is not allowed to change any properties or credentials.
  * 
- * @version $Revision: 1.13 $
+ * @ThreadSafe
+ * @version $Revision: 6381 $
  */
 public final class UserAdminPermission extends BasicPermission {
-    static final long serialVersionUID = -1179971692401603789L;
+	static final long			serialVersionUID			= -1179971692401603789L;
 	/**
 	 * The permission name &quot;admin&quot;.
 	 */
@@ -146,30 +148,26 @@
 	/**
 	 * No actions.
 	 */
-	static final int			ACTION_NONE					= 0x0;
+	static final int			ACTION_NONE					= 0;
 	/**
 	 * The actions in canonical form.
 	 * 
 	 * @serial
 	 */
-	private String				actions						= null;
+	private volatile String		actions						= null;
 	/**
 	 * The actions mask.
 	 */
-	private transient int		action_mask					= ACTION_NONE;
-	/*
-	 * Description of this <code> UserAdminPermission </code> (returned by <code>
-	 * toString </code> )
-	 */
-	private transient String	description;
+	private transient int		action_mask;
 
 	/**
-	 * Creates a new <code>UserAdminPermission</code> with the specified name and
-	 * actions. <code>name</code> is either the reserved string &quot;admin&quot;
-	 * or the name of a credential or property, and <code>actions</code> contains
-	 * a comma-separated list of the actions granted on the specified name.
-	 * Valid actions are <code>changeProperty</code>,<code>changeCredential</code>,
-	 * and getCredential.
+	 * Creates a new <code>UserAdminPermission</code> with the specified name
+	 * and actions. <code>name</code> is either the reserved string
+	 * &quot;admin&quot; or the name of a credential or property, and
+	 * <code>actions</code> contains a comma-separated list of the actions
+	 * granted on the specified name. Valid actions are
+	 * <code>changeProperty</code>,<code>changeCredential</code>, and
+	 * getCredential.
 	 * 
 	 * @param name the name of this <code>UserAdminPermission</code>
 	 * @param actions the action string.
@@ -178,7 +176,7 @@
 	 *         &quot;admin&quot; and <code>actions</code> are specified.
 	 */
 	public UserAdminPermission(String name, String actions) {
-		this(name, getMask(actions));
+		this(name, parseActions(actions));
 	}
 
 	/**
@@ -190,7 +188,7 @@
 	 */
 	UserAdminPermission(String name, int mask) {
 		super(name);
-		init(mask);
+		setTransients(mask);
 	}
 
 	/**
@@ -198,7 +196,7 @@
 	 * 
 	 * @param mask action mask
 	 */
-	private void init(int mask) {
+	private synchronized void setTransients(int mask) {
 		if (getName().equals(ADMIN)) {
 			if (mask != ACTION_NONE) {
 				throw new IllegalArgumentException("Actions specified for "
@@ -214,21 +212,32 @@
 	}
 
 	/**
-	 * Parses the action string into the action mask.
+	 * Returns the current action mask.
+	 * <p>
+	 * Used by the UserAdminPermissionCollection class.
+	 * 
+	 * @return Current action mask.
+	 */
+	synchronized int getActionsMask() {
+		return action_mask;
+	}
+
+	/**
+	 * Parse action string into action mask.
 	 * 
 	 * @param actions Action string.
 	 * @return action mask.
 	 */
-	private static int getMask(String actions) {
+	private static int parseActions(String actions) {
 		boolean seencomma = false;
 		int mask = ACTION_NONE;
 		if (actions == null) {
-			return (mask);
+			return mask;
 		}
 		char[] a = actions.toCharArray();
 		int i = a.length - 1;
 		if (i < 0)
-			return (mask);
+			return mask;
 		while (i != -1) {
 			char c;
 			// skip whitespace
@@ -265,7 +274,7 @@
 				switch (a[i - matchlen]) {
 					case ',' :
 						seencomma = true;
-					/* FALLTHROUGH */
+						/* FALLTHROUGH */
 					case ' ' :
 					case '\r' :
 					case '\n' :
@@ -284,7 +293,7 @@
 		if (seencomma) {
 			throw new IllegalArgumentException("invalid permission: " + actions);
 		}
-		return (mask);
+		return mask;
 	}
 
 	private static boolean match_change(char[] a, int i) {
@@ -323,15 +332,14 @@
 	}
 
 	/**
-	 * Checks if this <code>UserAdminPermission</code> object &quot;implies&quot;
-	 * the specified permission.
+	 * Checks if this <code>UserAdminPermission</code> object
+	 * &quot;implies&quot; the specified permission.
 	 * <P>
 	 * More specifically, this method returns <code>true</code> if:
 	 * <p>
 	 * <ul>
 	 * <li><i>p </i> is an instanceof <code>UserAdminPermission</code>,
-	 * <li><i>p </i>'s actions are a proper subset of this object's actions,
-	 * and
+	 * <li><i>p </i>'s actions are a proper subset of this object's actions, and
 	 * <li><i>p </i>'s name is implied by this object's name. For example,
 	 * &quot;java.*&quot; implies &quot;java.home&quot;.
 	 * </ul>
@@ -343,19 +351,18 @@
 	 */
 	public boolean implies(Permission p) {
 		if (p instanceof UserAdminPermission) {
-			UserAdminPermission target = (UserAdminPermission) p;
-			return (// Check that the we have the requested action
-			((target.action_mask & action_mask) == target.action_mask)
-					&&
-					// If the target action mask is ACTION_NONE, it must be an
+			UserAdminPermission requested = (UserAdminPermission) p;
+			int mask = getActionsMask();
+			int targetMask = requested.getActionsMask();
+			return // Check that the we have the requested action
+			((targetMask & mask) == targetMask) &&
+			// If the target action mask is ACTION_NONE, it must be an
 					// admin permission, and then we must be that too
-					(target.action_mask != ACTION_NONE || action_mask == ACTION_NONE) &&
-			// Check that name name matches
-			super.implies(p));
+					(targetMask != ACTION_NONE || mask == ACTION_NONE) &&
+					// Check that name name matches
+					super.implies(p);
 		}
-		else {
-			return (false);
-		}
+		return false;
 	}
 
 	/**
@@ -365,38 +372,40 @@
 	 * @return the canonical string representation of the actions.
 	 */
 	public String getActions() {
-		if (actions == null) {
+		String result = actions;
+		if (result == null) {
 			StringBuffer sb = new StringBuffer();
 			boolean comma = false;
-			if ((action_mask & ACTION_CHANGE_CREDENTIAL) == ACTION_CHANGE_CREDENTIAL) {
+			int mask = getActionsMask();
+			if ((mask & ACTION_CHANGE_CREDENTIAL) == ACTION_CHANGE_CREDENTIAL) {
 				sb.append(CHANGE_CREDENTIAL);
 				comma = true;
 			}
-			if ((action_mask & ACTION_CHANGE_PROPERTY) == ACTION_CHANGE_PROPERTY) {
+			if ((mask & ACTION_CHANGE_PROPERTY) == ACTION_CHANGE_PROPERTY) {
 				if (comma)
 					sb.append(',');
 				sb.append(CHANGE_PROPERTY);
 				comma = true;
 			}
-			if ((action_mask & ACTION_GET_CREDENTIAL) == ACTION_GET_CREDENTIAL) {
+			if ((mask & ACTION_GET_CREDENTIAL) == ACTION_GET_CREDENTIAL) {
 				if (comma)
 					sb.append(',');
 				sb.append(GET_CREDENTIAL);
 			}
-			actions = sb.toString();
+			actions = result = sb.toString();
 		}
-		return (actions);
+		return result;
 	}
 
 	/**
 	 * Returns a new <code>PermissionCollection</code> object for storing
 	 * <code>UserAdminPermission</code> objects.
 	 * 
-	 * @return a new <code>PermissionCollection</code> object suitable for storing
-	 *         <code>UserAdminPermission</code> objects.
+	 * @return a new <code>PermissionCollection</code> object suitable for
+	 *         storing <code>UserAdminPermission</code> objects.
 	 */
 	public PermissionCollection newPermissionCollection() {
-		return (new UserAdminPermissionCollection());
+		return new UserAdminPermissionCollection();
 	}
 
 	/**
@@ -407,38 +416,32 @@
 	 * @param obj the object to be compared for equality with this object.
 	 * 
 	 * @return <code>true</code> if <code>obj</code> is a
-	 *         <code>UserAdminPermission</code> object, and has the same name and
-	 *         actions as this <code>UserAdminPermission</code> object.
+	 *         <code>UserAdminPermission</code> object, and has the same name
+	 *         and actions as this <code>UserAdminPermission</code> object.
 	 */
 	public boolean equals(Object obj) {
 		if (obj == this) {
-			return (true);
+			return true;
 		}
-		if (obj instanceof UserAdminPermission) {
-			UserAdminPermission uap = (UserAdminPermission) obj;
-			return ((action_mask == uap.action_mask) && getName().equals(
-					uap.getName()));
+		if (!(obj instanceof UserAdminPermission)) {
+			return false;
 		}
-		else {
-			return (false);
-		}
+
+		UserAdminPermission uap = (UserAdminPermission) obj;
+
+		return (getActionsMask() == uap.getActionsMask())
+				&& getName().equals(uap.getName());
 	}
 
 	/**
-	 * Returns the hash code of this <code>UserAdminPermission</code> object.
+	 * Returns the hash code value for this object.
+	 * 
+	 * @return A hash code value for this object.
 	 */
 	public int hashCode() {
-		return (getName().hashCode() ^ getActions().hashCode());
-	}
-
-	/**
-	 * Returns the current action mask. Used by the
-	 * <code>UserAdminPermissionCollection</code> class.
-	 * 
-	 * @return the actions mask.
-	 */
-	int getMask() {
-		return (action_mask);
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		return h;
 	}
 
 	/**
@@ -457,10 +460,11 @@
 	/*
 	 * Restores this object from a stream (i.e., deserializes it).
 	 */
-	private synchronized void readObject(java.io.ObjectInputStream ois)
+	private synchronized void readObject(java.io.ObjectInputStream s)
 			throws IOException, ClassNotFoundException {
-		ois.defaultReadObject();
-		init(getMask(actions));
+		// Read in the action, then initialize the rest
+		s.defaultReadObject();
+		setTransients(parseActions(actions));
 	}
 
 	/**
@@ -472,42 +476,42 @@
 	 * @see "<code>org.osgi.service.permissionadmin.PermissionInfo.getEncoded</code>"
 	 */
 	public String toString() {
-		if (description == null) {
-			StringBuffer sb = new StringBuffer();
-			sb.append('(');
-			sb.append(getClass().getName());
-			sb.append(" \"");
-			sb.append(getName());
-			String actions = getActions();
-			if (actions.length() > 0) {
-				sb.append("\" \"");
-				sb.append(actions);
-			}
-			sb.append("\")");
-			description = sb.toString();
+		StringBuffer sb = new StringBuffer();
+		sb.append('(');
+		sb.append(getClass().getName());
+		sb.append(" \"");
+		sb.append(getName());
+		String a = getActions();
+		if (a.length() > 0) {
+			sb.append("\" \"");
+			sb.append(a);
 		}
-		return (description);
+		sb.append("\")");
+		return sb.toString();
 	}
 }
+
 /**
  * A <code>UserAdminPermissionCollection</code> stores a set of
  * <code>UserAdminPermission</code> permissions.
  */
 
 final class UserAdminPermissionCollection extends PermissionCollection {
-    static final long serialVersionUID = -7222111885230120581L;
+	static final long		serialVersionUID	= -7222111885230120581L;
 	/**
 	 * Table of permissions.
 	 * 
 	 * @serial
+	 * @GuardedBy this
 	 */
-	private Hashtable	permissions;
+	private final Hashtable	permissions;
 	/**
 	 * Boolean saying if "*" is in the collection.
 	 * 
 	 * @serial
+	 * @GuardedBy this
 	 */
-	private boolean		all_allowed;
+	private boolean			all_allowed;
 
 	/**
 	 * Creates an empty <code>UserAdminPermissionCollection</code> object.
@@ -518,15 +522,17 @@
 	}
 
 	/**
-	 * Adds the given permission to this <code>UserAdminPermissionCollection</code>.
-	 * The key for the hash is the name.
+	 * Adds the given permission to this
+	 * <code>UserAdminPermissionCollection</code>. The key for the hash is the
+	 * name.
 	 * 
 	 * @param permission the <code>Permission</code> object to add.
 	 * 
 	 * @throws IllegalArgumentException If the given permission is not a
 	 *         <code>UserAdminPermission</code>
-	 * @throws SecurityException If this <code>UserAdminPermissionCollection</code>
-	 *         object has been marked readonly
+	 * @throws SecurityException If this
+	 *         <code>UserAdminPermissionCollection</code> object has been marked
+	 *         readonly
 	 */
 	public void add(Permission permission) {
 		if (!(permission instanceof UserAdminPermission))
@@ -536,24 +542,27 @@
 			throw new SecurityException("Attempt to add a Permission to a "
 					+ "readonly PermissionCollection");
 		}
-		UserAdminPermission uap = (UserAdminPermission) permission;
-		String name = uap.getName();
-		UserAdminPermission existing = (UserAdminPermission) permissions
-				.get(name);
-		if (existing != null) {
-			int oldMask = existing.getMask();
-			int newMask = uap.getMask();
-			if (oldMask != newMask) {
-				permissions.put(name, new UserAdminPermission(name, oldMask
-						| newMask));
+		final UserAdminPermission uap = (UserAdminPermission) permission;
+		final String name = uap.getName();
+		synchronized (this) {
+			final UserAdminPermission existing = (UserAdminPermission) permissions
+					.get(name);
+			if (existing != null) {
+				int oldMask = existing.getActionsMask();
+				int newMask = uap.getActionsMask();
+				if (oldMask != newMask) {
+					permissions.put(name, new UserAdminPermission(name, oldMask
+							| newMask));
+				}
 			}
-		}
-		else {
-			permissions.put(name, permission);
-		}
-		if (!all_allowed) {
-			if (name.equals("*"))
-				all_allowed = true;
+			else {
+				permissions.put(name, uap);
+			}
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
+			}
 		}
 	}
 
@@ -568,33 +577,36 @@
 	 */
 	public boolean implies(Permission permission) {
 		if (!(permission instanceof UserAdminPermission)) {
-			return (false);
+			return false;
 		}
-		UserAdminPermission uap = (UserAdminPermission) permission;
+		final UserAdminPermission requested = (UserAdminPermission) permission;
+		String name = requested.getName();
+		final int desired = requested.getActionsMask();
 		UserAdminPermission x;
-		int desired = uap.getMask();
 		int effective = 0;
-		// Short circuit if the "*" Permission was added.
-		// desired can only be ACTION_NONE when name is "admin".
-		if (all_allowed && desired != UserAdminPermission.ACTION_NONE) {
-			x = (UserAdminPermission) permissions.get("*");
-			if (x != null) {
-				effective |= x.getMask();
-				if ((effective & desired) == desired) {
-					return (true);
+		synchronized (this) {
+			// Short circuit if the "*" Permission was added.
+			// desired can only be ACTION_NONE when name is "admin".
+			if (all_allowed && (desired != UserAdminPermission.ACTION_NONE)) {
+				x = (UserAdminPermission) permissions.get("*");
+				if (x != null) {
+					effective |= x.getActionsMask();
+					if ((effective & desired) == desired) {
+						return true;
+					}
 				}
 			}
+			// strategy:
+			// Check for full match first. Then work our way up the
+			// name looking for matches on a.b.*
+
+			x = (UserAdminPermission) permissions.get(name);
 		}
-		// strategy:
-		// Check for full match first. Then work our way up the
-		// name looking for matches on a.b.*
-		String name = uap.getName();
-		x = (UserAdminPermission) permissions.get(name);
 		if (x != null) {
 			// we have a direct hit!
-			effective |= x.getMask();
+			effective |= x.getActionsMask();
 			if ((effective & desired) == desired) {
-				return (true);
+				return true;
 			}
 		}
 		// work our way up the tree...
@@ -602,27 +614,30 @@
 		int offset = name.length() - 1;
 		while ((last = name.lastIndexOf(".", offset)) != -1) {
 			name = name.substring(0, last + 1) + "*";
-			x = (UserAdminPermission) permissions.get(name);
+			synchronized (this) {
+				x = (UserAdminPermission) permissions.get(name);
+			}
 			if (x != null) {
-				effective |= x.getMask();
+				effective |= x.getActionsMask();
 				if ((effective & desired) == desired) {
-					return (true);
+					return true;
 				}
 			}
 			offset = last - 1;
 		}
 		// we don't have to check for "*" as it was already checked
 		// at the top (all_allowed), so we just return false
-		return (false);
+		return false;
 	}
 
 	/**
-	 * Returns an enumeration of all the <code>UserAdminPermission</code> objects
-	 * in the container.
+	 * Returns an enumeration of all the <code>UserAdminPermission</code>
+	 * objects in the container.
 	 * 
-	 * @return an enumeration of all the <code>UserAdminPermission</code> objects.
+	 * @return an enumeration of all the <code>UserAdminPermission</code>
+	 *         objects.
 	 */
 	public Enumeration elements() {
-		return (permissions.elements());
+		return permissions.elements();
 	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html
new file mode 100644
index 0000000..c8c223d
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>User Admin Package Version 1.1.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.useradmin; version=&quot;[1.1,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo
new file mode 100644
index 0000000..3987f9c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/useradmin/packageinfo
@@ -0,0 +1 @@
+version 1.1
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java
index 8d7aada..49df68a 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/BasicEnvelope.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/BasicEnvelope.java,v 1.9 2006/06/16 16:31:43 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +19,7 @@
  * <code>BasicEnvelope</code> is an implementation of the {@link Envelope}
  * interface
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
  */
 public class BasicEnvelope implements Envelope {
 	Object	value;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java
index 5da384c..cef1c1c 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Consumer.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Consumer.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -53,7 +51,7 @@
  * different types of objects from the Producer service. The Consumer service
  * should have <code>WirePermission</code> for each of these scope names.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface Consumer {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java
index bf3d61a..5f57638 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Envelope.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Envelope.java,v 1.8 2006/06/16 16:31:43 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -45,7 +43,7 @@
  * @see WirePermission
  * @see BasicEnvelope
  * 
- * @version $Revision: 1.8 $
+ * @version $Revision: 5673 $
  */
 public interface Envelope {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java
index 3657a7a..faf6dfd 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Producer.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Producer.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -66,7 +64,7 @@
  * different types of objects (composite) to the Consumer service. The Producer
  * service should have <code>WirePermission</code> for each of these scope names.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface Producer {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java
index b972a35..9e0c1a9 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/Wire.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/Wire.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -55,7 +53,7 @@
  * is used in communication. The semantics of the names depend on the Producer
  * service and must not be interpreted by the Wire Admin service.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface Wire {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java
index 98a32b9..578ef4f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdmin.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireAdmin.java,v 1.11 2006/07/12 21:22:14 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -38,7 +36,7 @@
  * <code>ServicePermission[WireAdmin,GET]</code> to get the Wire Admin service to
  * create, modify, find, and delete <code>Wire</code> objects.
  * 
- * @version $Revision: 1.11 $
+ * @version $Revision: 5673 $
  */
 public interface WireAdmin {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java
index e2f3084..bba84ef 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminEvent.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireAdminEvent.java,v 1.9 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -56,7 +54,7 @@
  * 
  * @see WireAdminListener
  * 
- * @version $Revision: 1.9 $
+ * @version $Revision: 5673 $
  */
 public class WireAdminEvent {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java
index 9e7b04d..e741dd9 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireAdminListener.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireAdminListener.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -58,7 +56,7 @@
  * 
  * @see WireAdminEvent
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface WireAdminListener {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java
index 5190b9b..b616a4f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WireConstants.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WireConstants.java,v 1.10 2006/07/11 00:54:10 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). All Rights Reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,7 +19,7 @@
  * Defines standard names for <code>Wire</code> properties, wire filter
  * attributes, Consumer and Producer service properties.
  * 
- * @version $Revision: 1.10 $
+ * @version $Revision: 5673 $
  */
 public interface WireConstants {
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java
index b161002..6073466 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/WirePermission.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.service.wireadmin/src/org/osgi/service/wireadmin/WirePermission.java,v 1.13 2006/07/12 21:22:14 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2009). 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 +16,17 @@
 package org.osgi.service.wireadmin;
 
 import java.io.IOException;
-import java.security.*;
+import java.security.BasicPermission;
+import java.security.Permission;
+import java.security.PermissionCollection;
 import java.util.Enumeration;
 import java.util.Hashtable;
 
 /**
  * Permission for the scope of a <code>Wire</code> object. When a
- * <code>Envelope</code> object is used for communication with the <code>poll</code>
- * or <code>update</code> method, and the scope is set, then the <code>Wire</code>
- * object must verify that the Consumer service has
+ * <code>Envelope</code> object is used for communication with the
+ * <code>poll</code> or <code>update</code> method, and the scope is set, then
+ * the <code>Wire</code> object must verify that the Consumer service has
  * <code>WirePermission[name,CONSUME]</code> and the Producer service has
  * <code>WirePermission[name,PRODUCE]</code> for all names in the scope.
  * <p>
@@ -35,43 +35,45 @@
  * scope names starting with the string "Door". The last period is required due
  * to the implementations of the <code>BasicPermission</code> class.
  * 
- * @version $Revision: 1.13 $
+ * @ThreadSafe
+ * @version $Revision: 6381 $
  */
 final public class WirePermission extends BasicPermission {
-    static final long serialVersionUID = -5583709391516569321L;
+	static final long			serialVersionUID	= -5583709391516569321L;
 	/**
-	 * The action string for the <code>PRODUCE</code> action: value is "produce".
+	 * The action string for the <code>produce</code> action.
 	 */
-	public static final String	PRODUCE			= "produce";
+	public static final String	PRODUCE				= "produce";
 	/**
-	 * The action string for the <code>CONSUME</code> action: value is "consume".
+	 * The action string for the <code>consume</code> action.
 	 */
-	public static final String	CONSUME			= "consume";
-	private final static int	ACTION_PRODUCE	= 0x00000001;
-	private final static int	ACTION_CONSUME	= 0x00000002;
-	private final static int	ACTION_ALL		= ACTION_PRODUCE
-														| ACTION_CONSUME;
-	private final static int	ACTION_NONE		= 0;
+	public static final String	CONSUME				= "consume";
+	private final static int	ACTION_PRODUCE		= 0x00000001;
+	private final static int	ACTION_CONSUME		= 0x00000002;
+	private final static int	ACTION_ALL			= ACTION_PRODUCE
+															| ACTION_CONSUME;
+	private final static int	ACTION_NONE			= 0;
 	/**
 	 * The actions mask.
 	 */
-	private transient int		action_mask		= ACTION_NONE;
+	private transient int		action_mask;
 	/**
 	 * The actions in canonical form.
 	 * 
 	 * @serial
 	 */
-	private String				actions			= null;
+	private volatile String		actions				= null;
 
 	/**
 	 * Create a new WirePermission with the given name (may be wildcard) and
 	 * actions.
+	 * 
 	 * @param name Wire name.
-	 * @param actions <code>produce</code>, <code>consume</code>
-	 *        (canonical order).
+	 * @param actions <code>produce</code>, <code>consume</code> (canonical
+	 *        order).
 	 */
 	public WirePermission(String name, String actions) {
-		this(name, getMask(actions));
+		this(name, parseActions(actions));
 	}
 
 	/**
@@ -82,7 +84,7 @@
 	 */
 	WirePermission(String name, int mask) {
 		super(name);
-		init(mask);
+		setTransients(mask);
 	}
 
 	/**
@@ -90,7 +92,7 @@
 	 * 
 	 * @param mask action mask
 	 */
-	private void init(int mask) {
+	private synchronized void setTransients(int mask) {
 		if ((mask == ACTION_NONE) || ((mask & ACTION_ALL) != mask)) {
 			throw new IllegalArgumentException("invalid action string");
 		}
@@ -98,12 +100,22 @@
 	}
 
 	/**
+	 * Returns the current action mask. Used by the WirePermissionCollection
+	 * object.
+	 * 
+	 * @return The actions mask.
+	 */
+	synchronized int getActionsMask() {
+		return action_mask;
+	}
+
+	/**
 	 * Parse action string into action mask.
 	 * 
 	 * @param actions Action string.
 	 * @return action mask.
 	 */
-	private static int getMask(String actions) {
+	private static int parseActions(String actions) {
 		boolean seencomma = false;
 		int mask = ACTION_NONE;
 		if (actions == null) {
@@ -155,7 +167,7 @@
 				switch (a[i - matchlen]) {
 					case ',' :
 						seencomma = true;
-					/* FALLTHROUGH */
+						/* FALLTHROUGH */
 					case ' ' :
 					case '\r' :
 					case '\n' :
@@ -178,15 +190,14 @@
 	}
 
 	/**
-	 * Checks if this <code>WirePermission</code> object <code>implies</code> the
-	 * specified permission.
+	 * Checks if this <code>WirePermission</code> object <code>implies</code>
+	 * the specified permission.
 	 * <P>
 	 * More specifically, this method returns <code>true</code> if:
 	 * <p>
 	 * <ul>
 	 * <li><i>p </i> is an instanceof the <code>WirePermission</code> class,
-	 * <li><i>p </i>'s actions are a proper subset of this object's actions,
-	 * and
+	 * <li><i>p </i>'s actions are a proper subset of this object's actions, and
 	 * <li><i>p </i>'s name is implied by this object's name. For example,
 	 * <code>java.*</code> implies <code>java.home</code>.
 	 * </ul>
@@ -198,8 +209,9 @@
 	 */
 	public boolean implies(Permission p) {
 		if (p instanceof WirePermission) {
-			WirePermission target = (WirePermission) p;
-			return ((action_mask & target.action_mask) == target.action_mask)
+			WirePermission requested = (WirePermission) p;
+			int requestedMask = requested.getActionsMask();
+			return ((getActionsMask() & requestedMask) == requestedMask)
 					&& super.implies(p);
 		}
 		return false;
@@ -213,29 +225,31 @@
 	 * @return The canonical string representation of the actions.
 	 */
 	public String getActions() {
-		if (actions == null) {
+		String result = actions;
+		if (result == null) {
 			StringBuffer sb = new StringBuffer();
 			boolean comma = false;
-			if ((action_mask & ACTION_PRODUCE) == ACTION_PRODUCE) {
+			int mask = getActionsMask();
+			if ((mask & ACTION_PRODUCE) == ACTION_PRODUCE) {
 				sb.append(PRODUCE);
 				comma = true;
 			}
-			if ((action_mask & ACTION_CONSUME) == ACTION_CONSUME) {
+			if ((mask & ACTION_CONSUME) == ACTION_CONSUME) {
 				if (comma)
 					sb.append(',');
 				sb.append(CONSUME);
 			}
-			actions = sb.toString();
+			actions = result = sb.toString();
 		}
-		return actions;
+		return result;
 	}
 
 	/**
 	 * Returns a new <code>PermissionCollection</code> object for storing
 	 * <code>WirePermission</code> objects.
 	 * 
-	 * @return A new <code>PermissionCollection</code> object suitable for storing
-	 *         <code>WirePermission</code> objects.
+	 * @return A new <code>PermissionCollection</code> object suitable for
+	 *         storing <code>WirePermission</code> objects.
 	 */
 	public PermissionCollection newPermissionCollection() {
 		return new WirePermissionCollection();
@@ -248,8 +262,8 @@
 	 * <code>WirePermission</code> object.
 	 * 
 	 * @param obj The object to test for equality.
-	 * @return true if <code>obj</code> is a <code>WirePermission</code>, and has
-	 *         the same name and actions as this <code>WirePermission</code>
+	 * @return true if <code>obj</code> is a <code>WirePermission</code>, and
+	 *         has the same name and actions as this <code>WirePermission</code>
 	 *         object; <code>false</code> otherwise.
 	 */
 	public boolean equals(Object obj) {
@@ -259,8 +273,9 @@
 		if (!(obj instanceof WirePermission)) {
 			return false;
 		}
-		WirePermission p = (WirePermission) obj;
-		return (action_mask == p.action_mask) && getName().equals(p.getName());
+		WirePermission wp = (WirePermission) obj;
+		return (getActionsMask() == wp.getActionsMask())
+				&& getName().equals(wp.getName());
 	}
 
 	/**
@@ -269,17 +284,9 @@
 	 * @return Hash code value for this object.
 	 */
 	public int hashCode() {
-		return getName().hashCode() ^ getActions().hashCode();
-	}
-
-	/**
-	 * Returns the current action mask. Used by the WirePermissionCollection
-	 * object.
-	 * 
-	 * @return The actions mask.
-	 */
-	int getMask() {
-		return action_mask;
+		int h = 31 * 17 + getName().hashCode();
+		h = 31 * h + getActions().hashCode();
+		return h;
 	}
 
 	/**
@@ -297,8 +304,11 @@
 		sb.append(getClass().getName());
 		sb.append(" \"");
 		sb.append(getName());
-		sb.append("\" \"");
-		sb.append(getActions());
+		String a = getActions();
+		if (a.length() > 0) {
+			sb.append("\" \"");
+			sb.append(a);
+		}
 		sb.append("\")");
 		return sb.toString();
 	}
@@ -325,32 +335,35 @@
 			throws IOException, ClassNotFoundException {
 		// Read in the action, then initialize the rest
 		s.defaultReadObject();
-		init(getMask(actions));
+		setTransients(parseActions(actions));
 	}
 }
+
 /**
- * A <code>WirePermissionCollection</code> stores a set of <code>WirePermission</code>
- * permissions.
+ * A <code>WirePermissionCollection</code> stores a set of
+ * <code>WirePermission</code> permissions.
  */
 
 final class WirePermissionCollection extends PermissionCollection {
-    static final long serialVersionUID = 2617521094909826016L;
+	static final long		serialVersionUID	= 2617521094909826016L;
 	/**
 	 * Table of permissions.
 	 * 
+	 * @GuardedBy this
 	 * @serial
 	 */
-	private Hashtable	permissions;
+	private final Hashtable	permissions;
 	/**
 	 * Boolean saying if "*" is in the collection.
 	 * 
+	 * @GuardedBy this
 	 * @serial
 	 */
-	private boolean		all_allowed;
+	private boolean			all_allowed;
 
 	/**
 	 * Creates an empty WirePermissionCollection object.
-	 *  
+	 * 
 	 */
 	public WirePermissionCollection() {
 		permissions = new Hashtable();
@@ -363,35 +376,40 @@
 	 * @param permission The Permission object to add.
 	 * 
 	 * @throws IllegalArgumentException If the permission is not a
-	 *            WirePermission object.
+	 *         WirePermission object.
 	 * 
 	 * @throws SecurityException If this PermissionCollection has been marked
-	 *            read-only.
+	 *         read-only.
 	 */
 	public void add(Permission permission) {
-		if (!(permission instanceof WirePermission))
+		if (!(permission instanceof WirePermission)) {
 			throw new IllegalArgumentException("invalid permission: "
 					+ permission);
-		if (isReadOnly())
+		}
+		if (isReadOnly()) {
 			throw new SecurityException("attempt to add a Permission to a "
 					+ "readonly PermissionCollection");
-		WirePermission p = (WirePermission) permission;
-		String name = p.getName();
-		WirePermission existing = (WirePermission) permissions.get(name);
-		if (existing != null) {
-			int oldMask = existing.getMask();
-			int newMask = p.getMask();
-			if (oldMask != newMask) {
-				permissions.put(name, new WirePermission(name, oldMask
-						| newMask));
+		}
+		WirePermission wp = (WirePermission) permission;
+		String name = wp.getName();
+		synchronized (this) {
+			WirePermission existing = (WirePermission) permissions.get(name);
+			if (existing != null) {
+				int oldMask = existing.getActionsMask();
+				int newMask = wp.getActionsMask();
+				if (oldMask != newMask) {
+					permissions.put(name, new WirePermission(name, oldMask
+							| newMask));
+				}
 			}
-		}
-		else {
-			permissions.put(name, permission);
-		}
-		if (!all_allowed) {
-			if (name.equals("*"))
-				all_allowed = true;
+			else {
+				permissions.put(name, wp);
+			}
+			if (!all_allowed) {
+				if (name.equals("*")) {
+					all_allowed = true;
+				}
+			}
 		}
 	}
 
@@ -401,46 +419,53 @@
 	 * 
 	 * @param permission The Permission object to compare.
 	 * 
-	 * @return <code>true</code> if <code>permission</code> is a proper subset of a
-	 *         permission in the set; <code>false</code> otherwise.
+	 * @return <code>true</code> if <code>permission</code> is a proper subset
+	 *         of a permission in the set; <code>false</code> otherwise.
 	 */
 	public boolean implies(Permission permission) {
-		if (!(permission instanceof WirePermission))
+		if (!(permission instanceof WirePermission)) {
 			return false;
-		WirePermission p = (WirePermission) permission;
-		WirePermission x;
-		int desired = p.getMask();
-		int effective = 0;
-		// short circuit if the "*" Permission was added
-		if (all_allowed) {
-			x = (WirePermission) permissions.get("*");
-			if (x != null) {
-				effective |= x.getMask();
-				if ((effective & desired) == desired)
-					return true;
-			}
 		}
-		// strategy:
-		// Check for full match first. Then work our way up the
-		// name looking for matches on a.b.*
-		String name = p.getName();
-		x = (WirePermission) permissions.get(name);
+		WirePermission requested = (WirePermission) permission;
+		WirePermission x;
+		int desired = requested.getActionsMask();
+		int effective = 0;
+		String name = requested.getName();
+		synchronized (this) {
+			// short circuit if the "*" Permission was added
+			if (all_allowed) {
+				x = (WirePermission) permissions.get("*");
+				if (x != null) {
+					effective |= x.getActionsMask();
+					if ((effective & desired) == desired)
+						return true;
+				}
+			}
+			// strategy:
+			// Check for full match first. Then work our way up the
+			// name looking for matches on a.b.*
+			x = (WirePermission) permissions.get(name);
+		}
 		if (x != null) {
 			// we have a direct hit!
-			effective |= x.getMask();
-			if ((effective & desired) == desired)
+			effective |= x.getActionsMask();
+			if ((effective & desired) == desired) {
 				return true;
+			}
 		}
 		// work our way up the tree...
-		int last, offset;
-		offset = name.length() - 1;
+		int last;
+		int offset = name.length() - 1;
 		while ((last = name.lastIndexOf(".", offset)) != -1) {
 			name = name.substring(0, last + 1) + "*";
-			x = (WirePermission) permissions.get(name);
+			synchronized (this) {
+				x = (WirePermission) permissions.get(name);
+			}
 			if (x != null) {
-				effective |= x.getMask();
-				if ((effective & desired) == desired)
+				effective |= x.getActionsMask();
+				if ((effective & desired) == desired) {
 					return (true);
+				}
 			}
 			offset = last - 1;
 		}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/package.html b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/package.html
new file mode 100644
index 0000000..36d1d82
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/package.html
@@ -0,0 +1,11 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Wire Admin Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.service.wireadmin; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>
+
diff --git a/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/packageinfo
new file mode 100644
index 0000000..7c8de03
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/service/wireadmin/packageinfo
@@ -0,0 +1 @@
+version 1.0
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/cdma/ESNCondition.java b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/ESNCondition.java
new file mode 100644
index 0000000..06bd6f8
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/ESNCondition.java
@@ -0,0 +1,106 @@
+/*

+ * Copyright (c) OSGi Alliance (2007, 2009). 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.util.cdma;

+

+import java.security.AccessController;

+import java.security.PrivilegedAction;

+

+import org.osgi.framework.Bundle;

+import org.osgi.service.condpermadmin.Condition;

+import org.osgi.service.condpermadmin.ConditionInfo;

+

+/**

+ * Class representing an ESN condition. Instances of this class contain a string

+ * value that is matched against the ESN of the device.

+ * 

+ * @ThreadSafe

+ * @version $Revision: 6439 $

+ */

+public class ESNCondition {

+	private static final String	ORG_OSGI_UTIL_CDMA_ESN	= "org.osgi.util.cdma.esn";

+	private static final String	ESN;

+	private static final int	ESN_LENGTH				= 8;

+

+	static {

+		ESN = (String) AccessController.doPrivileged(new PrivilegedAction() {

+			public Object run() {

+				String esn = System.getProperty(ORG_OSGI_UTIL_CDMA_ESN);

+				if (esn == null) {

+					return null;

+				}

+				return esn.toUpperCase();

+			}

+		});

+	}

+

+	private ESNCondition() {

+		// prevent instances being constructed

+	}

+

+	/**

+	 * Creates an ESNCondition object.

+	 * 

+	 * @param bundle This parameter is ignored, as the ESN number is the

+	 *        property of the mobile device, and thus the same for all bundles.

+	 * @param conditionInfo Contains the ESN value against which to match the

+	 *        device's ESN. Its {@link ConditionInfo#getArgs()} method should

+	 *        return a String array with one value, the ESN string. The ESN is 8

+	 *        hexadecimal digits (32 bits) without hyphens. Limited pattern

+	 *        matching is allowed: the string is 0 to 7 digits, followed by an

+	 *        asterisk(<code>*</code>).

+	 * @return A Condition object that indicates whether the specified ESN

+	 *         number matches that of the device. If the number ends with an

+	 *         asterisk ( <code>*</code>), then the beginning of the ESN is

+	 *         compared to the pattern.

+	 * @throws IllegalArgumentException If the ESN is not a string of 8

+	 *         hexadecimal digits, or 0 to 7 hexadecimal digits with an

+	 *         <code>*</code> at the end.

+	 */

+	public static Condition getCondition(Bundle bundle,

+			ConditionInfo conditionInfo) {

+		String esn = conditionInfo.getArgs()[0].toUpperCase();

+		int length = esn.length();

+		if (length > ESN_LENGTH) {

+			throw new IllegalArgumentException("ESN too long: " + esn);

+		}

+		if (esn.endsWith("*")) {

+			length--;

+			esn = esn.substring(0, length);

+		}

+		else {

+			if (length < ESN_LENGTH) {

+				throw new IllegalArgumentException("ESN too short: " + esn);

+			}

+		}

+		for (int i = 0; i < length; i++) {

+			char c = esn.charAt(i);

+			if (('0' <= c) && (c <= '9')) {

+				continue;

+			}

+	        if (('A' <= c) && (c <= 'F')) {

+				continue;

+			}

+			throw new IllegalArgumentException("not a valid ESN: " + esn);

+		}

+		if (ESN == null) {

+			System.err

+					.println("The OSGi implementation of org.osgi.util.cdma.ESNCondition needs the system property "

+							+ ORG_OSGI_UTIL_CDMA_ESN + " set.");

+			return Condition.FALSE;

+		}

+		return ESN.startsWith(esn) ? Condition.TRUE : Condition.FALSE;

+	}

+}

diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/cdma/MEIDCondition.java b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/MEIDCondition.java
new file mode 100644
index 0000000..f5331d0
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/MEIDCondition.java
@@ -0,0 +1,106 @@
+/*

+ * Copyright (c) OSGi Alliance (2007, 2009). 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.util.cdma;

+

+import java.security.AccessController;

+import java.security.PrivilegedAction;

+

+import org.osgi.framework.Bundle;

+import org.osgi.service.condpermadmin.Condition;

+import org.osgi.service.condpermadmin.ConditionInfo;

+

+/**

+ * Class representing an MEID condition. Instances of this class contain a

+ * string value that is matched against the MEID of the device.

+ * 

+ * @ThreadSafe

+ * @version $Revision: 6439 $

+ */

+public class MEIDCondition {

+	private static final String	ORG_OSGI_UTIL_CDMA_MEID	= "org.osgi.util.cdma.meid";

+	private static final String	MEID;

+	private static final int	MEID_LENGTH				= 14;

+

+	static {

+		MEID = (String) AccessController.doPrivileged(new PrivilegedAction() {

+			public Object run() {

+				String meid = System.getProperty(ORG_OSGI_UTIL_CDMA_MEID);

+				if (meid == null) {

+					return null;

+				}

+				return meid.toUpperCase();

+			}

+		});

+	}

+

+	private MEIDCondition() {

+		// prevent instances being constructed

+	}

+

+	/**

+	 * Creates a MEIDCondition object.

+	 * 

+	 * @param bundle This parameter is ignored, as the MEID number is the

+	 *        property of the mobile device, and thus the same for all bundles.

+	 * @param conditionInfo Contains the MEID value against which to match the

+	 *        device's MEID. Its {@link ConditionInfo#getArgs()} method should

+	 *        return a String array with one value, the MEID string. The MEID is

+	 *        14 hexadecimal digits (56 bits) without hyphens. Limited pattern

+	 *        matching is allowed: the string is 0 to 13 digits, followed by an

+	 *        asterisk(<code>*</code>).

+	 * @return A Condition object that indicates whether the specified MEID

+	 *         number matches that of the device. If the number ends with an

+	 *         asterisk ( <code>*</code>), then the beginning of the MEID is

+	 *         compared to the pattern.

+	 * @throws IllegalArgumentException If the MEID is not a string of 14

+	 *         hexadecimal digits, or 0 to 13 hexadecimal digits with an

+	 *         <code>*</code> at the end.

+	 */

+	public static Condition getCondition(Bundle bundle,

+			ConditionInfo conditionInfo) {

+		String meid = conditionInfo.getArgs()[0].toUpperCase();

+		int length = meid.length();

+		if (length > MEID_LENGTH) {

+			throw new IllegalArgumentException("MEID too long: " + meid);

+		}

+		if (meid.endsWith("*")) {

+			length--;

+			meid = meid.substring(0, length);

+		}

+		else {

+			if (length < MEID_LENGTH) {

+				throw new IllegalArgumentException("MEID too short: " + meid);

+			}

+		}

+		for (int i = 0; i < length; i++) {

+			char c = meid.charAt(i);

+			if (('0' <= c) && (c <= '9')) {

+				continue;

+			}

+			if (('A' <= c) && (c <= 'F')) {

+				continue;

+			}

+			throw new IllegalArgumentException("not a valid MEID: " + meid);

+		}

+		if (MEID == null) {

+			System.err

+					.println("The OSGi implementation of org.osgi.util.cdma.MEIDCondition needs the system property "

+							+ ORG_OSGI_UTIL_CDMA_MEID + " set.");

+			return Condition.FALSE;

+		}

+		return MEID.startsWith(meid) ? Condition.TRUE : Condition.FALSE;

+	}

+}

diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/cdma/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/package.html
new file mode 100644
index 0000000..eaa0953
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->

+<BODY>

+<p>CDMA Conditions Package Version 1.0.

+<p>Bundles wishing to use this package must list the package

+in the Import-Package header of the bundle's manifest.

+For example:

+<pre>

+Import-Package: org.osgi.util.cdma; version=&quot;[1.0,2.0)&quot;

+</pre>

+</BODY>

diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/cdma/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/packageinfo
new file mode 100644
index 0000000..a4f1546
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/cdma/packageinfo
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java
index 958b55b..79761fa 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMEICondition.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.gsm/src/org/osgi/util/gsm/IMEICondition.java,v 1.21 2007/02/19 21:32:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). 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.
@@ -27,59 +25,74 @@
 /**
  * Class representing an IMEI condition. Instances of this class contain a
  * string value that is matched against the IMEI of the device.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 6439 $
  */
 public class IMEICondition {
-	private static final String ORG_OSGI_UTIL_GSM_IMEI = "org.osgi.util.gsm.imei";
-	private static final String imei ;
-		
+	private static final String	ORG_OSGI_UTIL_GSM_IMEI	= "org.osgi.util.gsm.imei";
+	private static final String	IMEI;
+	private static final int	IMEI_LENGTH				= 15;
+
 	static {
-		imei = (String)
-		AccessController.doPrivileged(
-				new PrivilegedAction() {
-					public Object run() {
-					return System.getProperty(ORG_OSGI_UTIL_GSM_IMEI);
-					}
-				}
-				);
+		IMEI = (String) AccessController.doPrivileged(new PrivilegedAction() {
+			public Object run() {
+				return System.getProperty(ORG_OSGI_UTIL_GSM_IMEI);
+			}
+		});
 	}
-	
+
 	private IMEICondition() {
+		// prevent instances being constructed
 	}
 
 	/**
-	 * Creates an IMEICondition object.
+	 * Creates an IMEI condition object.
 	 * 
-	 * @param bundle ignored, as the IMEI number is the property of the mobile device,
-	 * 					and thus the same for all bundles.
-	 * @param conditionInfo contains the IMEI value to match the device's IMEI against. Its
-	 * 		{@link ConditionInfo#getArgs()} method should return a String array with one value, the
-	 * 		IMEI string. The IMEI is 15 digits without hypens. Limited pattern matching is allowed,
-	 * 		then the string is 0 to 14 digits, followed by an asterisk(<code>*</code>).
-	 * @return An IMEICondition object, that can tell whether its IMEI number matches that of the device.
-	 * 			If the number contains an asterisk(<code>*</code>), then the beginning
-	 * 			of the imei is compared to the pattern.
-	 * @throws NullPointerException if one of the parameters is <code>null</code>.
-	 * @throws IllegalArgumentException if the IMEI is not a string of 15 digits, or 
-	 * 		0 to 14 digits with an <code>*</code> at the end.
+	 * @param bundle This parameter is ignored, as the IMEI number is a property
+	 *        of the mobile device and thus is the same for all bundles.
+	 * @param conditionInfo Contains the IMEI value against which to match the
+	 *        device's IMEI. Its {@link ConditionInfo#getArgs()} method should
+	 *        return a String array with one value: the IMEI string. The IMEI is
+	 *        15 digits without hyphens. Limited pattern matching is allowed:
+	 *        the string is 0 to 14 digits, followed by an asterisk (
+	 *        <code>*</code>).
+	 * @return A Condition object that indicates whether the specified IMEI
+	 *         number matches that of the device. If the number ends with an
+	 *         asterisk ( <code>*</code>), then the beginning of the IMEI is
+	 *         compared to the pattern.
+	 * @throws IllegalArgumentException If the IMEI is not a string of 15
+	 *         digits, or 0 to 14 digits with an <code>*</code> at the end.
 	 */
-	public static Condition getCondition(Bundle bundle, ConditionInfo conditionInfo) {
-		if (bundle==null) throw new NullPointerException("bundle");
+	public static Condition getCondition(Bundle bundle,
+			ConditionInfo conditionInfo) {
 		String imei = conditionInfo.getArgs()[0];
-		if (imei.length()>15) throw new IllegalArgumentException("imei too long: "+imei);
+		int length = imei.length();
+		if (length > IMEI_LENGTH) {
+			throw new IllegalArgumentException("IMEI too long: " + imei);
+		}
 		if (imei.endsWith("*")) {
-			imei = imei.substring(0,imei.length()-1);
-		} else {
-			if (imei.length()!=15) throw new IllegalArgumentException("not a valid imei: "+imei);
+			length--;
+			imei = imei.substring(0, length);
 		}
-		for(int i=0;i<imei.length();i++) {
-			int c = imei.charAt(i);
-			if (c<'0'||c>'9') throw new IllegalArgumentException("not a valid imei: "+imei);
+		else {
+			if (length < IMEI_LENGTH) {
+				throw new IllegalArgumentException("IMEI too short: " + imei);
+			}
 		}
-		if (IMEICondition.imei==null) {
-			System.err.println("The OSGi Reference Implementation of org.osgi.util.gsm.IMEICondition ");
-			System.err.println("needs the system property "+ORG_OSGI_UTIL_GSM_IMEI+" set.");
+		for (int i = 0; i < length; i++) {
+			char c = imei.charAt(i);
+			if (('0' <= c) && (c <= '9')) {
+				continue;
+			}
+			throw new IllegalArgumentException("not a valid IMEI: " + imei);
+		}
+		if (IMEI == null) {
+			System.err
+					.println("The OSGi implementation of org.osgi.util.gsm.IMEICondition needs the system property "
+							+ ORG_OSGI_UTIL_GSM_IMEI + " set.");
 			return Condition.FALSE;
 		}
-		return IMEICondition.imei.startsWith(imei)?Condition.TRUE:Condition.FALSE;
+		return IMEI.startsWith(imei) ? Condition.TRUE : Condition.FALSE;
 	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java
index 740bda1..d772d7a 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/IMSICondition.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.gsm/src/org/osgi/util/gsm/IMSICondition.java,v 1.23 2007/02/19 21:32:28 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2009). 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.
@@ -27,58 +25,74 @@
 /**
  * Class representing an IMSI condition. Instances of this class contain a
  * string value that is matched against the IMSI of the subscriber.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 6439 $
  */
 public class IMSICondition {
-	private static final String ORG_OSGI_UTIL_GSM_IMSI = "org.osgi.util.gsm.imsi";
-	private static final String imsi;
-	
+	private static final String	ORG_OSGI_UTIL_GSM_IMSI	= "org.osgi.util.gsm.imsi";
+	private static final String	IMSI;
+	private static final int	IMSI_LENGTH				= 15;
+
 	static {
-		imsi = (String)
-		AccessController.doPrivileged(
-				new PrivilegedAction() {
-					public Object run() {
-					return System.getProperty(ORG_OSGI_UTIL_GSM_IMSI);
-					}
-				}
-				);
+		IMSI = (String) AccessController.doPrivileged(new PrivilegedAction() {
+			public Object run() {
+				return System.getProperty(ORG_OSGI_UTIL_GSM_IMSI);
+			}
+		});
 	}
 
-	private IMSICondition() {}
+	private IMSICondition() {
+		// prevent instances being constructed
+	}
 
 	/**
 	 * Creates an IMSI condition object.
 	 * 
-	 * @param bundle ignored, as the IMSI number is the same for all bundles.
-	 * @param conditionInfo contains the IMSI value to match the device's IMSI against. Its
-	 * 		{@link ConditionInfo#getArgs()} method should return a String array with one value, the
-	 * 		IMSI string. The IMSI is 15 digits without hypens. Limited pattern matching is allowed,
-	 * 		then the string is 0 to 14 digits, followed by an asterisk(<code>*</code>).
-	 * @return An IMSICondition object, that can tell whether its IMSI number matches that of the device.
-	 * 			If the number contains an asterisk(<code>*</code>), then the beginning
-	 * 			of the IMSI is compared to the pattern.
-	 * @throws NullPointerException if one of the parameters is <code>null</code>.
-	 * @throws IllegalArgumentException if the IMSI is not a string of 15 digits, or 
-	 * 		0 to 14 digits with an <code>*</code> at the end.
+	 * @param bundle This parameter is ignored, as the IMSI number is a property
+	 *        of the mobile subscriber and thus is the same for all bundles.
+	 * @param conditionInfo Contains the IMSI value against which to match the
+	 *        subscriber's IMSI. Its {@link ConditionInfo#getArgs()} method
+	 *        should return a String array with one value: the IMSI string. The
+	 *        IMSI is 15 digits without hyphens. Limited pattern matching is
+	 *        allowed: the string is 0 to 14 digits, followed by an asterisk (
+	 *        <code>*</code>).
+	 * @return A Condition object that indicates whether the specified IMSI
+	 *         number matches that of the subscriber. If the number ends with an
+	 *         asterisk (<code>*</code>), then the beginning of the IMSI is
+	 *         compared to the pattern.
+	 * @throws IllegalArgumentException If the IMSI is not a string of 15
+	 *         digits, or 0 to 14 digits with an <code>*</code> at the end.
 	 */
-	public static Condition getCondition(Bundle bundle, ConditionInfo conditionInfo) {
-		if (bundle==null) throw new NullPointerException("bundle");
-		if (conditionInfo==null) throw new NullPointerException("conditionInfo");
+	public static Condition getCondition(Bundle bundle,
+			ConditionInfo conditionInfo) {
 		String imsi = conditionInfo.getArgs()[0];
-		if (imsi.length()>15) throw new IllegalArgumentException("imsi too long: "+imsi);
+		int length = imsi.length();
+		if (length > IMSI_LENGTH) {
+			throw new IllegalArgumentException("IMSI too long: " + imsi);
+		}
 		if (imsi.endsWith("*")) {
-			imsi = imsi.substring(0,imsi.length()-1);
-		} else {
-			if (imsi.length()!=15) throw new IllegalArgumentException("not a valid imei: "+imsi);
+			length--;
+			imsi = imsi.substring(0, length);
 		}
-		for(int i=0;i<imsi.length();i++) {
-			int c = imsi.charAt(i);
-			if (c<'0'||c>'9') throw new IllegalArgumentException("not a valid imei: "+imsi);
+		else {
+			if (length < IMSI_LENGTH) {
+				throw new IllegalArgumentException("IMSI too short: " + imsi);
+			}
 		}
-		if (IMSICondition.imsi==null) {
-			System.err.println("The OSGi Reference Implementation of org.osgi.util.gsm.IMSICondition ");
-			System.err.println("needs the system property "+ORG_OSGI_UTIL_GSM_IMSI+" set.");
+		for (int i = 0; i < length; i++) {
+			char c = imsi.charAt(i);
+			if (('0' <= c) && (c <= '9')) {
+				continue;
+			}
+			throw new IllegalArgumentException("not a valid IMSI: " + imsi);
+		}
+		if (IMSI == null) {
+			System.err
+					.println("The OSGi implementation of org.osgi.util.gsm.IMSICondition needs the system property "
+							+ ORG_OSGI_UTIL_GSM_IMSI + " set.");
 			return Condition.FALSE;
 		}
-		return (IMSICondition.imsi.startsWith(imsi))?Condition.TRUE:Condition.FALSE;
+		return IMSI.startsWith(imsi) ? Condition.TRUE : Condition.FALSE;
 	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/package.html
new file mode 100644
index 0000000..2b6bd0e
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Mobile GSM Conditions Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.gsm; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/gsm/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/packageinfo
new file mode 100644
index 0000000..c266447
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/gsm/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java
index 0b6cc70..82779cc 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Measurement.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.measurement/src/org/osgi/util/measurement/Measurement.java,v 1.14 2006/07/11 00:54:06 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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,7 +15,6 @@
  */
 package org.osgi.util.measurement;
 
-
 /**
  * Represents a value with an error, a unit and a time-stamp.
  * 
@@ -46,15 +43,16 @@
  * Note: This class has a natural ordering that is inconsistent with equals. See
  * {@link #compareTo}.
  * 
- * @version $Revision: 1.14 $
+ * @Immutable
+ * @version $Revision: 5715 $
  */
 public class Measurement implements Comparable {
-	/* package private so it can be accessed by Unit */
-	final double	value;
-	final double	error;
-	final long		time;
-	final Unit		unit;
-	private transient String	name;
+	private final double				value;
+	private final double				error;
+	private final long					time;
+	private final Unit					unit;
+	private transient volatile String	name;
+	private transient volatile int		hashCode;
 
 	/**
 	 * Create a new <code>Measurement</code> object.
@@ -370,7 +368,8 @@
 	 *         object.
 	 */
 	public String toString() {
-		if (name == null) {
+		String result = name;
+		if (result == null) {
 			StringBuffer sb = new StringBuffer();
 			sb.append(value);
 			if (error != 0.0d) {
@@ -382,9 +381,10 @@
 				sb.append(" ");
 				sb.append(u);
 			}
-			name = sb.toString();
+			result = sb.toString();
+			name = result;
 		}
-		return name;
+		return result;
 	}
 
 	/**
@@ -422,25 +422,20 @@
 			throw new ArithmeticException("Cannot compare " + this + " and "
 					+ that);
 		}
-		if (value == that.value) {
+		int result = Double.compare(value, that.value);
+		if (result == 0) {
 			return 0;
 		}
-		if (value < that.value) {
-			if ((value + error) >= (that.value - that.error)) {
+		if (result < 0) {
+			if (Double.compare(value + error, that.value - that.error) >= 0) {
 				return 0;
 			}
-			else {
-				return -1;
-			}
+			return -1;
 		}
-		else {
-			if ((value - error) <= (that.value + that.error)) {
-				return 0;
-			}
-			else {
-				return 1;
-			}
+		if (Double.compare(value - error, that.value + that.error) <= 0) {
+			return 0;
 		}
+		return 1;
 	}
 
 	/**
@@ -449,8 +444,16 @@
 	 * @return A hash code value for this object.
 	 */
 	public int hashCode() {
-		long bits = Double.doubleToLongBits(value + error);
-		return ((int) (bits ^ (bits >>> 32))) ^ unit.hashCode();
+		int h = hashCode;
+		if (h == 0) {
+			long bits = Double.doubleToLongBits(value);
+			h = 31 * 17 + ((int) (bits ^ (bits >>> 32)));
+			bits = Double.doubleToLongBits(error);
+			h = 31 * h + ((int) (bits ^ (bits >>> 32)));
+			h = 31 * h + unit.hashCode();
+			hashCode = h;
+		}
+		return h;
 	}
 
 	/**
@@ -474,7 +477,8 @@
 			return false;
 		}
 		Measurement that = (Measurement) obj;
-		return (value == that.value) && (error == that.error)
+		return (Double.compare(value, that.value) == 0)
+				&& (Double.compare(error, that.error) == 0)
 				&& unit.equals(that.unit);
 	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/State.java b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/State.java
index 77ce395..7fcc469 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/State.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/State.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.measurement/src/org/osgi/util/measurement/State.java,v 1.8 2006/06/16 16:31:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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.
@@ -27,12 +25,13 @@
  * <p>
  * A <code>State</code> object is immutable so that it may be easily shared.
  * 
- * @version $Revision: 1.8 $
+ * @Immutable
+ * @version $Revision: 5715 $
  */
 public class State {
-	final int		value;
-	final long		time;
-	final String	name;
+	private final int		value;
+	private final long		time;
+	private final String	name;
 
 	/**
 	 * Create a new <code>State</code> object.
@@ -108,9 +107,9 @@
 	 * @return A hash code value for this object.
 	 */
 	public int hashCode() {
-		int hash = value;
+		int hash = 31 * 17 + value;
 		if (name != null) {
-			hash ^= name.hashCode();
+			hash = 31 * hash + name.hashCode();
 		}
 		return hash;
 	}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Unit.java b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Unit.java
index e53bb25..5bea0c1 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Unit.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/Unit.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.measurement/src/org/osgi/util/measurement/Unit.java,v 1.15 2006/06/16 16:31:34 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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,7 +28,8 @@
  * +63. Any operation which produces an exponent outside of this range will
  * result in a <code>Unit</code> object with undefined exponents.
  * 
- * @version $Revision: 1.15 $
+ * @Immutable
+ * @version $Revision: 5715 $
  */
 /*
  * This local class maintains the information about units. It can calculate new
@@ -279,9 +278,11 @@
 	private final static Unit[]	allUnits	= new Unit[] {m, s, kg, K, A, mol,
 			cd, rad, m_s, m_s2, m2, m3, Hz, N, Pa, J, W, C, V, F, Ohm, S, Wb,
 			T, lx, Gy, kat, unity			};
+	
+	/* @GuardedBy("this") */
 	private static Hashtable	base;
-	private String				name;
-	private long				type;
+	private final String		name;
+	private final long			type;
 
 	/**
 	 * Creates a new <code>Unit</code> instance.
@@ -290,6 +291,9 @@
 	 * @param type the type of the <code>Unit</code>
 	 */
 	private Unit(String name, long type) {
+		if (name == null) {
+			name = computeName(type);
+		}
 		this.name = name;
 		this.type = type;
 		//System.out.println( name + " " + Long.toHexString( type ) );
@@ -338,7 +342,7 @@
 	 * @return This object's hash code.
 	 */
 	public int hashCode() {
-		return (int) ((type >>> 32) ^ type);
+		return 31 * 17 + (int) (type ^ (type >>> 32));
 	}
 
 	/**
@@ -435,16 +439,12 @@
 	 * 
 	 * @return the <code>Unit</code>
 	 */
-	static Unit find(long type) {
+	static synchronized Unit find(long type) {
 		if (base == null) {
-			synchronized (Unit.class) {
-				if (base == null) {
-					int size = allUnits.length;
-					base = new Hashtable(size << 1);
-					for (int i = 0; i < size; i++) {
-						base.put(allUnits[i], allUnits[i]);
-					}
-				}
+			int size = allUnits.length;
+			base = new Hashtable(size << 1);
+			for (int i = 0; i < size; i++) {
+				base.put(allUnits[i], allUnits[i]);
 			}
 		}
 		Unit unit = new Unit(null, type);
@@ -462,43 +462,39 @@
 	 * @return A <code>String</code> object representing the <code>Unit</code>
 	 */
 	public String toString() {
-		if (name == null) {
-			int m = (int) (((type >> m_SHIFT) & MASK) - ZERO);
-			int s = (int) (((type >> s_SHIFT) & MASK) - ZERO);
-			int kg = (int) (((type >> kg_SHIFT) & MASK) - ZERO);
-			int K = (int) (((type >> K_SHIFT) & MASK) - ZERO);
-			int A = (int) (((type >> A_SHIFT) & MASK) - ZERO);
-			int mol = (int) (((type >> mol_SHIFT) & MASK) - ZERO);
-			int cd = (int) (((type >> cd_SHIFT) & MASK) - ZERO);
-			int rad = (int) (((type >> rad_SHIFT) & MASK) - ZERO);
-			StringBuffer numerator = new StringBuffer();
-			StringBuffer denominator = new StringBuffer();
-			addSIname(m, "m", numerator, denominator);
-			addSIname(s, "s", numerator, denominator);
-			addSIname(kg, "kg", numerator, denominator);
-			addSIname(K, "K", numerator, denominator);
-			addSIname(A, "A", numerator, denominator);
-			addSIname(mol, "mol", numerator, denominator);
-			addSIname(cd, "cd", numerator, denominator);
-			addSIname(rad, "rad", numerator, denominator);
-			if (denominator.length() > 0) {
-				if (numerator.length() == 0) {
-					numerator.append("1");
-				}
-				numerator.append("/");
-				numerator.append((Object) denominator); /*
-														 * we use (Object) to
-														 * avoid using new 1.4
-														 * method
-														 * append(StringBuffer)
-														 */
-			}
-			name = numerator.toString();
-		}
 		return name;
 	}
 
-	private void addSIname(int si, String name, StringBuffer numerator,
+	private static String computeName(long type) {
+		int m = (int) (((type >> m_SHIFT) & MASK) - ZERO);
+		int s = (int) (((type >> s_SHIFT) & MASK) - ZERO);
+		int kg = (int) (((type >> kg_SHIFT) & MASK) - ZERO);
+		int K = (int) (((type >> K_SHIFT) & MASK) - ZERO);
+		int A = (int) (((type >> A_SHIFT) & MASK) - ZERO);
+		int mol = (int) (((type >> mol_SHIFT) & MASK) - ZERO);
+		int cd = (int) (((type >> cd_SHIFT) & MASK) - ZERO);
+		int rad = (int) (((type >> rad_SHIFT) & MASK) - ZERO);
+		StringBuffer numerator = new StringBuffer();
+		StringBuffer denominator = new StringBuffer();
+		addSIname(m, "m", numerator, denominator);
+		addSIname(s, "s", numerator, denominator);
+		addSIname(kg, "kg", numerator, denominator);
+		addSIname(K, "K", numerator, denominator);
+		addSIname(A, "A", numerator, denominator);
+		addSIname(mol, "mol", numerator, denominator);
+		addSIname(cd, "cd", numerator, denominator);
+		addSIname(rad, "rad", numerator, denominator);
+		if (denominator.length() > 0) {
+			if (numerator.length() == 0) {
+				numerator.append("1");
+			}
+			numerator.append("/");
+			numerator.append(denominator.toString()); 
+		}
+		return numerator.toString();
+	}
+	
+	private static void addSIname(int si, String name, StringBuffer numerator,
 			StringBuffer denominator) {
 		if (si != 0) {
 			StringBuffer sb = (si > 0) ? numerator : denominator;
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/package.html
new file mode 100644
index 0000000..2eb3a8c
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Measurement Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.measurement; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/measurement/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/packageinfo
new file mode 100644
index 0000000..c266447
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/measurement/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/mobile/UserPromptCondition.java b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/UserPromptCondition.java
index 423ba1a..3b40080 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/mobile/UserPromptCondition.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/UserPromptCondition.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.mobile/src/org/osgi/util/mobile/UserPromptCondition.java,v 1.26 2006/07/10 08:18:30 pnagy Exp $
- *
- * Copyright (c) OSGi Alliance (2004, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2004, 2008). 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.
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/mobile/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/package.html
new file mode 100644
index 0000000..5590197
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Mobile Conditions Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.mobile; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/mobile/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/packageinfo
new file mode 100644
index 0000000..a4f1546
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/mobile/packageinfo
@@ -0,0 +1 @@
+version 1.0
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/position/Position.java b/org.osgi.compendium/src/main/java/org/osgi/util/position/Position.java
index cf9e1ca..5fe3e0f 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/position/Position.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/position/Position.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.position/src/org/osgi/util/position/Position.java,v 1.9 2006/07/12 21:21:35 hargrave Exp $
- *
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2009). 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.
@@ -35,16 +33,19 @@
  * hashCode() because it is not clear how missing values should be handled. It
  * is up to the user of a position to determine how best to compare two position
  * objects. A <code>Position</code> object is immutable.
+ * 
+ * @Immutable
+ * @version $Revision: 6860 $
  */
 public class Position {
-	private Measurement	altitude;
-	private Measurement	longitude;
-	private Measurement	latitude;
-	private Measurement	speed;
-	private Measurement	track;
+	private final Measurement	altitude;
+	private final Measurement	longitude;
+	private final Measurement	latitude;
+	private final Measurement	speed;
+	private final Measurement	track;
 
 	/**
-	 * Contructs a <code>Position</code> object with the given values.
+	 * Constructs a <code>Position</code> object with the given values.
 	 * 
 	 * @param lat a <code>Measurement</code> object specifying the latitude in
 	 *        radians, or null
@@ -63,33 +64,87 @@
 			if (!Unit.rad.equals(lat.getUnit())) {
 				throw new IllegalArgumentException("Invalid Latitude");
 			}
-			this.latitude = lat;
 		}
 		if (lon != null) {
 			if (!Unit.rad.equals(lon.getUnit())) {
 				throw new IllegalArgumentException("Invalid Longitude");
 			}
-			this.longitude = lon;
 		}
-		normalizeLatLon();
 		if (alt != null) {
 			if (!Unit.m.equals(alt.getUnit())) {
 				throw new IllegalArgumentException("Invalid Altitude");
 			}
-			this.altitude = alt;
 		}
 		if (speed != null) {
 			if (!Unit.m_s.equals(speed.getUnit())) {
 				throw new IllegalArgumentException("Invalid Speed");
 			}
-			this.speed = speed;
 		}
 		if (track != null) {
 			if (!Unit.rad.equals(track.getUnit())) {
 				throw new IllegalArgumentException("Invalid Track");
 			}
-			this.track = normalizeTrack(track);
 		}
+
+		/*
+		 * Verify the longitude and latitude parameters so they fit the normal
+		 * coordinate system. A latitude is between -90 (south) and +90 (north).
+		 * A longitude is between -180 (Western hemisphere) and +180 (eastern
+		 * hemisphere). This method first normalizes the latitude and longitude
+		 * between +/- 180. If the |latitude| > 90, then the longitude is added
+		 * 180 and the latitude is normalized to fit +/-90. (Example are with
+		 * degrees though radians are used) <br> No normalization takes place
+		 * when either lon or lat is null.
+		 */
+		normalizeLatLon: {
+			if (lat == null || lon == null) {
+				break normalizeLatLon;
+			}
+			double dlat = lat.getValue();
+			double dlon = lon.getValue();
+			if (dlon >= -LON_RANGE && dlon < LON_RANGE && dlat >= -LAT_RANGE
+					&& dlat <= LAT_RANGE) {
+				break normalizeLatLon;
+			}
+			dlon = normalize(dlon, LON_RANGE);
+			dlat = normalize(dlat, LAT_RANGE * 2.0D); // First over 180 degree
+			// Check if we have to move to other side of the earth
+			if (dlat > LAT_RANGE || dlat < -LAT_RANGE) {
+				dlon = normalize(dlon - LON_RANGE, LON_RANGE);
+				dlat = normalize((LAT_RANGE * 2.0D) - dlat, LAT_RANGE);
+			}
+			lon = new Measurement(dlon, lon.getError(), lon.getUnit(), lon
+					.getTime());
+			lat = new Measurement(dlat, lat.getError(), lat.getUnit(), lat
+					.getTime());
+		}
+
+		/*
+		 * Normalize track to be a value such that: 0 <= value < +2PI. This
+		 * corresponds to 0 deg to +360 deg. 0 is North, 0.5PI is East, PI is
+		 * South, 1.5PI is West
+		 */
+		normalizeTrack: {
+			if (track == null) {
+				break normalizeTrack;
+			}
+			double dtrack = track.getValue();
+			if ((0.0D <= dtrack) && (dtrack < TRACK_RANGE)) {
+				break normalizeTrack; /* value is already normalized */
+			}
+			dtrack %= TRACK_RANGE;
+			if (dtrack < 0.0D) {
+				dtrack += TRACK_RANGE;
+			}
+			track = new Measurement(dtrack, track.getError(), track.getUnit(),
+					track.getTime());
+		}
+
+		this.latitude = lat;
+		this.longitude = lon;
+		this.altitude = alt;
+		this.speed = speed;
+		this.track = track;
 	}
 
 	/**
@@ -153,37 +208,6 @@
 	private static final double	LAT_RANGE	= Math.PI / 2.0D;
 
 	/**
-	 * Verify the longitude and latitude parameters so they fit the normal
-	 * coordinate system. A latitude is between -90 (south) and +90 (north). A A
-	 * longitude is between -180 (Western hemisphere) and +180 (eastern
-	 * hemisphere). This method first normalizes the latitude and longitude
-	 * between +/- 180. If the |latitude| > 90, then the longitude is added 180
-	 * and the latitude is normalized to fit +/-90. (Example are with degrees
-	 * though radians are used) <br>
-	 * No normalization takes place when either lon or lat is null.
-	 */
-	private void normalizeLatLon() {
-		if (longitude == null || latitude == null)
-			return;
-		double dlon = longitude.getValue();
-		double dlat = latitude.getValue();
-		if (dlon >= -LON_RANGE && dlon < LON_RANGE && dlat >= -LAT_RANGE
-				&& dlat <= LAT_RANGE)
-			return;
-		dlon = normalize(dlon, LON_RANGE);
-		dlat = normalize(dlat, LAT_RANGE * 2.0D); // First over 180 degree
-		// Check if we have to move to other side of the earth
-		if (dlat > LAT_RANGE || dlat < -LAT_RANGE) {
-			dlon = normalize(dlon - LON_RANGE, LON_RANGE);
-			dlat = normalize((LAT_RANGE * 2.0D) - dlat, LAT_RANGE);
-		}
-		longitude = new Measurement(dlon, longitude.getError(), longitude
-				.getUnit(), longitude.getTime());
-		latitude = new Measurement(dlat, latitude.getError(), latitude
-				.getUnit(), latitude.getTime());
-	}
-
-	/**
 	 * This function normalizes the a value according to a range. This is not
 	 * simple modulo (as I thought when I started), but requires some special
 	 * handling. For positive numbers we subtract 2*range from the number so
@@ -201,7 +225,7 @@
 	 * @param value The value that needs adjusting
 	 * @param range -range = < value < range
 	 */
-	private double normalize(double value, double range) {
+	private static double normalize(double value, double range) {
 		double twiceRange = 2.0D * range;
 		while (value >= range) {
 			value -= twiceRange;
@@ -213,25 +237,4 @@
 	}
 
 	private static final double	TRACK_RANGE	= Math.PI * 2.0D;
-
-	/**
-	 * Normalize track to be a value such that: 0 <= value < +2PI. This
-	 * corresponds to 0 deg to +360 deg. 0 is North 0.5*PI is East PI is South
-	 * 1.5*PI is West
-	 * 
-	 * @param track Value to be normalized
-	 * @return Normalized value
-	 */
-	private Measurement normalizeTrack(Measurement track) {
-		double value = track.getValue();
-		if ((0.0D <= value) && (value < TRACK_RANGE)) {
-			return track; /* value is already normalized */
-		}
-		value %= TRACK_RANGE;
-		if (value < 0.0D) {
-			value += TRACK_RANGE;
-		}
-		return new Measurement(value, track.getError(), track.getUnit(), track
-				.getTime());
-	}
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/position/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/position/package.html
new file mode 100644
index 0000000..d0d745f
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/position/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Position Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.position; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/position/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/position/packageinfo
new file mode 100644
index 0000000..c266447
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/position/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
\ No newline at end of file
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/AbstractTracked.java b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/AbstractTracked.java
new file mode 100644
index 0000000..681148f
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/AbstractTracked.java
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). 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.util.tracker;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Abstract class to track items. If a Tracker is reused (closed then reopened),
+ * then a new AbstractTracked object is used. This class acts a map of tracked
+ * item -> customized object. Subclasses of this class will act as the listener
+ * object for the tracker. This class is used to synchronize access to the
+ * tracked items. This is not a public class. It is only for use by the
+ * implementation of the Tracker class.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 5871 $
+ * @since 1.4
+ */
+abstract class AbstractTracked {
+	/* set this to true to compile in debug messages */
+	static final boolean		DEBUG	= false;
+
+	/**
+	 * Map of tracked items to customized objects.
+	 * 
+	 * @GuardedBy this
+	 */
+	private final Map			tracked;
+
+	/**
+	 * Modification count. This field is initialized to zero and incremented by
+	 * modified.
+	 * 
+	 * @GuardedBy this
+	 */
+	private int					trackingCount;
+
+	/**
+	 * List of items in the process of being added. This is used to deal with
+	 * nesting of events. Since events may be synchronously delivered, events
+	 * can be nested. For example, when processing the adding of a service and
+	 * the customizer causes the service to be unregistered, notification to the
+	 * nested call to untrack that the service was unregistered can be made to
+	 * the track method.
+	 * 
+	 * Since the ArrayList implementation is not synchronized, all access to
+	 * this list must be protected by the same synchronized object for
+	 * thread-safety.
+	 * 
+	 * @GuardedBy this
+	 */
+	private final List			adding;
+
+	/**
+	 * true if the tracked object is closed.
+	 * 
+	 * This field is volatile because it is set by one thread and read by
+	 * another.
+	 */
+	volatile boolean			closed;
+
+	/**
+	 * Initial list of items for the tracker. This is used to correctly process
+	 * the initial items which could be modified before they are tracked. This
+	 * is necessary since the initial set of tracked items are not "announced"
+	 * by events and therefore the event which makes the item untracked could be
+	 * delivered before we track the item.
+	 * 
+	 * An item must not be in both the initial and adding lists at the same
+	 * time. An item must be moved from the initial list to the adding list
+	 * "atomically" before we begin tracking it.
+	 * 
+	 * Since the LinkedList implementation is not synchronized, all access to
+	 * this list must be protected by the same synchronized object for
+	 * thread-safety.
+	 * 
+	 * @GuardedBy this
+	 */
+	private final LinkedList	initial;
+
+	/**
+	 * AbstractTracked constructor.
+	 */
+	AbstractTracked() {
+		tracked = new HashMap();
+		trackingCount = 0;
+		adding = new ArrayList(6);
+		initial = new LinkedList();
+		closed = false;
+	}
+
+	/**
+	 * Set initial list of items into tracker before events begin to be
+	 * received.
+	 * 
+	 * 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>
+	 *        entries in the list are ignored.
+	 * @GuardedBy this
+	 */
+	void setInitial(Object[] list) {
+		if (list == null) {
+			return;
+		}
+		int size = list.length;
+		for (int i = 0; i < size; i++) {
+			Object item = list[i];
+			if (item == null) {
+				continue;
+			}
+			if (DEBUG) {
+				System.out.println("AbstractTracked.setInitial: " + item); //$NON-NLS-1$
+			}
+			initial.add(item);
+		}
+	}
+
+	/**
+	 * Track the initial list of items. This is called after events can begin to
+	 * be received.
+	 * 
+	 * This method must be called from Tracker's open method while not
+	 * synchronized on this object after the add listener call.
+	 * 
+	 */
+	void trackInitial() {
+		while (true) {
+			Object item;
+			synchronized (this) {
+				if (closed || (initial.size() == 0)) {
+					/*
+					 * if there are no more initial items
+					 */
+					return; /* we are done */
+				}
+				/*
+				 * move the first item from the initial list to the adding list
+				 * within this synchronized block.
+				 */
+				item = initial.removeFirst();
+				if (tracked.get(item) != null) {
+					/* if we are already tracking this item */
+					if (DEBUG) {
+						System.out
+								.println("AbstractTracked.trackInitial[already tracked]: " + item); //$NON-NLS-1$
+					}
+					continue; /* skip this item */
+				}
+				if (adding.contains(item)) {
+					/*
+					 * if this item is already in the process of being added.
+					 */
+					if (DEBUG) {
+						System.out
+								.println("AbstractTracked.trackInitial[already adding]: " + item); //$NON-NLS-1$
+					}
+					continue; /* skip this item */
+				}
+				adding.add(item);
+			}
+			if (DEBUG) {
+				System.out.println("AbstractTracked.trackInitial: " + item); //$NON-NLS-1$
+			}
+			trackAdding(item, null); /*
+									 * Begin tracking it. We call trackAdding
+									 * since we have already put the item in the
+									 * adding list.
+									 */
+		}
+	}
+
+	/**
+	 * Called by the owning Tracker object when it is closed.
+	 */
+	void close() {
+		closed = true;
+	}
+
+	/**
+	 * Begin to track an item.
+	 * 
+	 * @param item Item to be tracked.
+	 * @param related Action related object.
+	 */
+	void track(final Object item, final Object related) {
+		final Object object;
+		synchronized (this) {
+			if (closed) {
+				return;
+			}
+			object = tracked.get(item);
+			if (object == null) { /* we are not tracking the item */
+				if (adding.contains(item)) {
+					/* if this item is already in the process of being added. */
+					if (DEBUG) {
+						System.out
+								.println("AbstractTracked.track[already adding]: " + item); //$NON-NLS-1$
+					}
+					return;
+				}
+				adding.add(item); /* mark this item is being added */
+			}
+			else { /* we are currently tracking this item */
+				if (DEBUG) {
+					System.out
+							.println("AbstractTracked.track[modified]: " + item); //$NON-NLS-1$
+				}
+				modified(); /* increment modification count */
+			}
+		}
+
+		if (object == null) { /* we are not tracking the item */
+			trackAdding(item, related);
+		}
+		else {
+			/* Call customizer outside of synchronized region */
+			customizerModified(item, related, object);
+			/*
+			 * If the customizer throws an unchecked exception, it is safe to
+			 * let it propagate
+			 */
+		}
+	}
+
+	/**
+	 * Common logic to add an item to the tracker used by track and
+	 * trackInitial. The specified item must have been placed in the adding list
+	 * before calling this method.
+	 * 
+	 * @param item Item to be tracked.
+	 * @param related Action related object.
+	 */
+	private void trackAdding(final Object item, final Object related) {
+		if (DEBUG) {
+			System.out.println("AbstractTracked.trackAdding: " + item); //$NON-NLS-1$
+		}
+		Object object = null;
+		boolean becameUntracked = false;
+		/* Call customizer outside of synchronized region */
+		try {
+			object = customizerAdding(item, related);
+			/*
+			 * If the customizer throws an unchecked exception, it will
+			 * propagate after the finally
+			 */
+		}
+		finally {
+			synchronized (this) {
+				if (adding.remove(item) && !closed) {
+					/*
+					 * if the item was not untracked during the customizer
+					 * callback
+					 */
+					if (object != null) {
+						tracked.put(item, object);
+						modified(); /* increment modification count */
+						notifyAll(); /* notify any waiters */
+					}
+				}
+				else {
+					becameUntracked = true;
+				}
+			}
+		}
+		/*
+		 * The item became untracked during the customizer callback.
+		 */
+		if (becameUntracked && (object != null)) {
+			if (DEBUG) {
+				System.out
+						.println("AbstractTracked.trackAdding[removed]: " + item); //$NON-NLS-1$
+			}
+			/* Call customizer outside of synchronized region */
+			customizerRemoved(item, related, object);
+			/*
+			 * If the customizer throws an unchecked exception, it is safe to
+			 * let it propagate
+			 */
+		}
+	}
+
+	/**
+	 * Discontinue tracking the item.
+	 * 
+	 * @param item Item to be untracked.
+	 * @param related Action related object.
+	 */
+	void untrack(final Object item, final Object related) {
+		final Object object;
+		synchronized (this) {
+			if (initial.remove(item)) { /*
+										 * if this item is already in the list
+										 * of initial references to process
+										 */
+				if (DEBUG) {
+					System.out
+							.println("AbstractTracked.untrack[removed from initial]: " + item); //$NON-NLS-1$
+				}
+				return; /*
+						 * we have removed it from the list and it will not be
+						 * processed
+						 */
+			}
+
+			if (adding.remove(item)) { /*
+										 * if the item is in the process of
+										 * being added
+										 */
+				if (DEBUG) {
+					System.out
+							.println("AbstractTracked.untrack[being added]: " + item); //$NON-NLS-1$
+				}
+				return; /*
+						 * in case the item is untracked while in the process of
+						 * adding
+						 */
+			}
+			object = tracked.remove(item); /*
+											 * must remove from tracker before
+											 * calling customizer callback
+											 */
+			if (object == null) { /* are we actually tracking the item */
+				return;
+			}
+			modified(); /* increment modification count */
+		}
+		if (DEBUG) {
+			System.out.println("AbstractTracked.untrack[removed]: " + item); //$NON-NLS-1$
+		}
+		/* Call customizer outside of synchronized region */
+		customizerRemoved(item, related, object);
+		/*
+		 * If the customizer throws an unchecked exception, it is safe to let it
+		 * propagate
+		 */
+	}
+
+	/**
+	 * Returns the number of tracked items.
+	 * 
+	 * @return The number of tracked items.
+	 * 
+	 * @GuardedBy this
+	 */
+	int size() {
+		return tracked.size();
+	}
+
+	/**
+	 * Return the customized object for the specified item
+	 * 
+	 * @param item The item to lookup in the map
+	 * @return The customized object for the specified item.
+	 * 
+	 * @GuardedBy this
+	 */
+	Object getCustomizedObject(final Object item) {
+		return tracked.get(item);
+	}
+
+	/**
+	 * Return the list of tracked items.
+	 * 
+	 * @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) {
+		return tracked.keySet().toArray(list);
+	}
+
+	/**
+	 * Increment the modification count. If this method is overridden, the
+	 * overriding method MUST call this method to increment the tracking count.
+	 * 
+	 * @GuardedBy this
+	 */
+	void modified() {
+		trackingCount++;
+	}
+
+	/**
+	 * Returns the tracking count for this <code>ServiceTracker</code> 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
+	 * count is incremented.
+	 * 
+	 * @GuardedBy this
+	 * @return The tracking count for this object.
+	 */
+	int getTrackingCount() {
+		return trackingCount;
+	}
+
+	/**
+	 * 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
+	 *         the item is not to be tracked.
+	 */
+	abstract Object customizerAdding(final Object item, final Object related);
+
+	/**
+	 * Call the specific customizer modified method. This method must not be
+	 * called while synchronized on this object.
+	 * 
+	 * @param item Tracked item.
+	 * @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);
+
+	/**
+	 * Call the specific customizer removed method. This method must not be
+	 * called while synchronized on this object.
+	 * 
+	 * @param item Tracked item.
+	 * @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);
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTracker.java b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTracker.java
new file mode 100644
index 0000000..8791d98
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTracker.java
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). 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.util.tracker;
+
+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.
+ * <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
+ * 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
+ * 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
+ * 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
+ * thread-safe.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 5894 $
+ * @since 1.4
+ */
+public class BundleTracker implements BundleTrackerCustomizer {
+	/* set this to true to compile in debug messages */
+	static final boolean			DEBUG	= false;
+
+	/**
+	 * The Bundle Context used by this <code>BundleTracker</code>.
+	 */
+	protected final BundleContext	context;
+
+	/**
+	 * The <code>BundleTrackerCustomizer</code> object for this tracker.
+	 */
+	final BundleTrackerCustomizer	customizer;
+
+	/**
+	 * Tracked bundles: <code>Bundle</code> object -> customized Object and
+	 * <code>BundleListener</code> object
+	 */
+	private volatile Tracked		tracked;
+
+	/**
+	 * Accessor method for the current Tracked object. This method is only
+	 * intended to be used by the unsynchronized methods which do not modify the
+	 * tracked field.
+	 * 
+	 * @return The current Tracked object.
+	 */
+	private Tracked tracked() {
+		return tracked;
+	}
+
+	/**
+	 * State mask for bundles being tracked. This field contains the ORed values
+	 * of the bundle states being tracked.
+	 */
+	final int						mask;
+
+	/**
+	 * Create a <code>BundleTracker</code> 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>.
+	 * 
+	 * @param context The <code>BundleContext</code> against which the tracking
+	 *        is done.
+	 * @param stateMask The bit mask of the <code>OR</code>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.
+	 * @see Bundle#getState()
+	 */
+	public BundleTracker(BundleContext context, int stateMask,
+			BundleTrackerCustomizer customizer) {
+		this.context = context;
+		this.mask = stateMask;
+		this.customizer = (customizer == null) ? this : customizer;
+	}
+
+	/**
+	 * Open this <code>BundleTracker</code> 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>.
+	 * 
+	 * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+	 *         with which this <code>BundleTracker</code> 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
+	 *         Java Runtime Environment supports permissions.
+	 */
+	public void open() {
+		final Tracked t;
+		synchronized (this) {
+			if (tracked != null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("BundleTracker.open"); //$NON-NLS-1$
+			}
+			t = new Tracked();
+			synchronized (t) {
+				context.addBundleListener(t);
+				Bundle[] bundles = context.getBundles();
+				if (bundles != null) {
+					int length = bundles.length;
+					for (int i = 0; i < length; i++) {
+						int state = bundles[i].getState();
+						if ((state & mask) == 0) {
+							/* null out bundles whose states are not interesting */
+							bundles[i] = null;
+						}
+					}
+					/* set tracked with the initial bundles */
+					t.setInitial(bundles); 
+				}
+			}
+			tracked = t;
+		}
+		/* Call tracked outside of synchronized region */
+		t.trackInitial(); /* process the initial references */
+	}
+
+	/**
+	 * Close this <code>BundleTracker</code>.
+	 * 
+	 * <p>
+	 * This method should be called when this <code>BundleTracker</code> should
+	 * end the tracking of bundles.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getBundles()} to get the list of
+	 * tracked bundles to remove.
+	 */
+	public void close() {
+		final Bundle[] bundles;
+		final Tracked outgoing;
+		synchronized (this) {
+			outgoing = tracked;
+			if (outgoing == null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("BundleTracker.close"); //$NON-NLS-1$
+			}
+			outgoing.close();
+			bundles = getBundles();
+			tracked = null;
+			try {
+				context.removeBundleListener(outgoing);
+			}
+			catch (IllegalStateException e) {
+				/* In case the context was stopped. */
+			}
+		}
+		if (bundles != null) {
+			for (int i = 0; i < bundles.length; i++) {
+				outgoing.untrack(bundles[i], null);
+			}
+		}
+	}
+
+	/**
+	 * Default implementation of the
+	 * <code>BundleTrackerCustomizer.addingBundle</code> method.
+	 * 
+	 * <p>
+	 * This method is only called when this <code>BundleTracker</code> has been
+	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+	 * 
+	 * <p>
+	 * This implementation simply returns the specified <code>Bundle</code>.
+	 * 
+	 * <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 event The bundle event which caused this customizer method to be
+	 *        called or <code>null</code> 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;
+	}
+
+	/**
+	 * Default implementation of the
+	 * <code>BundleTrackerCustomizer.modifiedBundle</code> method.
+	 * 
+	 * <p>
+	 * This method is only called when this <code>BundleTracker</code> has been
+	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+	 * 
+	 * <p>
+	 * This implementation does nothing.
+	 * 
+	 * @param bundle The <code>Bundle</code> 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
+	 *        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) {
+		/* do nothing */
+	}
+
+	/**
+	 * Default implementation of the
+	 * <code>BundleTrackerCustomizer.removedBundle</code> method.
+	 * 
+	 * <p>
+	 * This method is only called when this <code>BundleTracker</code> has been
+	 * constructed with a <code>null BundleTrackerCustomizer</code> argument.
+	 * 
+	 * <p>
+	 * This implementation does nothing.
+	 * 
+	 * @param bundle The <code>Bundle</code> 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
+	 *        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) {
+		/* 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</code>s or <code>null</code> if no
+	 *         bundles are being tracked.
+	 */
+	public Bundle[] getBundles() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			int length = t.size();
+			if (length == 0) {
+				return null;
+			}
+			return (Bundle[]) t.getTracked(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>.
+	 * 
+	 * @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
+	 *         being tracked.
+	 */
+	public Object getObject(Bundle bundle) {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return null;
+		}
+		synchronized (t) {
+			return t.getCustomizedObject(bundle);
+		}
+	}
+
+	/**
+	 * Remove a bundle from this <code>BundleTracker</code>.
+	 * 
+	 * The specified bundle will be removed from this <code>BundleTracker</code>
+	 * . If the specified bundle was being tracked then the
+	 * <code>BundleTrackerCustomizer.removedBundle</code> method will be called
+	 * for that bundle.
+	 * 
+	 * @param bundle The <code>Bundle</code> to be removed.
+	 */
+	public void remove(Bundle bundle) {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return;
+		}
+		t.untrack(bundle, null);
+	}
+
+	/**
+	 * Return the number of bundles being tracked by this
+	 * <code>BundleTracker</code>.
+	 * 
+	 * @return The number of bundles being tracked.
+	 */
+	public int size() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return 0;
+		}
+		synchronized (t) {
+			return t.size();
+		}
+	}
+
+	/**
+	 * Returns the tracking count for this <code>BundleTracker</code>.
+	 * 
+	 * 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.
+	 * 
+	 * <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.
+	 * 
+	 * @return The tracking count for this <code>BundleTracker</code> or -1 if
+	 *         this <code>BundleTracker</code> is not open.
+	 */
+	public int getTrackingCount() {
+		final Tracked t = tracked();
+		if (t == null) { /* if BundleTracker is not open */
+			return -1;
+		}
+		synchronized (t) {
+			return t.getTrackingCount();
+		}
+	}
+
+	/**
+	 * Inner class which subclasses AbstractTracked. This class is the
+	 * <code>SynchronousBundleListener</code> object for the tracker.
+	 * 
+	 * @ThreadSafe
+	 * @since 1.4
+	 */
+	class Tracked extends AbstractTracked implements SynchronousBundleListener {
+		/**
+		 * Tracked constructor.
+		 */
+		Tracked() {
+			super();
+		}
+
+		/**
+		 * <code>BundleListener</code> method for the <code>BundleTracker</code>
+		 * class. This method must NOT be synchronized to avoid deadlock
+		 * potential.
+		 * 
+		 * @param event <code>BundleEvent</code> object from the framework.
+		 */
+		public void bundleChanged(final BundleEvent event) {
+			/*
+			 * Check if we had a delayed call (which could happen when we
+			 * close).
+			 */
+			if (closed) {
+				return;
+			}
+			final Bundle bundle = event.getBundle();
+			final int state = bundle.getState();
+			if (DEBUG) {
+				System.out
+						.println("BundleTracker.Tracked.bundleChanged[" + state + "]: " + bundle); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+
+			if ((state & mask) != 0) {
+				track(bundle, event);
+				/*
+				 * If the customizer throws an unchecked exception, it is safe
+				 * to let it propagate
+				 */
+			}
+			else {
+				untrack(bundle, event);
+				/*
+				 * If the customizer throws an unchecked exception, it is safe
+				 * to let it propagate
+				 */
+			}
+		}
+
+		/**
+		 * 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 the item is not to be tracked.
+		 */
+		Object customizerAdding(final Object item,
+				final Object related) {
+			return customizer
+					.addingBundle((Bundle) item, (BundleEvent) related);
+		}
+
+		/**
+		 * Call the specific customizer modified method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @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);
+		}
+
+		/**
+		 * Call the specific customizer removed method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @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);
+		}
+	}
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java
new file mode 100644
index 0000000..100c6b4
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/BundleTrackerCustomizer.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) OSGi Alliance (2007, 2008). 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.util.tracker;
+
+import org.osgi.framework.Bundle;
+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
+ * tracked bundle is modified or has been removed from a
+ * <code>BundleTracker</code>.
+ * 
+ * <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
+ * 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
+ * thread-safe.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 5874 $
+ * @since 1.4
+ */
+public interface BundleTrackerCustomizer {
+	/**
+	 * A bundle is being added to the <code>BundleTracker</code>.
+	 * 
+	 * <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
+	 * {@link BundleTracker#getObject(Bundle) getObject} method.
+	 * 
+	 * @param bundle The <code>Bundle</code> being added to the
+	 *        <code>BundleTracker</code>.
+	 * @param event The bundle event which caused this customizer method to be
+	 *        called or <code>null</code> 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>
+	 *         object should not be tracked.
+	 */
+	public Object addingBundle(Bundle bundle, BundleEvent event);
+
+	/**
+	 * A bundle tracked by the <code>BundleTracker</code> has been modified.
+	 * 
+	 * <p>
+	 * This method is called when a bundle being tracked by the
+	 * <code>BundleTracker</code> has had its state modified.
+	 * 
+	 * @param bundle The <code>Bundle</code> 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
+	 *        with the call to this method.
+	 * @param object The tracked object for the specified bundle.
+	 */
+	public void modifiedBundle(Bundle bundle, BundleEvent event,
+			Object object);
+
+	/**
+	 * A bundle tracked by the <code>BundleTracker</code> has been removed.
+	 * 
+	 * <p>
+	 * This method is called after a bundle is no longer being tracked by the
+	 * <code>BundleTracker</code>.
+	 * 
+	 * @param bundle The <code>Bundle</code> 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
+	 *        with the call to this method.
+	 * @param object The tracked object for the specified bundle.
+	 */
+	public void removedBundle(Bundle bundle, BundleEvent event,
+			Object object);
+}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTracker.java b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTracker.java
index c945088..b4e373b 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTracker.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTracker.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTracker.java,v 1.29 2007/02/19 19:04:33 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2009). 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,53 +16,61 @@
 
 package org.osgi.util.tracker;
 
-import java.util.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
-import org.osgi.framework.*;
+import org.osgi.framework.AllServiceListener;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+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
  * 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> object can use the
- * <code>ServiceTrackerCustomizer</code> object to customize the service
- * objects to be tracked. The <code>ServiceTracker</code> object 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>
- * object correctly handles all of the details of listening to
- * <code>ServiceEvent</code> objects and getting and ungetting services.
+ * 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
+ * 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
+ * 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 tracked service.
+ * 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 tracked service.
  * <p>
  * The <code>ServiceTracker</code> class is thread-safe. It does not call a
- * <code>ServiceTrackerCustomizer</code> object while holding any locks.
+ * <code>ServiceTrackerCustomizer</code> while holding any locks.
  * <code>ServiceTrackerCustomizer</code> implementations must also be
  * thread-safe.
  * 
  * @ThreadSafe
- * @version $Revision: 1.29 $
+ * @version $Revision: 6386 $
  */
 public class ServiceTracker implements ServiceTrackerCustomizer {
 	/* set this to true to compile in debug messages */
 	static final boolean				DEBUG			= false;
 	/**
-	 * Bundle context against which this <code>ServiceTracker</code> object is
-	 * tracking.
+	 * The Bundle Context used by this <code>ServiceTracker</code>.
 	 */
 	protected final BundleContext		context;
 	/**
-	 * Filter specifying search criteria for the services to track.
+	 * The Filter used by this <code>ServiceTracker</code> which specifies the
+	 * search criteria for the services to track.
 	 * 
 	 * @since 1.1
 	 */
 	protected final Filter				filter;
 	/**
-	 * <code>ServiceTrackerCustomizer</code> object for this tracker.
+	 * The <code>ServiceTrackerCustomizer</code> for this tracker.
 	 */
 	final ServiceTrackerCustomizer		customizer;
 	/**
@@ -84,17 +90,22 @@
 	 */
 	private final ServiceReference		trackReference;
 	/**
-	 * Tracked services: <code>ServiceReference</code> object -> customized
-	 * Object and <code>ServiceListener</code> object
+	 * Tracked services: <code>ServiceReference</code> -> customized Object and
+	 * <code>ServiceListener</code> object
 	 */
 	private volatile Tracked			tracked;
+
 	/**
-	 * Modification count. This field is initialized to zero by open, set to -1
-	 * by close and incremented by modified.
+	 * Accessor method for the current Tracked object. This method is only
+	 * intended to be used by the unsynchronized methods which do not modify the
+	 * tracked field.
 	 * 
-	 * This field is volatile since it is accessed by multiple threads.
+	 * @return The current Tracked object.
 	 */
-	private volatile int				trackingCount	= -1;
+	private Tracked tracked() {
+		return tracked;
+	}
+
 	/**
 	 * Cached ServiceReference for getServiceReference.
 	 * 
@@ -109,126 +120,153 @@
 	private volatile Object				cachedService;
 
 	/**
-	 * Create a <code>ServiceTracker</code> object on the specified
-	 * <code>ServiceReference</code> object.
+	 * 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>.
 	 * 
 	 * <p>
 	 * The service referenced by the specified <code>ServiceReference</code>
-	 * object will be tracked by this <code>ServiceTracker</code> object.
+	 * will be tracked by this <code>ServiceTracker</code>.
 	 * 
-	 * @param context <code>BundleContext</code> object against which the
-	 *        tracking is done.
-	 * @param reference <code>ServiceReference</code> object for the service
-	 *        to be tracked.
+	 * @param context The <code>BundleContext</code> against which the tracking
+	 *        is done.
+	 * @param reference The <code>ServiceReference</code> 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> object.
-	 *        If customizer is <code>null</code>, then this
-	 *        <code>ServiceTracker</code> object will be used as the
-	 *        <code>ServiceTrackerCustomizer</code> object and the
-	 *        <code>ServiceTracker</code> object will call the
+	 *        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.
 	 */
-	public ServiceTracker(BundleContext context, ServiceReference reference,
-			ServiceTrackerCustomizer customizer) {
+	public ServiceTracker(final BundleContext context,
+			final ServiceReference reference,
+			final ServiceTrackerCustomizer 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() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		this.listenerFilter = "(" + Constants.SERVICE_ID + "="
+				+ reference.getProperty(Constants.SERVICE_ID).toString() + ")"; 
 		try {
 			this.filter = context.createFilter(listenerFilter);
 		}
-		catch (InvalidSyntaxException e) { // we could only get this exception
-			// if the ServiceReference was
-			// invalid
-			throw new IllegalArgumentException(
-					"unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+		catch (InvalidSyntaxException e) {
+			/*
+			 * we could only get this exception if the ServiceReference was
+			 * invalid
+			 */
+			IllegalArgumentException iae = new IllegalArgumentException(
+					"unexpected InvalidSyntaxException: " + e.getMessage());
+			iae.initCause(e);
+			throw iae;
 		}
 	}
 
 	/**
-	 * Create a <code>ServiceTracker</code> object on the specified class
-	 * name.
+	 * Create a <code>ServiceTracker</code> on the specified class name.
 	 * 
 	 * <p>
 	 * Services registered under the specified class name will be tracked by
-	 * this <code>ServiceTracker</code> object.
+	 * this <code>ServiceTracker</code>.
 	 * 
-	 * @param context <code>BundleContext</code> object against which the
-	 *        tracking is done.
-	 * @param clazz Class name of the services to be tracked.
+	 * @param context The <code>BundleContext</code> 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> object.
-	 *        If customizer is <code>null</code>, then this
-	 *        <code>ServiceTracker</code> object will be used as the
-	 *        <code>ServiceTrackerCustomizer</code> object and the
-	 *        <code>ServiceTracker</code> object will call the
+	 *        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.
 	 */
-	public ServiceTracker(BundleContext context, String clazz,
-			ServiceTrackerCustomizer customizer) {
+	public ServiceTracker(final BundleContext context, final String clazz,
+			final ServiceTrackerCustomizer customizer) {
 		this.context = context;
 		this.trackReference = null;
 		this.trackClass = clazz;
 		this.customizer = (customizer == null) ? this : customizer;
-		this.listenerFilter = "(" + Constants.OBJECTCLASS + "=" + clazz.toString() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+		// we call clazz.toString to verify clazz is non-null!
+		this.listenerFilter = "(" + Constants.OBJECTCLASS + "="
+				+ clazz.toString() + ")"; 
 		try {
 			this.filter = context.createFilter(listenerFilter);
 		}
-		catch (InvalidSyntaxException e) { // we could only get this exception
-			// if the clazz argument was
-			// malformed
-			throw new IllegalArgumentException(
-					"unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
+		catch (InvalidSyntaxException e) {
+			/*
+			 * we could only get this exception if the clazz argument was
+			 * malformed
+			 */
+			IllegalArgumentException iae = new IllegalArgumentException(
+					"unexpected InvalidSyntaxException: " + e.getMessage());
+			iae.initCause(e);
+			throw iae;
 		}
 	}
 
 	/**
-	 * Create a <code>ServiceTracker</code> object on the specified
-	 * <code>Filter</code> object.
+	 * Create a <code>ServiceTracker</code> on the specified <code>Filter</code>
+	 * object.
 	 * 
 	 * <p>
 	 * Services which match the specified <code>Filter</code> object will be
-	 * tracked by this <code>ServiceTracker</code> object.
+	 * tracked by this <code>ServiceTracker</code>.
 	 * 
-	 * @param context <code>BundleContext</code> object against which the
-	 *        tracking is done.
-	 * @param filter <code>Filter</code> object to select the services to be
+	 * @param context The <code>BundleContext</code> against which the tracking
+	 *        is done.
+	 * @param filter The <code>Filter</code> 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> object.
-	 *        If customizer is null, then this <code>ServiceTracker</code>
-	 *        object will be used as the <code>ServiceTrackerCustomizer</code>
-	 *        object and the <code>ServiceTracker</code> object will call the
+	 *        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.
 	 * @since 1.1
 	 */
-	public ServiceTracker(BundleContext context, Filter filter,
-			ServiceTrackerCustomizer customizer) {
+	public ServiceTracker(final BundleContext context, final Filter filter,
+			final ServiceTrackerCustomizer customizer) {
 		this.context = context;
 		this.trackReference = null;
 		this.trackClass = null;
-		this.listenerFilter = 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.filter = filter;
 		this.customizer = (customizer == null) ? this : customizer;
-		if ((context == null) || (filter == null)) { // we throw a NPE here
-			// to
-			// be consistent with the
-			// other constructors
+		if ((context == null) || (filter == null)) {
+			/*
+			 * we throw a NPE here to be consistent with the other constructors
+			 */
 			throw new NullPointerException();
 		}
 	}
 
 	/**
-	 * Open this <code>ServiceTracker</code> object and begin tracking
-	 * services.
+	 * Open this <code>ServiceTracker</code> and begin tracking services.
 	 * 
 	 * <p>
-	 * This method calls <code>open(false)</code>.
+	 * This implementation calls <code>open(false)</code>.
 	 * 
-	 * @throws java.lang.IllegalStateException if the <code>BundleContext</code>
-	 *         object with which this <code>ServiceTracker</code> object was
-	 *         created is no longer valid.
+	 * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+	 *         with which this <code>ServiceTracker</code> was created is no
+	 *         longer valid.
 	 * @see #open(boolean)
 	 */
 	public void open() {
@@ -236,122 +274,140 @@
 	}
 
 	/**
-	 * Open this <code>ServiceTracker</code> object and begin tracking
-	 * services.
+	 * Open this <code>ServiceTracker</code> and begin tracking services.
 	 * 
 	 * <p>
 	 * Services which match the search criteria specified when this
-	 * <code>ServiceTracker</code> object was created are now tracked by this
-	 * <code>ServiceTracker</code> object.
+	 * <code>ServiceTracker</code> was created are now tracked by this
+	 * <code>ServiceTracker</code>.
 	 * 
 	 * @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
-	 *        services which are class loader accessibile to the bundle whose
+	 *        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>
-	 *         object with which this <code>ServiceTracker</code> object was
-	 *         created is no longer valid.
+	 * @throws java.lang.IllegalStateException If the <code>BundleContext</code>
+	 *         with which this <code>ServiceTracker</code> was created is no
+	 *         longer valid.
 	 * @since 1.3
 	 */
-	public synchronized void open(boolean trackAllServices) {
-		if (tracked != null) {
-			return;
-		}
-		if (DEBUG) {
-			System.out.println("ServiceTracker.open: " + filter); //$NON-NLS-1$
-		}
-		tracked = trackAllServices ? new AllTracked() : new Tracked();
-		trackingCount = 0;
-		synchronized (tracked) {
-			try {
-				context.addServiceListener(tracked, listenerFilter);
-				ServiceReference[] references;
-				if (listenerFilter == null) { // user supplied filter
-					references = getInitialReferences(trackAllServices, null,
-							filter.toString());
-				}
-				else { // constructor supplied filter
-					if (trackClass == null) {
-						references = new ServiceReference[] {trackReference};
-					}
-					else {
+	public void open(boolean trackAllServices) {
+		final Tracked t;
+		synchronized (this) {
+			if (tracked != null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("ServiceTracker.open: " + filter); 
+			}
+			t = trackAllServices ? new AllTracked() : new Tracked();
+			synchronized (t) {
+				try {
+					context.addServiceListener(t, listenerFilter);
+					ServiceReference[] references = null;
+					if (trackClass != null) {
 						references = getInitialReferences(trackAllServices,
 								trackClass, null);
 					}
+					else {
+						if (trackReference != null) {
+							if (trackReference.getBundle() != null) {
+								references = new ServiceReference[] {trackReference};
+							}
+						}
+						else { /* user supplied filter */
+							references = getInitialReferences(trackAllServices,
+									null,
+									(listenerFilter != null) ? listenerFilter
+											: filter.toString());
+						}
+					}
+					/* set tracked with the initial references */
+					t.setInitial(references); 
 				}
-
-				tracked.setInitialServices(references); // set tracked with
-				// the initial
-				// references
+				catch (InvalidSyntaxException e) {
+					throw new RuntimeException(
+							"unexpected InvalidSyntaxException: "
+									+ e.getMessage(), e); 
+				}
 			}
-			catch (InvalidSyntaxException e) {
-				throw new RuntimeException(
-						"unexpected InvalidSyntaxException: " + e.getMessage()); //$NON-NLS-1$
-			}
+			tracked = t;
 		}
 		/* Call tracked outside of synchronized region */
-		tracked.trackInitialServices(); // process the initial references
+		t.trackInitial(); /* process the initial references */
 	}
 
 	/**
-	 * Returns the list of initial <code>ServiceReference</code> objects that
-	 * will be tracked by this <code>ServiceTracker</code> object.
+	 * Returns the list of initial <code>ServiceReference</code>s that will be
+	 * tracked by this <code>ServiceTracker</code>.
 	 * 
-	 * @param trackAllServices If true, use getAllServiceReferences.
-	 * @param trackClass the class name with which the service was registered,
-	 *        or null for all services.
-	 * @param filterString the filter criteria or null for all services.
-	 * @return the list of initial <code>ServiceReference</code> objects.
-	 * @throws InvalidSyntaxException if the filter uses an invalid syntax.
+	 * @param trackAllServices If <code>true</code>, use
+	 *        <code>getAllServiceReferences</code>.
+	 * @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
+	 *        services.
+	 * @return The list of initial <code>ServiceReference</code>s.
+	 * @throws InvalidSyntaxException If the specified filterString has an
+	 *         invalid syntax.
 	 */
 	private ServiceReference[] getInitialReferences(boolean trackAllServices,
-			String trackClass, String filterString)
+			String className, String filterString)
 			throws InvalidSyntaxException {
 		if (trackAllServices) {
-			return context.getAllServiceReferences(trackClass, filterString);
+			return context.getAllServiceReferences(className, filterString);
 		}
-		else {
-			return context.getServiceReferences(trackClass, filterString);
-		}
+		return context.getServiceReferences(className, filterString);
 	}
 
 	/**
-	 * Close this <code>ServiceTracker</code> object.
+	 * Close this <code>ServiceTracker</code>.
 	 * 
 	 * <p>
-	 * This method should be called when this <code>ServiceTracker</code>
-	 * object should end the tracking of services.
+	 * This method should be called when this <code>ServiceTracker</code> should
+	 * end the tracking of services.
+	 * 
+	 * <p>
+	 * This implementation calls {@link #getServiceReferences()} to get the list
+	 * of tracked services to remove.
 	 */
-	public synchronized void close() {
-		if (tracked == null) {
-			return;
+	public void close() {
+		final Tracked outgoing;
+		final ServiceReference[] references;
+		synchronized (this) {
+			outgoing = tracked;
+			if (outgoing == null) {
+				return;
+			}
+			if (DEBUG) {
+				System.out.println("ServiceTracker.close: " + filter); 
+			}
+			outgoing.close();
+			references = getServiceReferences();
+			tracked = null;
+			try {
+				context.removeServiceListener(outgoing);
+			}
+			catch (IllegalStateException e) {
+				/* In case the context was stopped. */
+			}
 		}
-		if (DEBUG) {
-			System.out.println("ServiceTracker.close: " + filter); //$NON-NLS-1$
-		}
-		tracked.close();
-		ServiceReference[] references = getServiceReferences();
-		Tracked outgoing = tracked;
-		tracked = null;
-		try {
-			context.removeServiceListener(outgoing);
-		}
-		catch (IllegalStateException e) {
-			/* In case the context was stopped. */
+		modified(); /* clear the cache */
+		synchronized (outgoing) {
+			outgoing.notifyAll(); /* wake up any waiters */
 		}
 		if (references != null) {
 			for (int i = 0; i < references.length; i++) {
-				outgoing.untrack(references[i]);
+				outgoing.untrack(references[i], null);
 			}
 		}
-		trackingCount = -1;
 		if (DEBUG) {
 			if ((cachedReference == null) && (cachedService == null)) {
 				System.out
-						.println("ServiceTracker.close[cached cleared]: " + filter); //$NON-NLS-1$
+						.println("ServiceTracker.close[cached cleared]: "
+						+ filter); 
 			}
 		}
 	}
@@ -361,25 +417,26 @@
 	 * <code>ServiceTrackerCustomizer.addingService</code> method.
 	 * 
 	 * <p>
-	 * This method is only called when this <code>ServiceTracker</code> object
-	 * has been constructed with a <code>null ServiceTrackerCustomizer</code>
-	 * argument.
+	 * This method is only called when this <code>ServiceTracker</code> has been
+	 * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
 	 * 
-	 * The default implementation returns the result of calling
-	 * <code>getService</code>, on the <code>BundleContext</code> object
-	 * with which this <code>ServiceTracker</code> object was created, passing
-	 * the specified <code>ServiceReference</code> object.
+	 * <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>.
 	 * <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
-	 * not to rely on the default implementation of removedService that will
-	 * unget the service.
+	 * not to rely on the default implementation of
+	 * {@link #removedService(ServiceReference, Object) removedService} to unget
+	 * the service.
 	 * 
-	 * @param reference Reference to service being added to this
-	 *        <code>ServiceTracker</code> object.
+	 * @param reference The reference to the service being added to this
+	 *        <code>ServiceTracker</code>.
 	 * @return The service object to be tracked for the service added to this
-	 *         <code>ServiceTracker</code> object.
-	 * @see ServiceTrackerCustomizer
+	 *         <code>ServiceTracker</code>.
+	 * @see ServiceTrackerCustomizer#addingService(ServiceReference)
 	 */
 	public Object addingService(ServiceReference reference) {
 		return context.getService(reference);
@@ -390,17 +447,18 @@
 	 * <code>ServiceTrackerCustomizer.modifiedService</code> method.
 	 * 
 	 * <p>
-	 * This method is only called when this <code>ServiceTracker</code> object
-	 * has been constructed with a <code>null ServiceTrackerCustomizer</code>
-	 * argument.
+	 * This method is only called when this <code>ServiceTracker</code> has been
+	 * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
 	 * 
-	 * The default implementation does nothing.
+	 * <p>
+	 * This implementation does nothing.
 	 * 
-	 * @param reference Reference to modified service.
+	 * @param reference The reference to modified service.
 	 * @param service The service object for the modified service.
-	 * @see ServiceTrackerCustomizer
+	 * @see ServiceTrackerCustomizer#modifiedService(ServiceReference, Object)
 	 */
 	public void modifiedService(ServiceReference reference, Object service) {
+		/* do nothing */
 	}
 
 	/**
@@ -408,22 +466,21 @@
 	 * <code>ServiceTrackerCustomizer.removedService</code> method.
 	 * 
 	 * <p>
-	 * This method is only called when this <code>ServiceTracker</code> object
-	 * has been constructed with a <code>null ServiceTrackerCustomizer</code>
-	 * argument.
+	 * This method is only called when this <code>ServiceTracker</code> has been
+	 * constructed with a <code>null ServiceTrackerCustomizer</code> argument.
 	 * 
-	 * The default implementation calls <code>ungetService</code>, on the
-	 * <code>BundleContext</code> object with which this
-	 * <code>ServiceTracker</code> object was created, passing the specified
-	 * <code>ServiceReference</code> object.
+	 * <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>.
 	 * <p>
 	 * This method can be overridden in a subclass. If the default
-	 * implementation of <code>addingService</code> method was used, this
-	 * method must unget the service.
+	 * implementation of {@link #addingService(ServiceReference) addingService}
+	 * method was used, this method must unget the service.
 	 * 
-	 * @param reference Reference to removed service.
+	 * @param reference The reference to removed service.
 	 * @param service The service object for the removed service.
-	 * @see ServiceTrackerCustomizer
+	 * @see ServiceTrackerCustomizer#removedService(ServiceReference, Object)
 	 */
 	public void removedService(ServiceReference reference, Object service) {
 		context.ungetService(reference);
@@ -431,39 +488,42 @@
 
 	/**
 	 * Wait for at least one service to be tracked by this
-	 * <code>ServiceTracker</code> object.
+	 * <code>ServiceTracker</code>. This method will also return when this
+	 * <code>ServiceTracker</code> 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 period of time.
+	 * <code>BundleActivator</code> methods are expected to complete in a short
+	 * period of time.
 	 * 
-	 * @param timeout time interval in milliseconds to wait. If zero, the method
-	 *        will wait indefinately.
-	 * @return Returns the result of <code>getService()</code>.
+	 * <p>
+	 * This implementation calls {@link #getService()} to determine if a service
+	 * is being tracked.
+	 * 
+	 * @param timeout The time interval in milliseconds to wait. If zero, the
+	 *        method will wait indefinitely.
+	 * @return Returns the result of {@link #getService()}.
 	 * @throws InterruptedException If another thread has interrupted the
 	 *         current thread.
 	 * @throws IllegalArgumentException If the value of timeout is negative.
 	 */
 	public Object waitForService(long timeout) throws InterruptedException {
 		if (timeout < 0) {
-			throw new IllegalArgumentException("timeout value is negative"); //$NON-NLS-1$
+			throw new IllegalArgumentException("timeout value is negative"); 
 		}
-		Object object = getService();
+		Object object = getService(); 
 		while (object == null) {
-			Tracked tracked = this.tracked; /*
-											 * use local var since we are not
-											 * synchronized
-											 */
-			if (tracked == null) { /* if ServiceTracker is not open */
+			final Tracked t = tracked();
+			if (t == null) { /* if ServiceTracker is not open */
 				return null;
 			}
-			synchronized (tracked) {
-				if (tracked.size() == 0) {
-					tracked.wait(timeout);
+			synchronized (t) {
+				if (t.size() == 0) {
+					t.wait(timeout);
 				}
 			}
-			object = getService();
+			object = getService(); 
 			if (timeout > 0) {
 				return object;
 			}
@@ -472,53 +532,45 @@
 	}
 
 	/**
-	 * Return an array of <code>ServiceReference</code> objects for all
-	 * services being tracked by this <code>ServiceTracker</code> object.
+	 * Return an array of <code>ServiceReference</code>s for all services being
+	 * tracked by this <code>ServiceTracker</code>.
 	 * 
-	 * @return Array of <code>ServiceReference</code> objects or
-	 *         <code>null</code> if no service are being tracked.
+	 * @return Array of <code>ServiceReference</code>s or <code>null</code> if
+	 *         no services are being tracked.
 	 */
 	public ServiceReference[] getServiceReferences() {
-		Tracked tracked = this.tracked; /*
-										 * use local var since we are not
-										 * synchronized
-										 */
-		if (tracked == null) { /* if ServiceTracker is not open */
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
 			return null;
 		}
-		synchronized (tracked) {
-			int length = tracked.size();
+		synchronized (t) {
+			int length = t.size();
 			if (length == 0) {
 				return null;
 			}
-			ServiceReference[] references = new ServiceReference[length];
-			Enumeration keys = tracked.keys();
-			for (int i = 0; i < length; i++) {
-				references[i] = (ServiceReference) keys.nextElement();
-			}
-			return references;
+			return (ServiceReference[]) t
+					.getTracked(new ServiceReference[length]);
 		}
 	}
 
 	/**
-	 * Returns a <code>ServiceReference</code> object for one of the services
-	 * being tracked by this <code>ServiceTracker</code> object.
+	 * Returns a <code>ServiceReference</code> for one of the services being
+	 * tracked by this <code>ServiceTracker</code>.
 	 * 
 	 * <p>
 	 * If multiple services are being tracked, the service with the highest
 	 * ranking (as specified in its <code>service.ranking</code> property) is
-	 * returned.
+	 * 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
+	 * is, the service that was registered first is returned. This is the same
+	 * algorithm used by <code>BundleContext.getServiceReference</code>.
 	 * 
 	 * <p>
-	 * If there is a tie in ranking, the service with the lowest service ID (as
-	 * specified in its <code>service.id</code> property); that is, the
-	 * service that was registered first is returned.
-	 * <p>
-	 * This is the same algorithm used by
-	 * <code>BundleContext.getServiceReference</code>.
+	 * This implementation calls {@link #getServiceReferences()} to get the list
+	 * of references for the tracked services.
 	 * 
-	 * @return <code>ServiceReference</code> object or <code>null</code> if
-	 *         no service is being tracked.
+	 * @return A <code>ServiceReference</code> or <code>null</code> if no
+	 *         services are being tracked.
 	 * @since 1.1
 	 */
 	public ServiceReference getServiceReference() {
@@ -526,22 +578,21 @@
 		if (reference != null) {
 			if (DEBUG) {
 				System.out
-						.println("ServiceTracker.getServiceReference[cached]: " + filter); //$NON-NLS-1$
+						.println("ServiceTracker.getServiceReference[cached]: "
+								+ filter); 
 			}
 			return reference;
 		}
 		if (DEBUG) {
-			System.out.println("ServiceTracker.getServiceReference: " + filter); //$NON-NLS-1$
+			System.out.println("ServiceTracker.getServiceReference: " + filter); 
 		}
-		ServiceReference[] references = getServiceReferences();
+		ServiceReference[] references = getServiceReferences(); 
 		int length = (references == null) ? 0 : references.length;
-		if (length == 0) /* if no service is being tracked */
-		{
+		if (length == 0) { /* if no service is being tracked */
 			return null;
 		}
 		int index = 0;
-		if (length > 1) /* if more than one service, select highest ranking */
-		{
+		if (length > 1) { /* if more than one service, select highest ranking */
 			int rankings[] = new int[length];
 			int count = 0;
 			int maxRanking = Integer.MIN_VALUE;
@@ -563,8 +614,7 @@
 					}
 				}
 			}
-			if (count > 1) /* if still more than one service, select lowest id */
-			{
+			if (count > 1) { /* if still more than one service, select lowest id */
 				long minId = Long.MAX_VALUE;
 				for (int i = 0; i < length; i++) {
 					if (rankings[i] == maxRanking) {
@@ -584,51 +634,51 @@
 
 	/**
 	 * Returns the service object for the specified
-	 * <code>ServiceReference</code> object if the referenced service is being
-	 * tracked by this <code>ServiceTracker</code> object.
+	 * <code>ServiceReference</code> if the specified referenced service is
+	 * being tracked by this <code>ServiceTracker</code>.
 	 * 
-	 * @param reference Reference to the desired service.
-	 * @return Service object or <code>null</code> if the service referenced
-	 *         by the specified <code>ServiceReference</code> object is not
-	 *         being tracked.
+	 * @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
+	 *         tracked.
 	 */
 	public Object getService(ServiceReference reference) {
-		Tracked tracked = this.tracked; /*
-										 * use local var since we are not
-										 * synchronized
-										 */
-		if (tracked == null) { /* if ServiceTracker is not open */
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
 			return null;
 		}
-		synchronized (tracked) {
-			return tracked.get(reference);
+		synchronized (t) {
+			return t.getCustomizedObject(reference);
 		}
 	}
 
 	/**
 	 * Return an array of service objects for all services being tracked by this
-	 * <code>ServiceTracker</code> object.
+	 * <code>ServiceTracker</code>.
 	 * 
-	 * @return Array of service objects or <code>null</code> if no service are
-	 *         being tracked.
+	 * <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.
+	 * 
+	 * @return An array of service objects or <code>null</code> if no services
+	 *         are being tracked.
 	 */
 	public Object[] getServices() {
-		Tracked tracked = this.tracked; /*
-										 * use local var since we are not
-										 * synchronized
-										 */
-		if (tracked == null) { /* if ServiceTracker is not open */
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
 			return null;
 		}
-		synchronized (tracked) {
-			ServiceReference[] references = getServiceReferences();
+		synchronized (t) {
+			ServiceReference[] 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;
 		}
@@ -636,13 +686,13 @@
 
 	/**
 	 * Returns a service object for one of the services being tracked by this
-	 * <code>ServiceTracker</code> object.
+	 * <code>ServiceTracker</code>.
 	 * 
 	 * <p>
-	 * If any services are being tracked, this method returns the result of
-	 * calling <code>getService(getServiceReference())</code>.
+	 * If any services are being tracked, this implementation returns the result
+	 * of calling <code>getService(getServiceReference())</code>.
 	 * 
-	 * @return Service object or <code>null</code> if no service is being
+	 * @return A service object or <code>null</code> if no services are being
 	 *         tracked.
 	 */
 	public Object getService() {
@@ -650,258 +700,114 @@
 		if (service != null) {
 			if (DEBUG) {
 				System.out
-						.println("ServiceTracker.getService[cached]: " + filter); //$NON-NLS-1$
+						.println("ServiceTracker.getService[cached]: "
+						+ filter); 
 			}
 			return service;
 		}
 		if (DEBUG) {
-			System.out.println("ServiceTracker.getService: " + filter); //$NON-NLS-1$
+			System.out.println("ServiceTracker.getService: " + filter); 
 		}
-		ServiceReference reference = getServiceReference();
+		ServiceReference reference = getServiceReference(); 
 		if (reference == null) {
 			return null;
 		}
-		return cachedService = getService(reference);
+		return cachedService = getService(reference); 
 	}
 
 	/**
-	 * Remove a service from this <code>ServiceTracker</code> object.
+	 * Remove a service from this <code>ServiceTracker</code>.
 	 * 
 	 * The specified service will be removed from this
-	 * <code>ServiceTracker</code> object. If the specified service was being
-	 * tracked then the <code>ServiceTrackerCustomizer.removedService</code>
-	 * method will be called for that service.
+	 * <code>ServiceTracker</code>. If the specified service was being tracked
+	 * then the <code>ServiceTrackerCustomizer.removedService</code> method will
+	 * be called for that service.
 	 * 
-	 * @param reference Reference to the service to be removed.
+	 * @param reference The reference to the service to be removed.
 	 */
 	public void remove(ServiceReference reference) {
-		Tracked tracked = this.tracked; /*
-										 * use local var since we are not
-										 * synchronized
-										 */
-		if (tracked == null) { /* if ServiceTracker is not open */
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
 			return;
 		}
-		tracked.untrack(reference);
+		t.untrack(reference, null);
 	}
 
 	/**
 	 * Return the number of services being tracked by this
-	 * <code>ServiceTracker</code> object.
+	 * <code>ServiceTracker</code>.
 	 * 
-	 * @return Number of services being tracked.
+	 * @return The number of services being tracked.
 	 */
 	public int size() {
-		Tracked tracked = this.tracked; /*
-										 * use local var since we are not
-										 * synchronized
-										 */
-		if (tracked == null) { /* if ServiceTracker is not open */
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
 			return 0;
 		}
-		return tracked.size();
+		synchronized (t) {
+			return t.size();
+		}
 	}
 
 	/**
-	 * Returns the tracking count for this <code>ServiceTracker</code> object.
+	 * Returns the tracking count for this <code>ServiceTracker</code>.
 	 * 
 	 * The tracking count is initialized to 0 when this
-	 * <code>ServiceTracker</code> object is opened. Every time a service is
-	 * added, modified or removed from this <code>ServiceTracker</code> object
-	 * the tracking count is incremented.
+	 * <code>ServiceTracker</code> is opened. Every time a service is added,
+	 * modified or removed from this <code>ServiceTracker</code>, the tracking
+	 * count is incremented.
 	 * 
 	 * <p>
 	 * The tracking count can be used to determine if this
-	 * <code>ServiceTracker</code> object 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> object since the previous tracking count
-	 * was collected.
+	 * <code>ServiceTracker</code> 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.
 	 * 
 	 * @since 1.2
-	 * @return The tracking count for this <code>ServiceTracker</code> object
-	 *         or -1 if this <code>ServiceTracker</code> object is not open.
+	 * @return The tracking count for this <code>ServiceTracker</code> or -1 if
+	 *         this <code>ServiceTracker</code> is not open.
 	 */
 	public int getTrackingCount() {
-		return trackingCount;
+		final Tracked t = tracked();
+		if (t == null) { /* if ServiceTracker is not open */
+			return -1;
+		}
+		synchronized (t) {
+			return t.getTrackingCount();
+		}
 	}
 
 	/**
 	 * Called by the Tracked object whenever the set of tracked services is
-	 * modified. Increments the tracking count and clears the cache.
-	 * 
-	 * @GuardedBy tracked
+	 * modified. Clears the cache.
 	 */
 	/*
 	 * This method must not be synchronized since it is called by Tracked while
 	 * Tracked is synchronized. We don't want synchronization interactions
-	 * between the ServiceListener thread and the user thread.
+	 * between the listener thread and the user thread.
 	 */
 	void modified() {
-		trackingCount++; /* increment modification count */
 		cachedReference = null; /* clear cached value */
 		cachedService = null; /* clear cached value */
 		if (DEBUG) {
-			System.out.println("ServiceTracker.modified: " + filter); //$NON-NLS-1$
+			System.out.println("ServiceTracker.modified: " + filter); 
 		}
 	}
 
 	/**
-	 * Inner class to track services. If a <code>ServiceTracker</code> object
-	 * is reused (closed then reopened), then a new Tracked object is used. This
-	 * class is a hashtable mapping <code>ServiceReference</code> object ->
-	 * customized Object. This class is the <code>ServiceListener</code>
-	 * object for the tracker. This class is used to synchronize access to the
-	 * tracked services. This is not a public class. It is only for use by the
-	 * implementation of the <code>ServiceTracker</code> class.
+	 * Inner class which subclasses AbstractTracked. This class is the
+	 * <code>ServiceListener</code> object for the tracker.
 	 * 
 	 * @ThreadSafe
 	 */
-	class Tracked extends Hashtable implements ServiceListener {
-		static final long			serialVersionUID	= -7420065199791006079L;
-		/**
-		 * List of ServiceReferences in the process of being added. This is used
-		 * to deal with nesting of ServiceEvents. Since ServiceEvents are
-		 * synchronously delivered, ServiceEvents can be nested. For example,
-		 * when processing the adding of a service and the customizer causes the
-		 * service to be unregistered, notification to the nested call to
-		 * untrack that the service was unregistered can be made to the track
-		 * method.
-		 * 
-		 * Since the ArrayList implementation is not synchronized, all access to
-		 * this list must be protected by the same synchronized object for
-		 * thread-safety.
-		 * 
-		 * @GuardedBy this
-		 */
-		private final ArrayList		adding;
-
-		/**
-		 * true if the tracked object is closed.
-		 * 
-		 * This field is volatile because it is set by one thread and read by
-		 * another.
-		 */
-		private volatile boolean	closed;
-
-		/**
-		 * Initial list of ServiceReferences for the tracker. This is used to
-		 * correctly process the initial services which could become
-		 * unregistered before they are tracked. This is necessary since the
-		 * initial set of tracked services are not "announced" by ServiceEvents
-		 * and therefore the ServiceEvent for unregistration could be delivered
-		 * before we track the service.
-		 * 
-		 * A service must not be in both the initial and adding lists at the
-		 * same time. A service must be moved from the initial list to the
-		 * adding list "atomically" before we begin tracking it.
-		 * 
-		 * Since the LinkedList implementation is not synchronized, all access
-		 * to this list must be protected by the same synchronized object for
-		 * thread-safety.
-		 * 
-		 * @GuardedBy this
-		 */
-		private final LinkedList	initial;
-
+	class Tracked extends AbstractTracked implements ServiceListener {
 		/**
 		 * Tracked constructor.
 		 */
-		protected Tracked() {
+		Tracked() {
 			super();
-			closed = false;
-			adding = new ArrayList(6);
-			initial = new LinkedList();
-		}
-
-		/**
-		 * Set initial list of services into tracker before ServiceEvents begin
-		 * to be received.
-		 * 
-		 * This method must be called from ServiceTracker.open while
-		 * synchronized on this object in the same synchronized block as the
-		 * addServiceListener call.
-		 * 
-		 * @param references The initial list of services to be tracked.
-		 * @GuardedBy this
-		 */
-		protected void setInitialServices(ServiceReference[] references) {
-			if (references == null) {
-				return;
-			}
-			int size = references.length;
-			for (int i = 0; i < size; i++) {
-				if (DEBUG) {
-					System.out
-							.println("ServiceTracker.Tracked.setInitialServices: " + references[i]); //$NON-NLS-1$
-				}
-				initial.add(references[i]);
-			}
-		}
-
-		/**
-		 * Track the initial list of services. This is called after
-		 * ServiceEvents can begin to be received.
-		 * 
-		 * This method must be called from ServiceTracker.open while not
-		 * synchronized on this object after the addServiceListener call.
-		 * 
-		 */
-		protected void trackInitialServices() {
-			while (true) {
-				ServiceReference reference;
-				synchronized (this) {
-					if (initial.size() == 0) {
-						/*
-						 * if there are no more inital services
-						 */
-						return; /* we are done */
-					}
-					/*
-					 * move the first service from the initial list to the
-					 * adding list within this synchronized block.
-					 */
-					reference = (ServiceReference) initial.removeFirst();
-					if (this.get(reference) != null) {
-						/* if we are already tracking this service */
-						if (DEBUG) {
-							System.out
-									.println("ServiceTracker.Tracked.trackInitialServices[already tracked]: " + reference); //$NON-NLS-1$
-						}
-						continue; /* skip this service */
-					}
-					if (adding.contains(reference)) {
-						/*
-						 * if this service is already in the process of being
-						 * added.
-						 */
-						if (DEBUG) {
-							System.out
-									.println("ServiceTracker.Tracked.trackInitialServices[already adding]: " + reference); //$NON-NLS-1$
-						}
-						continue; /* skip this service */
-					}
-					adding.add(reference);
-				}
-				if (DEBUG) {
-					System.out
-							.println("ServiceTracker.Tracked.trackInitialServices: " + reference); //$NON-NLS-1$
-				}
-				trackAdding(reference); /*
-										 * Begin tracking it. We call
-										 * trackAdding since we have already put
-										 * the reference in the adding list.
-										 */
-			}
-		}
-
-		/**
-		 * Called by the owning <code>ServiceTracker</code> object when it is
-		 * closed.
-		 */
-		protected void close() {
-			closed = true;
 		}
 
 		/**
@@ -911,7 +817,7 @@
 		 * 
 		 * @param event <code>ServiceEvent</code> object from the framework.
 		 */
-		public void serviceChanged(ServiceEvent event) {
+		public void serviceChanged(final ServiceEvent event) {
 			/*
 			 * Check if we had a delayed call (which could happen when we
 			 * close).
@@ -919,33 +825,34 @@
 			if (closed) {
 				return;
 			}
-			ServiceReference reference = event.getServiceReference();
+			final ServiceReference reference = event.getServiceReference();
 			if (DEBUG) {
 				System.out
-						.println("ServiceTracker.Tracked.serviceChanged[" + event.getType() + "]: " + reference); //$NON-NLS-1$ //$NON-NLS-2$
+						.println("ServiceTracker.Tracked.serviceChanged["
+						+ event.getType() + "]: " + reference);  
 			}
 
 			switch (event.getType()) {
 				case ServiceEvent.REGISTERED :
 				case ServiceEvent.MODIFIED :
-					if (listenerFilter != null) { // constructor supplied
+					if (listenerFilter != null) { // service listener added with
 						// filter
-						track(reference);
+						track(reference, event);
 						/*
 						 * If the customizer throws an unchecked exception, it
 						 * is safe to let it propagate
 						 */
 					}
-					else { // user supplied filter
+					else { // service listener added without filter
 						if (filter.match(reference)) {
-							track(reference);
+							track(reference, event);
 							/*
 							 * If the customizer throws an unchecked exception,
 							 * it is safe to let it propagate
 							 */
 						}
 						else {
-							untrack(reference);
+							untrack(reference, event);
 							/*
 							 * If the customizer throws an unchecked exception,
 							 * it is safe to let it propagate
@@ -953,8 +860,9 @@
 						}
 					}
 					break;
+				case ServiceEvent.MODIFIED_ENDMATCH :
 				case ServiceEvent.UNREGISTERING :
-					untrack(reference);
+					untrack(reference, event);
 					/*
 					 * If the customizer throws an unchecked exception, it is
 					 * safe to let it propagate
@@ -964,170 +872,54 @@
 		}
 
 		/**
-		 * Begin to track the referenced service.
+		 * Increment the tracking count and tell the tracker there was a
+		 * modification.
 		 * 
-		 * @param reference Reference to a service to be tracked.
+		 * @GuardedBy this
 		 */
-		private void track(ServiceReference reference) {
-			Object object;
-			synchronized (this) {
-				object = this.get(reference);
-			}
-			if (object != null) /* we are already tracking the service */
-			{
-				if (DEBUG) {
-					System.out
-							.println("ServiceTracker.Tracked.track[modified]: " + reference); //$NON-NLS-1$
-				}
-				synchronized (this) {
-					modified(); /* increment modification count */
-				}
-				/* Call customizer outside of synchronized region */
-				customizer.modifiedService(reference, object);
-				/*
-				 * If the customizer throws an unchecked exception, it is safe
-				 * to let it propagate
-				 */
-				return;
-			}
-			synchronized (this) {
-				if (adding.contains(reference)) { /*
-													 * if this service is
-													 * already in the process of
-													 * being added.
-													 */
-					if (DEBUG) {
-						System.out
-								.println("ServiceTracker.Tracked.track[already adding]: " + reference); //$NON-NLS-1$
-					}
-					return;
-				}
-				adding.add(reference); /* mark this service is being added */
-			}
-
-			trackAdding(reference); /*
-									 * call trackAdding now that we have put the
-									 * reference in the adding list
-									 */
+		void modified() {
+			super.modified(); /* increment the modification count */
+			ServiceTracker.this.modified();
 		}
 
 		/**
-		 * Common logic to add a service to the tracker used by track and
-		 * trackInitialServices. The specified reference must have been placed
-		 * in the adding list before calling this method.
+		 * Call the specific customizer adding method. This method must not be
+		 * called while synchronized on this object.
 		 * 
-		 * @param reference Reference to a service to be tracked.
+		 * @param item Item to be tracked.
+		 * @param related Action related object.
+		 * @return Customized object for the tracked item or <code>null</code>
+		 *         if the item is not to be tracked.
 		 */
-		private void trackAdding(ServiceReference reference) {
-			if (DEBUG) {
-				System.out
-						.println("ServiceTracker.Tracked.trackAdding: " + reference); //$NON-NLS-1$
-			}
-			Object object = null;
-			boolean becameUntracked = false;
-			/* Call customizer outside of synchronized region */
-			try {
-				object = customizer.addingService(reference);
-				/*
-				 * If the customizer throws an unchecked exception, it will
-				 * propagate after the finally
-				 */
-			}
-			finally {
-				synchronized (this) {
-					if (adding.remove(reference)) { /*
-													 * if the service was not
-													 * untracked during the
-													 * customizer callback
-													 */
-						if (object != null) {
-							this.put(reference, object);
-							modified(); /* increment modification count */
-							notifyAll(); /*
-											 * notify any waiters in
-											 * waitForService
-											 */
-						}
-					}
-					else {
-						becameUntracked = true;
-					}
-				}
-			}
-			/*
-			 * The service became untracked during the customizer callback.
-			 */
-			if (becameUntracked) {
-				if (DEBUG) {
-					System.out
-							.println("ServiceTracker.Tracked.trackAdding[removed]: " + reference); //$NON-NLS-1$
-				}
-				/* Call customizer outside of synchronized region */
-				customizer.removedService(reference, object);
-				/*
-				 * If the customizer throws an unchecked exception, it is safe
-				 * to let it propagate
-				 */
-			}
+		Object customizerAdding(final Object item,
+				final Object related) {
+			return customizer.addingService((ServiceReference) item);
 		}
 
 		/**
-		 * Discontinue tracking the referenced service.
+		 * Call the specific customizer modified method. This method must not be
+		 * called while synchronized on this object.
 		 * 
-		 * @param reference Reference to the tracked service.
+		 * @param item Tracked item.
+		 * @param related Action related object.
+		 * @param object Customized object for the tracked item.
 		 */
-		protected void untrack(ServiceReference reference) {
-			Object object;
-			synchronized (this) {
-				if (initial.remove(reference)) { /*
-													 * if this service is
-													 * already in the list of
-													 * initial references to
-													 * process
-													 */
-					if (DEBUG) {
-						System.out
-								.println("ServiceTracker.Tracked.untrack[removed from initial]: " + reference); //$NON-NLS-1$
-					}
-					return; /*
-							 * we have removed it from the list and it will not
-							 * be processed
-							 */
-				}
+		void customizerModified(final Object item,
+				final Object related, final Object object) {
+			customizer.modifiedService((ServiceReference) item, object);
+		}
 
-				if (adding.remove(reference)) { /*
-												 * if the service is in the
-												 * process of being added
-												 */
-					if (DEBUG) {
-						System.out
-								.println("ServiceTracker.Tracked.untrack[being added]: " + reference); //$NON-NLS-1$
-					}
-					return; /*
-							 * in case the service is untracked while in the
-							 * process of adding
-							 */
-				}
-				object = this.remove(reference); /*
-													 * must remove from tracker
-													 * before calling customizer
-													 * callback
-													 */
-				if (object == null) { /* are we actually tracking the service */
-					return;
-				}
-				modified(); /* increment modification count */
-			}
-			if (DEBUG) {
-				System.out
-						.println("ServiceTracker.Tracked.untrack[removed]: " + reference); //$NON-NLS-1$
-			}
-			/* Call customizer outside of synchronized region */
-			customizer.removedService(reference, object);
-			/*
-			 * If the customizer throws an unchecked exception, it is safe to
-			 * let it propagate
-			 */
+		/**
+		 * Call the specific customizer removed method. This method must not be
+		 * called while synchronized on this object.
+		 * 
+		 * @param item Tracked item.
+		 * @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);
 		}
 	}
 
@@ -1139,12 +931,10 @@
 	 * @ThreadSafe
 	 */
 	class AllTracked extends Tracked implements AllServiceListener {
-		static final long	serialVersionUID	= 4050764875305137716L;
-
 		/**
 		 * AllTracked constructor.
 		 */
-		protected AllTracked() {
+		AllTracked() {
 			super();
 		}
 	}
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
index e091078..5c270e3 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/ServiceTrackerCustomizer.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.tracker/src/org/osgi/util/tracker/ServiceTrackerCustomizer.java,v 1.13 2007/02/19 19:04:33 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2000, 2008). All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,76 +20,75 @@
 
 /**
  * The <code>ServiceTrackerCustomizer</code> interface allows a
- * <code>ServiceTracker</code> object to customize the service objects that
- * are tracked. The <code>ServiceTrackerCustomizer</code> object is called
- * when a service is being added to the <code>ServiceTracker</code> object.
- * The <code>ServiceTrackerCustomizer</code> can then return an object for the
- * tracked service. The <code>ServiceTrackerCustomizer</code> object is also
- * called when a tracked service is modified or has been removed from the
- * <code>ServiceTracker</code> object.
+ * <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
+ * a tracked service is modified or has been removed from a
+ * <code>ServiceTracker</code>.
  * 
  * <p>
  * The methods in this interface may be called as the result of a
- * <code>ServiceEvent</code> being received by a <code>ServiceTracker</code>
- * object. Since <code>ServiceEvent</code> 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>ServiceEvent</code> being received by a <code>ServiceTracker</code>.
+ * Since <code>ServiceEvent</code>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
  * synchronized on any object.
  * 
  * <p>
  * The <code>ServiceTracker</code> class is thread-safe. It does not call a
- * <code>ServiceTrackerCustomizer</code> object while holding any locks.
+ * <code>ServiceTrackerCustomizer</code> while holding any locks.
  * <code>ServiceTrackerCustomizer</code> implementations must also be
  * thread-safe.
  * 
  * @ThreadSafe
- * @version $Revision: 1.13 $
+ * @version $Revision: 5874 $
  */
 public interface ServiceTrackerCustomizer {
 	/**
-	 * A service is being added to the <code>ServiceTracker</code> object.
+	 * A service is being added to the <code>ServiceTracker</code>.
 	 * 
 	 * <p>
 	 * This method is called before a service which matched the search
-	 * parameters of the <code>ServiceTracker</code> object is added to it.
-	 * This method should return the service object to be tracked for this
-	 * <code>ServiceReference</code> object. The returned service object is
-	 * stored in the <code>ServiceTracker</code> object and is available from
-	 * the <code>getService</code> and <code>getServices</code> methods.
+	 * 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.
 	 * 
-	 * @param reference Reference to service being added to the
-	 *        <code>ServiceTracker</code> object.
-	 * @return The service object to be tracked for the
-	 *         <code>ServiceReference</code> object or <code>null</code> if
-	 *         the <code>ServiceReference</code> object should not be tracked.
+	 * @param reference The reference to the service being added to the
+	 *        <code>ServiceTracker</code>.
+	 * @return The service object to be tracked for the specified referenced
+	 *         service or <code>null</code> if the specified referenced service
+	 *         should not be tracked.
 	 */
 	public Object addingService(ServiceReference reference);
 
 	/**
-	 * A service tracked by the <code>ServiceTracker</code> object has been
-	 * modified.
+	 * A service tracked by the <code>ServiceTracker</code> has been modified.
 	 * 
 	 * <p>
 	 * This method is called when a service being tracked by the
-	 * <code>ServiceTracker</code> object has had it properties modified.
+	 * <code>ServiceTracker</code> has had it properties modified.
 	 * 
-	 * @param reference Reference to service that has been modified.
-	 * @param service The service object for the modified service.
+	 * @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);
 
 	/**
-	 * A service tracked by the <code>ServiceTracker</code> object has been
-	 * removed.
+	 * A service tracked by the <code>ServiceTracker</code> has been removed.
 	 * 
 	 * <p>
 	 * This method is called after a service is no longer being tracked by the
-	 * <code>ServiceTracker</code> object.
+	 * <code>ServiceTracker</code>.
 	 * 
-	 * @param reference Reference to service that has been removed.
-	 * @param service The service object for the removed service.
+	 * @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);
 }
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/package.html
new file mode 100644
index 0000000..c29c891
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>Tracker Package Version 1.4.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.tracker; version=&quot;[1.4,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/tracker/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/packageinfo
new file mode 100644
index 0000000..cc13f19
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/tracker/packageinfo
@@ -0,0 +1 @@
+version 1.4
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/xml/XMLParserActivator.java b/org.osgi.compendium/src/main/java/org/osgi/util/xml/XMLParserActivator.java
index c1e6cd8..963c092 100644
--- a/org.osgi.compendium/src/main/java/org/osgi/util/xml/XMLParserActivator.java
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/xml/XMLParserActivator.java
@@ -1,7 +1,5 @@
 /*
- * $Header: /cvshome/build/org.osgi.util.xml/src/org/osgi/util/xml/XMLParserActivator.java,v 1.11 2006/10/27 18:17:06 hargrave Exp $
- * 
- * Copyright (c) OSGi Alliance (2002, 2006). All Rights Reserved.
+ * Copyright (c) OSGi Alliance (2002, 2008). 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,13 +16,28 @@
 
 package org.osgi.util.xml;
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.net.URL;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
 
-import javax.xml.parsers.*;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.FactoryConfigurationError;
+import javax.xml.parsers.SAXParserFactory;
 
-import org.osgi.framework.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
 
 /**
  * A BundleActivator class that allows any JAXP compliant XML Parser to register
@@ -50,8 +63,8 @@
  * An XMLParserActivator assumes that it can find the class file names of the
  * factory classes in the following files:
  * <ul>
- * <li><code>/META-INF/services/javax.xml.parsers.SAXParserFactory</code> is
- * a file contained in a jar available to the runtime which contains the
+ * <li><code>/META-INF/services/javax.xml.parsers.SAXParserFactory</code> is a
+ * file contained in a jar available to the runtime which contains the
  * implementation class name(s) of the SAXParserFactory.
  * <li><code>/META-INF/services/javax.xml.parsers.DocumentBuilderFactory</code>
  * is a file contained in a jar available to the runtime which contains the
@@ -63,11 +76,11 @@
  * 
  * <p>
  * <code>XMLParserActivator</code> attempts to instantiate both the
- * <code>SAXParserFactory</code> and the <code>DocumentBuilderFactory</code>.
- * It registers each factory with the framework along with service properties:
+ * <code>SAXParserFactory</code> and the <code>DocumentBuilderFactory</code>. It
+ * registers each factory with the framework along with service properties:
  * <ul>
- * <li>{@link #PARSER_VALIDATING}- indicates if this factory supports
- * validating parsers. It's value is a <code>Boolean</code>.
+ * <li>{@link #PARSER_VALIDATING}- indicates if this factory supports validating
+ * parsers. It's value is a <code>Boolean</code>.
  * <li>{@link #PARSER_NAMESPACEAWARE}- indicates if this factory supports
  * namespace aware parsers It's value is a <code>Boolean</code>.
  * </ul>
@@ -76,48 +89,51 @@
  * or attributes which could be used to select a parser with a filter. These can
  * be added by extending this class and overriding the
  * <code>setSAXProperties</code> and <code>setDOMProperties</code> methods.
+ * 
+ * @ThreadSafe
+ * @version $Revision: 5900 $
  */
 public class XMLParserActivator implements BundleActivator, ServiceFactory {
 	/** Context of this bundle */
-	private BundleContext		context;
+	private volatile BundleContext	context;
 	/**
 	 * Filename containing the SAX Parser Factory Class name. Also used as the
 	 * basis for the <code>SERVICE_PID<code> registration property.
 	 */
-	public static final String	SAXFACTORYNAME			= "javax.xml.parsers.SAXParserFactory";
+	public static final String		SAXFACTORYNAME			= "javax.xml.parsers.SAXParserFactory";
 	/**
 	 * Filename containing the DOM Parser Factory Class name. Also used as the
 	 * basis for the <code>SERVICE_PID</code> registration property.
 	 */
-	public static final String	DOMFACTORYNAME			= "javax.xml.parsers.DocumentBuilderFactory";
+	public static final String		DOMFACTORYNAME			= "javax.xml.parsers.DocumentBuilderFactory";
 	/** Path to the factory class name files */
-	private static final String	PARSERCLASSFILEPATH		= "/META-INF/services/";
+	private static final String		PARSERCLASSFILEPATH		= "/META-INF/services/";
 	/** Fully qualified path name of SAX Parser Factory Class Name file */
-	public static final String	SAXCLASSFILE			= PARSERCLASSFILEPATH
-																+ SAXFACTORYNAME;
+	public static final String		SAXCLASSFILE			= PARSERCLASSFILEPATH
+																	+ SAXFACTORYNAME;
 	/** Fully qualified path name of DOM Parser Factory Class Name file */
-	public static final String	DOMCLASSFILE			= PARSERCLASSFILEPATH
-																+ DOMFACTORYNAME;
+	public static final String		DOMCLASSFILE			= PARSERCLASSFILEPATH
+																	+ DOMFACTORYNAME;
 	/** SAX Factory Service Description */
-	private static final String	SAXFACTORYDESCRIPTION	= "A JAXP Compliant SAX Parser";
+	private static final String		SAXFACTORYDESCRIPTION	= "A JAXP Compliant SAX Parser";
 	/** DOM Factory Service Description */
-	private static final String	DOMFACTORYDESCRIPTION	= "A JAXP Compliant DOM Parser";
+	private static final String		DOMFACTORYDESCRIPTION	= "A JAXP Compliant DOM Parser";
 	/**
 	 * Service property specifying if factory is configured to support
 	 * validating parsers. The value is of type <code>Boolean</code>.
 	 */
-	public static final String	PARSER_VALIDATING		= "parser.validating";
+	public static final String		PARSER_VALIDATING		= "parser.validating";
 	/**
 	 * Service property specifying if factory is configured to support namespace
 	 * aware parsers. The value is of type <code>Boolean</code>.
 	 */
-	public static final String	PARSER_NAMESPACEAWARE	= "parser.namespaceAware";
+	public static final String		PARSER_NAMESPACEAWARE	= "parser.namespaceAware";
 	/**
 	 * Key for parser factory name property - this must be saved in the parsers
 	 * properties hashtable so that the parser factory can be instantiated from
 	 * a ServiceReference
 	 */
-	private static final String	FACTORYNAMEKEY			= "parser.factoryname";
+	private static final String		FACTORYNAMEKEY			= "parser.factoryname";
 
 	/**
 	 * Called when this bundle is started so the Framework can perform the
@@ -141,20 +157,12 @@
 	public void start(BundleContext context) throws Exception {
 		this.context = context;
 		Bundle parserBundle = context.getBundle();
-		try {
-			// check for sax parsers
-			registerSAXParsers(getParserFactoryClassNames(parserBundle
-					.getResource(SAXCLASSFILE)));
-			// check for dom parsers
-			registerDOMParsers(getParserFactoryClassNames(parserBundle
-					.getResource(DOMCLASSFILE)));
-		}
-		catch (IOException ioe) {
-			// if there were any IO errors accessing the resource files
-			// containing the class names
-			ioe.printStackTrace();
-			throw new FactoryConfigurationError(ioe);
-		}
+		// check for sax parsers
+		registerSAXParsers(getParserFactoryClassNames(parserBundle
+				.getResource(SAXCLASSFILE)));
+		// check for dom parsers
+		registerDOMParsers(getParserFactoryClassNames(parserBundle
+				.getResource(DOMCLASSFILE)));
 	}
 
 	/**
@@ -168,6 +176,7 @@
 	 *         bundle, and release all services used by the bundle.
 	 */
 	public void stop(BundleContext context) throws Exception {
+		// framework will automatically unregister the parser services
 	}
 
 	/**
@@ -177,77 +186,70 @@
 	 * 
 	 * @param parserUrl The URL of the service file containing the parser class
 	 *        names
-	 * @return A vector of strings containing the parser class names or null if
-	 *         parserUrl is null
+	 * @return A List of strings containing the parser class names.
 	 * @throws IOException if there is a problem reading the URL input stream
 	 */
-	private Vector getParserFactoryClassNames(URL parserUrl) throws IOException {
-		Vector v = new Vector(1);
-		if (parserUrl != null) {
-			String parserFactoryClassName = null;
-			InputStream is = parserUrl.openStream();
-			BufferedReader br = new BufferedReader(new InputStreamReader(is));
-			while (true) {
-				parserFactoryClassName = br.readLine();
-				if (parserFactoryClassName == null) {
-					break; // end of file reached
-				}
-				String pfcName = parserFactoryClassName.trim();
-				if (pfcName.length() == 0) {
-					continue; // blank line
-				}
-				int commentIdx = pfcName.indexOf("#");
-				if (commentIdx == 0) { // comment line
-					continue;
-				}
-				else
-					if (commentIdx < 0) { // no comment on this line
-						v.addElement(pfcName);
-					}
-					else {
-						v.addElement(pfcName.substring(0, commentIdx).trim());
-					}
+	private List getParserFactoryClassNames(URL parserUrl) throws IOException {
+		if (parserUrl == null) {
+			return Collections.EMPTY_LIST;
+		}
+		List v = new ArrayList(1);
+		String parserFactoryClassName = null;
+		InputStream is = parserUrl.openStream();
+		BufferedReader br = new BufferedReader(new InputStreamReader(is));
+		while (true) {
+			parserFactoryClassName = br.readLine();
+			if (parserFactoryClassName == null) {
+				break; // end of file reached
 			}
-			return v;
+			String pfcName = parserFactoryClassName.trim();
+			if (pfcName.length() == 0) {
+				continue; // blank line
+			}
+			int commentIdx = pfcName.indexOf("#");
+			if (commentIdx == 0) { // comment line
+				continue;
+			}
+			else
+				if (commentIdx < 0) { // no comment on this line
+					v.add(pfcName);
+				}
+				else {
+					v.add(pfcName.substring(0, commentIdx).trim());
+				}
 		}
-		else {
-			return null;
-		}
+		return v;
 	}
 
 	/**
 	 * Register SAX Parser Factory Services with the framework.
 	 * 
-	 * @param parserFactoryClassNames - a <code>Vector</code> of
+	 * @param parserFactoryClassNames - a <code>List</code> of
 	 *        <code>String</code> objects containing the names of the parser
 	 *        Factory Classes
 	 * @throws FactoryConfigurationError if thrown from <code>getFactory</code>
 	 */
-	private void registerSAXParsers(Vector parserFactoryClassNames)
+	private void registerSAXParsers(List parserFactoryClassNames)
 			throws FactoryConfigurationError {
-		if (parserFactoryClassNames != null) {
-			Enumeration e = parserFactoryClassNames.elements();
-			int index = 0;
-			while (e.hasMoreElements()) {
-				String parserFactoryClassName = (String) e.nextElement();
-				// create a sax parser factory just to get it's default
-				// properties. It will never be used since
-				// this class will operate as a service factory and give each
-				// service requestor it's own SaxParserFactory
-				SAXParserFactory factory = (SAXParserFactory) getFactory(parserFactoryClassName);
-				Hashtable properties = new Hashtable(7);
-				// figure out the default properties of the parser
-				setDefaultSAXProperties(factory, properties, index);
-				// store the parser factory class name in the properties so that
-				// it can be retrieved when getService is called
-				// to return a parser factory
-				properties.put(FACTORYNAMEKEY, parserFactoryClassName);
-				// release the factory
-				factory = null;
-				// register the factory as a service
-				context.registerService(SAXFACTORYNAME, this, properties);
-				index++;
-			}
+		Iterator e = parserFactoryClassNames.iterator();
+		int index = 0;
+		while (e.hasNext()) {
+			String parserFactoryClassName = (String) e.next();
+			// create a sax parser factory just to get it's default
+			// properties. It will never be used since
+			// this class will operate as a service factory and give each
+			// service requestor it's own SaxParserFactory
+			SAXParserFactory factory = (SAXParserFactory) getFactory(parserFactoryClassName);
+			Hashtable properties = new Hashtable(7);
+			// figure out the default properties of the parser
+			setDefaultSAXProperties(factory, properties, index);
+			// store the parser factory class name in the properties so that
+			// it can be retrieved when getService is called
+			// to return a parser factory
+			properties.put(FACTORYNAMEKEY, parserFactoryClassName);
+			// register the factory as a service
+			context.registerService(SAXFACTORYNAME, this, properties);
+			index++;
 		}
 	}
 
@@ -280,10 +282,9 @@
 	 * Set the customizable SAX Parser Service Properties.
 	 * 
 	 * <p>
-	 * This method attempts to instantiate a validating parser and a
-	 * namespaceaware parser to determine if the parser can support those
-	 * features. The appropriate properties are then set in the specified
-	 * properties object.
+	 * This method attempts to instantiate a validating parser and a namespace
+	 * aware parser to determine if the parser can support those features. The
+	 * appropriate properties are then set in the specified properties object.
 	 * 
 	 * <p>
 	 * This method can be overridden to add additional SAX2 features and
@@ -328,36 +329,32 @@
 	/**
 	 * Register DOM Parser Factory Services with the framework.
 	 * 
-	 * @param parserFactoryClassNames - a <code>Vector</code> of
+	 * @param parserFactoryClassNames - a <code>List</code> of
 	 *        <code>String</code> objects containing the names of the parser
 	 *        Factory Classes
 	 * @throws FactoryConfigurationError if thrown from <code>getFactory</code>
 	 */
-	private void registerDOMParsers(Vector parserFactoryClassNames)
+	private void registerDOMParsers(List parserFactoryClassNames)
 			throws FactoryConfigurationError {
-		if (parserFactoryClassNames != null) {
-			Enumeration e = parserFactoryClassNames.elements();
-			int index = 0;
-			while (e.hasMoreElements()) {
-				String parserFactoryClassName = (String) e.nextElement();
-				// create a dom parser factory just to get it's default
-				// properties. It will never be used since
-				// this class will operate as a service factory and give each
-				// service requestor it's own DocumentBuilderFactory
-				DocumentBuilderFactory factory = (DocumentBuilderFactory) getFactory(parserFactoryClassName);
-				Hashtable properties = new Hashtable(7);
-				// figure out the default properties of the parser
-				setDefaultDOMProperties(factory, properties, index);
-				// store the parser factory class name in the properties so that
-				// it can be retrieved when getService is called
-				// to return a parser factory
-				properties.put(FACTORYNAMEKEY, parserFactoryClassName);
-				// release the factory
-				factory = null;
-				// register the factory as a service
-				context.registerService(DOMFACTORYNAME, this, properties);
-				index++;
-			}
+		Iterator e = parserFactoryClassNames.iterator();
+		int index = 0;
+		while (e.hasNext()) {
+			String parserFactoryClassName = (String) e.next();
+			// create a dom parser factory just to get it's default
+			// properties. It will never be used since
+			// this class will operate as a service factory and give each
+			// service requestor it's own DocumentBuilderFactory
+			DocumentBuilderFactory factory = (DocumentBuilderFactory) getFactory(parserFactoryClassName);
+			Hashtable properties = new Hashtable(7);
+			// figure out the default properties of the parser
+			setDefaultDOMProperties(factory, properties, index);
+			// store the parser factory class name in the properties so that
+			// it can be retrieved when getService is called
+			// to return a parser factory
+			properties.put(FACTORYNAMEKEY, parserFactoryClassName);
+			// register the factory as a service
+			context.registerService(DOMFACTORYNAME, this, properties);
+			index++;
 		}
 	}
 
@@ -388,10 +385,9 @@
 	 * Set the customizable DOM Parser Service Properties.
 	 * 
 	 * <p>
-	 * This method attempts to instantiate a validating parser and a
-	 * namespaceaware parser to determine if the parser can support those
-	 * features. The appropriate properties are then set in the specified props
-	 * object.
+	 * This method attempts to instantiate a validating parser and a namespace
+	 * aware parser to determine if the parser can support those features. The
+	 * appropriate properties are then set in the specified props object.
 	 * 
 	 * <p>
 	 * This method can be overridden to add additional DOM2 features and
@@ -443,20 +439,16 @@
 	 */
 	private Object getFactory(String parserFactoryClassName)
 			throws FactoryConfigurationError {
-		Exception e = null;
 		try {
-			return Class.forName(parserFactoryClassName).newInstance();
+			return context.getBundle().loadClass(parserFactoryClassName)
+					.newInstance();
 		}
-		catch (ClassNotFoundException cnfe) {
-			e = cnfe;
+		catch (RuntimeException e) {
+			throw e;
 		}
-		catch (InstantiationException ie) {
-			e = ie;
+		catch (Exception e) {
+			throw new FactoryConfigurationError(e);
 		}
-		catch (IllegalAccessException iae) {
-			e = iae;
-		}
-		throw new FactoryConfigurationError(e);
 	}
 
 	/**
@@ -484,32 +476,26 @@
 		ServiceReference sref = registration.getReference();
 		String parserFactoryClassName = (String) sref
 				.getProperty(FACTORYNAMEKEY);
-		try {
-			// need to set factory properties
-			Object factory = getFactory(parserFactoryClassName);
-			if (factory instanceof SAXParserFactory) {
-				((SAXParserFactory) factory).setValidating(((Boolean) sref
-						.getProperty(PARSER_VALIDATING)).booleanValue());
-				((SAXParserFactory) factory).setNamespaceAware(((Boolean) sref
-						.getProperty(PARSER_NAMESPACEAWARE)).booleanValue());
+		// need to set factory properties
+		Object factory = getFactory(parserFactoryClassName);
+		if (factory instanceof SAXParserFactory) {
+			((SAXParserFactory) factory).setValidating(((Boolean) sref
+					.getProperty(PARSER_VALIDATING)).booleanValue());
+			((SAXParserFactory) factory).setNamespaceAware(((Boolean) sref
+					.getProperty(PARSER_NAMESPACEAWARE)).booleanValue());
+		}
+		else {
+			if (factory instanceof DocumentBuilderFactory) {
+				((DocumentBuilderFactory) factory)
+						.setValidating(((Boolean) sref
+								.getProperty(PARSER_VALIDATING)).booleanValue());
+				((DocumentBuilderFactory) factory)
+						.setNamespaceAware(((Boolean) sref
+								.getProperty(PARSER_NAMESPACEAWARE))
+								.booleanValue());
 			}
-			else
-				if (factory instanceof DocumentBuilderFactory) {
-					((DocumentBuilderFactory) factory)
-							.setValidating(((Boolean) sref
-									.getProperty(PARSER_VALIDATING))
-									.booleanValue());
-					((DocumentBuilderFactory) factory)
-							.setNamespaceAware(((Boolean) sref
-									.getProperty(PARSER_NAMESPACEAWARE))
-									.booleanValue());
-				}
-			return factory;
 		}
-		catch (FactoryConfigurationError fce) {
-			fce.printStackTrace();
-			return null;
-		}
+		return factory;
 	}
 
 	/**
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/xml/package.html b/org.osgi.compendium/src/main/java/org/osgi/util/xml/package.html
new file mode 100644
index 0000000..e153322
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/xml/package.html
@@ -0,0 +1,10 @@
+<!-- $Revision: 6204 $ -->
+<BODY>
+<p>XML Parser Package Version 1.0.
+<p>Bundles wishing to use this package must list the package
+in the Import-Package header of the bundle's manifest.
+For example:
+<pre>
+Import-Package: org.osgi.util.xml; version=&quot;[1.0,2.0)&quot;
+</pre>
+</BODY>
diff --git a/org.osgi.compendium/src/main/java/org/osgi/util/xml/packageinfo b/org.osgi.compendium/src/main/java/org/osgi/util/xml/packageinfo
new file mode 100644
index 0000000..c266447
--- /dev/null
+++ b/org.osgi.compendium/src/main/java/org/osgi/util/xml/packageinfo
@@ -0,0 +1 @@
+version 1.0.1
\ No newline at end of file