fixes for composite update clarifications.
diff --git a/bundles/org.eclipse.osgi/core/composite/org/eclipse/osgi/internal/composite/CompositeImpl.java b/bundles/org.eclipse.osgi/core/composite/org/eclipse/osgi/internal/composite/CompositeImpl.java
index 6c2b9ea..908c0f2 100644
--- a/bundles/org.eclipse.osgi/core/composite/org/eclipse/osgi/internal/composite/CompositeImpl.java
+++ b/bundles/org.eclipse.osgi/core/composite/org/eclipse/osgi/internal/composite/CompositeImpl.java
@@ -39,6 +39,12 @@
 
 public class CompositeImpl extends BundleHost implements CompositeBundle {
 	private static final StateObjectFactory stateFactory = new StateObjectFactoryImpl();
+	private static final ThreadLocal<Boolean> updating = new ThreadLocal<Boolean>() {
+		public Boolean initialValue() {
+			return Boolean.FALSE;
+		}
+	};
+
 	private final CompositeSystemBundle compositeSystemBundle;
 	private final CompositeInfo compositeInfo;
 	private final StartLevelManager startLevelManager;
@@ -145,6 +151,10 @@
 	}
 
 	public void update(InputStream in) throws BundleException {
+		if (in == RELOAD) {
+			super.update(RELOAD);
+			return;
+		}
 		try {
 			in.close();
 		} catch (IOException e) {
@@ -172,10 +182,13 @@
 			config.load(configURL.openStream());
 			// get an in memory input stream to jar content of the composite we want to install
 			InputStream content = CompositeSupport.getCompositeInput(config, compositeManifest);
+			updating.set(true);
 			// update with the new content
 			super.update(content);
 		} catch (IOException e) {
 			throw new BundleException("Error creating composite bundle", e); //$NON-NLS-1$
+		} finally {
+			updating.set(false);
 		}
 	}
 
@@ -185,6 +198,16 @@
 		// update the composite info with the new data.
 		CompositeInfo updatedInfo = createCompositeInfo(getBundleId(), false);
 		compositeInfo.update(updatedInfo);
+		AbstractBundle[] bundles = framework.getBundles(getBundleId());
+		// reload all the constituents 
+		for (AbstractBundle bundle : bundles) {
+			if (bundle.getBundleId() != 0) // not the system bundle
+				try {
+					bundle.reload();
+				} catch (BundleException e) {
+					framework.publishFrameworkEvent(FrameworkEvent.ERROR, bundle, e);
+				}
+		}
 	}
 
 	protected void startHook() {
@@ -192,7 +215,10 @@
 	}
 
 	protected void stopHook() {
-		startLevelManager.shutdown();
+		if (updating.get())
+			startLevelManager.update();
+		else
+			startLevelManager.shutdown();
 	}
 
 	public void uninstallWorkerPrivileged() throws BundleException {
@@ -342,10 +368,6 @@
 		return (String) configuration.setProperty(key, value);
 	}
 
-	protected void load() {
-		super.load();
-	}
-
 	protected void refresh() {
 		super.refresh();
 		loadConstituents();
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
index 63ec6c8..3330406 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/AbstractBundle.java
@@ -10,8 +10,7 @@
  *******************************************************************************/
 package org.eclipse.osgi.framework.internal.core;
 
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.net.URL;
 import java.net.URLConnection;
 import java.security.*;
@@ -36,6 +35,7 @@
  * This class is abstract and is extended by BundleHost and BundleFragment.
  */
 public abstract class AbstractBundle implements Bundle, Comparable<Bundle>, KeyedElement, BundleStartLevel {
+	protected static final InputStream RELOAD = new ByteArrayInputStream(new byte[0]);
 	/** The Framework this bundle is part of */
 	protected final Framework framework;
 	/** The state of the bundle. */
@@ -557,6 +557,10 @@
 		update(null);
 	}
 
+	public void reload() throws BundleException {
+		update(RELOAD);
+	}
+
 	public void update(final InputStream in) throws BundleException {
 		if (Debug.DEBUG && Debug.DEBUG_GENERAL) {
 			Debug.println("update location " + bundledata.getLocation()); //$NON-NLS-1$
@@ -583,6 +587,8 @@
 							Debug.println("   from location: " + updateLocation); //$NON-NLS-1$
 						/* Map the update location to a URLConnection */
 						source = framework.adaptor.mapLocationToURLConnection(updateLocation);
+					} else if (in == RELOAD) {
+						source = null;
 					} else {
 						/* Map the InputStream to a URLConnection */
 						source = new BundleSource(in);
@@ -591,7 +597,7 @@
 					updateWorkerPrivileged(source, callerContext);
 					return null;
 				}
-			});
+			}, in == RELOAD);
 		} finally {
 			completeStateChange();
 		}
@@ -600,7 +606,7 @@
 	/**
 	 * Update worker. Assumes the caller has the state change lock.
 	 */
-	protected void updateWorker(PrivilegedExceptionAction action) throws BundleException {
+	final void updateWorker(PrivilegedExceptionAction action, boolean reload) throws BundleException {
 		int previousState = 0;
 		if (!isFragment())
 			previousState = state;
@@ -616,7 +622,8 @@
 		}
 		try {
 			AccessController.doPrivileged(action);
-			framework.publishBundleEvent(BundleEvent.UPDATED, this);
+			if (!reload)
+				framework.publishBundleEvent(BundleEvent.UPDATED, this);
 		} catch (PrivilegedActionException pae) {
 			if (pae.getException() instanceof RuntimeException)
 				throw (RuntimeException) pae.getException();
diff --git a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java
index b7fdb58..098452f 100644
--- a/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java
+++ b/bundles/org.eclipse.osgi/core/framework/org/eclipse/osgi/framework/internal/core/StartLevelManager.java
@@ -214,13 +214,11 @@
 		doSetStartLevel(0);
 	}
 
-	/**
-	 *  Internal worker method to set the startlevel
-	 *
-	 * @param newSL start level value                  
-	 * @param callerBundle - the bundle initiating the change in start level
-	 */
-	public void doSetStartLevel(int newSL) {
+	public void update() {
+		doSetStartLevel(0, FrameworkEvent.STOPPED_UPDATE);
+	}
+
+	private void doSetStartLevel(int newSL, int frameworkEvent) {
 		synchronized (lock) {
 			ClassLoader previousTCCL = Thread.currentThread().getContextClassLoader();
 			ClassLoader contextFinder = framework.getContextFinder();
@@ -261,7 +259,7 @@
 					}
 					if (newSL == 0) {
 						// stop and unload all bundles
-						stopSystemBundle();
+						stopSystemBundle(frameworkEvent);
 						unloadAllBundles(framework.bundles);
 					}
 				}
@@ -276,6 +274,16 @@
 		}
 	}
 
+	/**
+	 *  Internal worker method to set the startlevel
+	 *
+	 * @param newSL start level value                  
+	 * @param callerBundle - the bundle initiating the change in start level
+	 */
+	public void doSetStartLevel(int newSL) {
+		doSetStartLevel(newSL, FrameworkEvent.STOPPED);
+	}
+
 	/** 
 	 * This method is used within the package to save the actual active startlevel value for the framework.
 	 * Externally the setStartLevel method must be used.
@@ -602,7 +610,7 @@
 	/**
 	 *  Stop the system bundle
 	 */
-	private void stopSystemBundle() {
+	private void stopSystemBundle(int frameworkEvent) {
 		try {
 			systemBundle.context.stop();
 		} catch (BundleException sbe) {
@@ -617,7 +625,7 @@
 		framework.publishBundleEvent(BundleEvent.STOPPED, systemBundle);
 		if (systemBundle.getCompositeId() > 0) {
 			// TODO warning this is hacky should encapsulate this in CompositeImpl somehow
-			framework.publishFrameworkEvent(FrameworkEvent.STOPPED, systemBundle, null);
+			framework.publishFrameworkEvent(frameworkEvent, systemBundle, null);
 			systemBundle.state = Bundle.STARTING;
 			framework.publishBundleEvent(BundleEvent.STARTING, systemBundle);
 		}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUpdate.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUpdate.java
index 918c24d..9aae872 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUpdate.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/BundleUpdate.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * Copyright (c) 2005, 2010 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -24,10 +24,10 @@
 import org.osgi.framework.*;
 
 public class BundleUpdate implements BundleOperation {
-	private BaseData data;
+	private final BaseData data;
+	private final URLConnection source;
+	private final BaseStorage storage;
 	private BaseData newData;
-	private URLConnection source;
-	private BaseStorage storage;
 
 	public BundleUpdate(BaseData data, URLConnection source, BaseStorage storage) {
 		this.data = data;
@@ -42,6 +42,10 @@
 	 * @throws BundleException if an error occurs
 	 */
 	public BundleData begin() throws BundleException {
+		if (source == null) {
+			newData = data;
+			return newData;
+		}
 		try {
 			newData = storage.createBaseData(data.getBundleID(), data.getCompositeID(), data.getLocation());
 			newData.setLastModified(System.currentTimeMillis());
@@ -115,6 +119,10 @@
 	 */
 
 	public void commit(boolean postpone) throws BundleException {
+		if (newData == data) {
+			storage.updateState(newData, BundleEvent.UPDATED);
+			return;
+		}
 		storage.processExtension(data, BaseStorage.EXTENSION_UNINSTALLED); // remove the old extension
 		storage.processExtension(newData, BaseStorage.EXTENSION_UPDATED); // update to the new one
 		try {
@@ -138,6 +146,8 @@
 	 * @throws BundleException If a failure occured modifiying peristent storage.
 	 */
 	public void undo() throws BundleException {
+		if (newData == data)
+			return;
 		if (newData != null) {
 			BaseStorageHook newStorageHook = (BaseStorageHook) newData.getStorageHook(BaseStorageHook.KEY);
 			try {