/*******************************************************************************
 * Copyright (c) 2003, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.osgi.framework.internal.core;

import java.io.IOException;
import java.util.*;
import org.eclipse.osgi.framework.debug.Debug;
import org.eclipse.osgi.framework.debug.DebugOptions;
import org.eclipse.osgi.framework.util.SecureAction;
import org.eclipse.osgi.service.resolver.*;
import org.osgi.framework.*;
import org.osgi.service.packageadmin.*;
import org.osgi.service.packageadmin.ExportedPackage;
import org.osgi.service.packageadmin.NamedClassSpace;

/**
 * PackageAdmin service for the OSGi specification.
 *
 * Framework service which allows bundle programmers to inspect the packages
 * exported in the framework and eagerly update or uninstall bundles.
 *
 * If present, there will only be a single instance of this service
 * registered in the framework.
 *
 * <p> The term <i>exported package</i> (and the corresponding interface
 * {@link ExportedPackage}) refers to a package that has actually been
 * exported (as opposed to one that is available for export).
 *
 * <p> Note that the information about exported packages returned by this
 * service is valid only until the next time {@link #refreshPackages} is
 * called.
 * If an ExportedPackage becomes stale, (that is, the package it references
 * has been updated or removed as a result of calling
 * PackageAdmin.refreshPackages()),
 * its getName() and getSpecificationVersion() continue to return their
 * old values, isRemovalPending() returns true, and getExportingBundle()
 * and getImportingBundles() return null.
 */
public class PackageAdminImpl implements PackageAdmin {

	/** framework object */
	protected Framework framework;

	/** BundleLoaders that are pending removal. Value is BundleLoader */
	protected Vector removalPending;

	protected KeyedHashSet exportedPackages;
	protected KeyedHashSet exportedBundles;

	private long cumulativeTime;

	private static boolean restrictServiceClasses = false;

	/**
	 * Constructor.
	 *
	 * @param framework Framework object.
	 */
	protected PackageAdminImpl(Framework framework) {
		this.framework = framework;
	}

	protected void initialize() {
		restrictServiceClasses = System.getProperty(Constants.OSGI_RESTRICTSERVICECLASSES) != null;
		removalPending = new Vector(10, 10);

		State state = framework.adaptor.getState();
		if (!state.isResolved()) {
			state.resolve(false);
		}
		exportedPackages = new KeyedHashSet(false);
		exportedBundles = new KeyedHashSet(false);
	}

	private KeyedHashSet getExportedPackages(KeyedHashSet packageSet) {
		State state = framework.adaptor.getState();
		PackageSpecification[] packageSpecs = state.getExportedPackages();

		for (int i = 0; i < packageSpecs.length; i++) {
			BundleDescription bundleSpec = packageSpecs[i].getSupplier();
			if (bundleSpec == null)
				continue;
			AbstractBundle bundle = framework.getBundle(bundleSpec.getBundleId());
			if (bundle == null) {
				BundleException be = new BundleException(Msg.formatter.getString("BUNDLE_NOT_IN_FRAMEWORK",bundleSpec)); //$NON-NLS-1$
				framework.publishFrameworkEvent(FrameworkEvent.ERROR,framework.systemBundle,be);
				continue;
			}
			// check export permissions before getting the host;
			// we want to check the permissions of the fragment
			if (!bundle.checkExportPackagePermission(packageSpecs[i].getName()))
				continue;
			// if we have a host then get the host bundle
			HostSpecification hostSpec = bundleSpec.getHost();
			if (hostSpec != null) {
				bundleSpec = hostSpec.getSupplier();
				if (bundleSpec == null)
					continue;
				bundle = framework.getBundle(bundleSpec.getBundleId());
				if (bundle == null) {
					BundleException be = new BundleException(Msg.formatter.getString("BUNDLE_NOT_IN_FRAMEWORK",bundleSpec)); //$NON-NLS-1$
					framework.publishFrameworkEvent(FrameworkEvent.ERROR,framework.systemBundle,be);
					continue;
				}
			}

			if (bundle.isResolved() && bundle instanceof BundleHost) {
				ExportedPackageImpl packagesource = new ExportedPackageImpl(packageSpecs[i], ((BundleHost) bundle).getLoaderProxy());
				packageSet.add(packagesource);
			}
		}
		return packageSet;
	}

	private KeyedHashSet getExportedBundles(KeyedHashSet bundleSet) {
		State state = framework.adaptor.getState();
		BundleDescription[] bundleDescripts = state.getResolvedBundles();
		for (int i = 0; i < bundleDescripts.length; i++) {
			BundleDescription bundledes = bundleDescripts[i];
			AbstractBundle bundle = framework.getBundle(bundledes.getBundleId());
			if (bundle != null && bundle.isResolved() && bundle.getSymbolicName() != null && bundle instanceof BundleHost && bundle.checkProvideBundlePermission(bundle.getSymbolicName())) {
				BundleLoaderProxy loaderProxy = ((BundleHost) bundle).getLoaderProxy();
				bundleSet.add(loaderProxy);
			}
		}
		return bundleSet;
	}

	protected void cleanup() { //This is only called when the framework is shutting down
		removalPending = null;
		exportedPackages = null;
		exportedBundles = null;
	}

	protected void addRemovalPending(BundleLoaderProxy loaderProxy) {
		removalPending.addElement(loaderProxy);
	}

	protected void deleteRemovalPending(BundleLoaderProxy loaderProxy) throws BundleException {

		boolean exporting = loaderProxy.inUse();
		if (exporting) {
			/* Reaching here is an internal error */
			if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
				Debug.println("BundleLoader.unexportPackager returned true! " + loaderProxy);
				Debug.printStackTrace(new Exception("Stack trace"));
			}
			throw new BundleException(Msg.formatter.getString("OSGI_INTERNAL_ERROR")); //$NON-NLS-1$
		}
		unexportResources(loaderProxy);
		BundleLoader loader = loaderProxy.getBundleLoader();
		loader.clear();
		loader.close();
		removalPending.remove(loaderProxy);
	}

	/**
	 * Gets the packages exported by the specified bundle.
	 *
	 * @param bundle The bundle whose exported packages are to be returned,
	 *               or <tt>null</tt> if all the packages currently
	 *               exported in the framework are to be returned.  If the
	 *               specified bundle is the system bundle (that is, the
	 *               bundle with id 0), this method returns all the packages
	 *               on the system classpath whose name does not start with
	 *               "java.".  In an environment where the exhaustive list
	 *               of packages on the system classpath is not known in
	 *               advance, this method will return all currently known
	 *               packages on the system classpath, that is, all packages
	 *               on the system classpath that contains one or more classes
	 *               that have been loaded.
	 *
	 * @return The array of packages exported by the specified bundle,
	 * or <tt>null</tt> if the specified bundle has not exported any packages.
	 */
	public org.osgi.service.packageadmin.ExportedPackage[] getExportedPackages(org.osgi.framework.Bundle bundle) {
		// need to make sure the dependacies are marked before this call.
		synchronized (framework.bundles) {
			framework.bundles.markDependancies();

			KeyedElement[] elements = exportedPackages.elements();
			if (bundle != null) {
				Vector result = new Vector();
				for (int i = 0; i < elements.length; i++) {
					ExportedPackageImpl pkgElement = (ExportedPackageImpl) elements[i];
					if (pkgElement.supplier.getBundle() == bundle) {
						result.add(pkgElement);
					}
				}
				if (result.size() == 0) {
					return null;
				}
				ExportedPackageImpl[] pkgElements = new ExportedPackageImpl[result.size()];
				return (ExportedPackage[]) result.toArray(pkgElements);
			} else {
				if (elements.length == 0) {
					return null;
				}
				ExportedPackageImpl[] pkgElements = new ExportedPackageImpl[elements.length];
				System.arraycopy(elements, 0, pkgElements, 0, pkgElements.length);
				return pkgElements;
			}
		}
	}

	/**
	 * Gets the ExportedPackage with the specified package name.  All exported
	 * packages
	 * will be checked for the specified name.  In an environment where the
	 * exhaustive list of packages on the system classpath is not known in
	 * advance, this method attempts to see if the named package is on the
	 * system classpath.
	 * This
	 * means that this method may discover an ExportedPackage that was
	 * not present in the list returned by <tt>getExportedPackages()</tt>.
	 *
	 * @param name The name of the exported package to be returned.
	 *
	 * @return The exported package with the specified name, or <tt>null</tt>
	 *         if no expored package with that name exists.
	 */
	public org.osgi.service.packageadmin.ExportedPackage getExportedPackage(String packageName) {
		// need to make sure the dependacies are marked before this call.
		synchronized (framework.bundles) {
			framework.bundles.markDependancies();
			return (ExportedPackageImpl) exportedPackages.getByKey(packageName);
		}
	}

	/**
	 * Forces the update (replacement) or removal of packages exported by
	 * the specified bundles.
	 *
	 * <p> If no bundles are specified, this method will update or remove any
	 * packages exported by any bundles that were previously updated or
	 * uninstalled. The technique by which this is accomplished
	 * may vary among different framework implementations. One permissible
	 * implementation is to stop and restart the Framework.
	 *
	 * <p> This method returns to the caller immediately and then performs the
	 * following steps in its own thread:
	 *
	 * <ol>
	 * <p>
	 * <li> Compute a graph of bundles starting with the specified ones. If no
	 * bundles are specified, compute a graph of bundles starting with
	 * previously updated or uninstalled ones.
	 * Any bundle that imports a package that is currently exported
	 * by a bundle in the graph is added to the graph. The graph is fully
	 * constructed when there is no bundle outside the graph that imports a
	 * package from a bundle in the graph. The graph may contain
	 * <tt>UNINSTALLED</tt> bundles that are currently still
	 * exporting packages.
	 *
	 * <p>
	 * <li> Each bundle in the graph will be stopped as described in the
	 * <tt>Bundle.stop</tt> method.
	 *
	 * <p>
	 * <li> Each bundle in the graph that is in the
	 * <tt>RESOLVED</tt> state is moved
	 * to the <tt>INSTALLED</tt> state.
	 * The effect of this step is that bundles in the graph are no longer
	 * <tt>RESOLVED</tt>.
	 *
	 * <p>
	 * <li> Each bundle in the graph that is in the UNINSTALLED state is
	 * removed from the graph and is now completely removed from the framework.
	 *
	 * <p>
	 * <li> Each bundle in the graph that was in the
	 * <tt>ACTIVE</tt> state prior to Step 2 is started as
	 * described in the <tt>Bundle.start</tt> method, causing all
	 * bundles required for the restart to be resolved.
	 * It is possible that, as a
	 * result of the previous steps, packages that were
	 * previously exported no longer are. Therefore, some bundles
	 * may be unresolvable until another bundle
	 * offering a compatible package for export has been installed in the
	 * framework.
	 * </ol>
	 *
	 * <p> For any exceptions that are thrown during any of these steps, a
	 * <tt>FrameworkEvent</tt> of type <tt>ERROR</tt> is
	 * broadcast, containing the exception.
	 *
	 * @param bundles the bundles whose exported packages are to be updated or
	 * removed,
	 * or <tt>null</tt> for all previously updated or uninstalled bundles.
	 *
	 * @exception SecurityException if the caller does not have the
	 * <tt>AdminPermission</tt> and the Java runtime environment supports
	 * permissions.
	 */
	public void refreshPackages(org.osgi.framework.Bundle[] input) {
		framework.checkAdminPermission();

		AbstractBundle[] copy = null;
		if (input != null) {
			synchronized (input) {
				int size = input.length;

				copy = new AbstractBundle[size];

				System.arraycopy(input, 0, copy, 0, size);
			}
		}

		final AbstractBundle[] bundles = copy;
		Thread refresh = SecureAction.createThread(new Runnable() {
			public void run() {
				refreshPackages(bundles);
			}
		}, "Refresh Packages");

		refresh.start();
	}

	/**
	 * Worker routine called on a seperate thread to perform the actual work.
	 *
	 * @param Seed for the graph.
	 */
	protected void refreshPackages(AbstractBundle[] refresh) {
		try {
			Vector graph = null;
			synchronized (framework.bundles) {
				if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
					Debug.println("refreshPackages: Initialize graph");
				}
				// make sure the dependencies are marked first
				framework.bundles.markDependancies();

				graph = computeAffectedBundles(refresh);

				// get the state.
				State state = framework.adaptor.getState();
				// resolve the state.
				state.resolve(false);

				// process the delta.  This will set the state of all
				// the bundles in the graph.
				processDelta(graph);
			}
			/*
			 * Resume the suspended bundles outside of the synchronization block.
			 * This will cause the bundles to be resolved using the most up-to-date
			 * generations of the bundles.
			 */
			resumeBundles(graph);

		} finally {
			framework.publishFrameworkEvent(FrameworkEvent.PACKAGES_REFRESHED, framework.systemBundle, null);
		}

	}

	private void resumeBundles(Vector graph) {

		AbstractBundle[] refresh = new AbstractBundle[graph.size()];
		boolean[] previouslyResolved = new boolean[graph.size()];
		graph.copyInto(refresh);
		Util.sort(refresh, 0, graph.size());
		if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
			Debug.println("refreshPackages: restart the bundles");
		}
		for (int i = 0; i < refresh.length; i++) {
			AbstractBundle bundle = (AbstractBundle) refresh[i];
			if (bundle.isResolved())
				framework.resumeBundle(bundle);
		}
	}

	private void processDelta(Vector graph) {
		AbstractBundle[] refresh = new AbstractBundle[graph.size()];
		boolean[] previouslyResolved = new boolean[graph.size()];
		graph.copyInto(refresh);
		Util.sort(refresh, 0, graph.size());

		Vector notify = new Vector();
		try {
			try {
				/*
				 * Suspend each bundle and grab its state change lock.
				 */
				if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
					Debug.println("refreshPackages: Suspend each bundle and acquire its state change lock");
				}
				for (int i = refresh.length - 1; i >= 0; i--) {
					AbstractBundle changedBundle = refresh[i];
					previouslyResolved[i] = changedBundle.isResolved();
					if (changedBundle.isActive() && !changedBundle.isFragment()) {
						boolean suspended = framework.suspendBundle(changedBundle, true);
						if (!suspended) {
							throw new BundleException(Msg.formatter.getString("BUNDLE_STATE_CHANGE_EXCEPTION")); //$NON-NLS-1$
						}
					} else {
						changedBundle.beginStateChange();
					}

					if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
						if (changedBundle.stateChanging == null) {
							Debug.println("Bundle state change lock is clear! " + changedBundle);
							Debug.printStackTrace(new Exception("Stack trace"));
						}
					}
				}
				/*
				 * Refresh the bundles which will unexport the packages.
				 * This will move RESOLVED bundles to the INSTALLED state.
				 */
				if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
					Debug.println("refreshPackages: refresh the bundles");
				}
				/*
				 * Unimport detached BundleLoaders for bundles in the graph.
				 */
				for (int i = removalPending.size() - 1; i >= 0; i--) {
					BundleLoaderProxy loaderProxy = (BundleLoaderProxy) removalPending.elementAt(i);

					if (graph.contains(loaderProxy.getBundle())) {
						framework.bundles.unMarkDependancies(loaderProxy);
					}
				}

				for (int i = 0; i < refresh.length; i++) {
					AbstractBundle changedBundle = refresh[i];
					changedBundle.refresh();
					// send out unresolved events
					if (previouslyResolved[i])
						framework.publishBundleEvent(BundleEvent.UNRESOLVED, changedBundle);
				}

				/*
				 * Cleanup detached BundleLoaders for bundles in the graph.
				 */
				if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
					Debug.println("refreshPackages: unexport the removal pending packages");
				}
				for (int i = removalPending.size() - 1; i >= 0; i--) {
					BundleLoaderProxy loaderProxy = (BundleLoaderProxy) removalPending.elementAt(i);
					AbstractBundle removedBundle = loaderProxy.getBundle();

					if (graph.contains(removedBundle)) {
						deleteRemovalPending(loaderProxy);
					}
				}

				// set the resolved bundles state
				List allBundles = framework.bundles.getBundles();
				int size = allBundles.size();
				for (int i = 0; i < size; i++) {
					AbstractBundle bundle = (AbstractBundle) allBundles.get(i);
					if (bundle.isResolved())
						continue;
					BundleDescription bundleDes = bundle.getBundleDescription();
					if (bundleDes != null) {
						if (bundleDes.isResolved()) {
							if (bundle.isFragment()) {
								BundleHost host = (BundleHost) framework.getBundle(bundleDes.getHost().getSupplier().getBundleId());
								if (((BundleFragment) bundle).setHost(host)) {
									bundle.resolve();
								}
							} else {
								bundle.resolve();
							}
							if (bundle.isResolved()) {
								notify.addElement(bundle);
							}
						}
					}
				}

				// update the exported package and bundle lists.
				exportedPackages = getExportedPackages(exportedPackages);
				exportedBundles = getExportedBundles(exportedBundles);
			} finally {
				/*
				 * Release the state change locks.
				 */
				if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
					Debug.println("refreshPackages: release the state change locks");
				}
				for (int i = 0; i < refresh.length; i++) {
					AbstractBundle changedBundle = refresh[i];
					changedBundle.completeStateChange();
				}
			}
			/*
			 * Take this opportunity to clean up the adaptor storage.
			 */
			if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
				Debug.println("refreshPackages: clean up adaptor storage");
			}
			try {
				framework.adaptor.compactStorage();
			} catch (IOException e) {
				if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
					Debug.println("refreshPackages exception: " + e.getMessage());
					Debug.printStackTrace(e);
				}
				framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, new BundleException(Msg.formatter.getString("BUNDLE_REFRESH_FAILURE"), e)); //$NON-NLS-1$
			}
		} catch (BundleException e) {
			if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
				Debug.println("refreshPackages exception: " + e.getMessage());
				Debug.printStackTrace(e.getNestedException());
			}
			framework.publishFrameworkEvent(FrameworkEvent.ERROR, framework.systemBundle, new BundleException(Msg.formatter.getString("BUNDLE_REFRESH_FAILURE"), e)); //$NON-NLS-1$
		}

		// send out any resolved/unresolved events
		for (int i = 0; i < notify.size(); i++) {
			AbstractBundle changedBundle = (AbstractBundle) notify.elementAt(i);
			framework.publishBundleEvent(changedBundle.isResolved() ? BundleEvent.RESOLVED : BundleEvent.UNRESOLVED, changedBundle);
		}

	}

	private void unresolvePermissions(Vector bundles, Hashtable packages) {
		/*
		 * All bundles must be notified of the unexported packages so that
		 * they may unresolve permissions if necessary.
		 * This done after resolve bundles so that unresolved permissions
		 * can be immediately resolved.
		 */
		if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
			Debug.println("refreshPackages: unresolve permissions");
		}
		int size = bundles.size();
		for (int i = 0; i < size; i++) {
			AbstractBundle bundle = (AbstractBundle) bundles.elementAt(i);
			bundle.unresolvePermissions(packages);
		}
	}

	private Vector computeAffectedBundles(AbstractBundle[] refresh) {
		Vector graph = new Vector();

		if (refresh == null) {
			int size = removalPending.size();
			for (int i = 0; i < size; i++) {
				BundleLoaderProxy loaderProxy = (BundleLoaderProxy) removalPending.elementAt(i);
				AbstractBundle bundle = loaderProxy.getBundle();
				if (!graph.contains(bundle)) {
					if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
						Debug.println(" refresh: " + bundle);
					}
					graph.addElement(bundle);

					// add in any dependents of the removal pending loader.
					AbstractBundle[] dependents = loaderProxy.getDependentBundles();
					for (int j = 0; j < dependents.length; j++) {
						if (!graph.contains(dependents[j])) {
							graph.addElement(dependents[j]);
						}
					}
				}
			}
		} else {
			for (int i = 0; i < refresh.length; i++) {
				AbstractBundle bundle = refresh[i];
				if (bundle == framework.systemBundle) {
					continue;
				}
				if (bundle.isFragment()) {
					// if it is a fragment then put the host in the graph
					BundleHost host = (BundleHost) bundle.getHost();
					if (host != null) {
						if (!graph.contains(host)) {
							graph.addElement(host);
						}
					}
				}

				if (!graph.contains(bundle)) {
					if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
						Debug.println(" refresh: " + bundle);
					}
					graph.addElement(bundle);
				}
			}
		}

		/*
		 * If there is nothing to do, then return.
		 */
		if (graph.size() == 0) {
			if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
				Debug.println("refreshPackages: Empty graph");
			}

			return graph;
		}

		/*
		 * Complete graph.
		 */
		if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
			Debug.println("refreshPackages: Complete graph");
		}

		boolean changed;
		do {
			changed = false;
			int size = graph.size();
			for (int i = size - 1; i >= 0; i--) {
				AbstractBundle bundle = (AbstractBundle) graph.elementAt(i);
				if (!bundle.isFragment()) {
					BundleLoaderProxy loaderProxy = ((BundleHost) bundle).getLoaderProxy();
					if (loaderProxy != null) {
						// add any dependents
						AbstractBundle[] dependents = loaderProxy.getDependentBundles();
						for (int j = 0; j < dependents.length; j++) {
							if (!graph.contains(dependents[j])) {
								graph.addElement(dependents[j]);
								changed = true;
							}
						}
					}
					// add in any fragments
					org.osgi.framework.Bundle[] frags = bundle.getFragments();
					if (frags != null) {
						for (int j = 0; j < frags.length; j++) {
							if (!graph.contains(frags[j])) {
								graph.addElement(frags[j]);
								changed = true;
							}
						}
					}
				} else {
					// add in the host.
					AbstractBundle host = (AbstractBundle) bundle.getHost();
					if (host != null) {
						if (!graph.contains(host)) {
							graph.addElement(host);
							changed = true;
						}
					}
				}
			}

			// look for the bundles in removalPending list
			for (int i = removalPending.size() - 1; i >= 0; i--) {
				BundleLoaderProxy removedLoaderProxy = (BundleLoaderProxy) removalPending.elementAt(i);
				AbstractBundle removedBundle = removedLoaderProxy.getBundle();

				if (graph.contains(removedBundle)) {
					// add in the dependents of the removedLoaderProxy
					AbstractBundle[] dependents = removedLoaderProxy.getDependentBundles();
					for (int k = 0; k < dependents.length; k++) {
						if (!graph.contains(dependents[k])) {
							graph.addElement(dependents[k]);
							changed = true;
						}
					}
				}
			}
		} while (changed);

		return graph;
	}

	/**
	 * Sets all the bundles in the state that are resolved to the resolved
	 * state.  This should only be called when the framework is launching.
	 *
	 */
	protected void setResolvedBundles() {
		State state = framework.adaptor.getState();
		BundleDescription[] descriptions = state.getBundles();
		for (int i = 0; i < descriptions.length; i++) {
			long bundleId = descriptions[i].getBundleId();
			AbstractBundle bundle = framework.getBundle(bundleId);
			if (bundle == null ) {
				BundleException be = new BundleException(Msg.formatter.getString("BUNDLE_NOT_IN_FRAMEWORK",descriptions[i])); //$NON-NLS-1$
				framework.publishFrameworkEvent(FrameworkEvent.ERROR,framework.systemBundle,be);
			}
			if (bundle != framework.systemBundle) {
				if (descriptions[i].isResolved()) {
					if (bundle.isFragment()) {
						BundleHost host = (BundleHost) framework.getBundle(descriptions[i].getHost().getSupplier().getBundleId());
						if (((BundleFragment) bundle).setHost(host)) {
							bundle.resolve();
						}
					} else {
						bundle.resolve();
					}
				}
			}
		}
		exportedPackages = getExportedPackages(exportedPackages);
		exportedBundles = getExportedBundles(exportedBundles);
	}

	/**
	 * A permissible implementation of this method is to attempt to 
	 * resolve all unresolved bundles installed in the framework.
	 * That is what this method does.
	 * @param bundles the set of bundles to attempt to resolve.
	 */
	public void resolveBundles(org.osgi.framework.Bundle[] bundles) {
		resolveBundles();
	}

	/**
	 * Attempt to resolve all unresolved bundles. When this method returns
	 * all bundles are resolved that can be resolved. A resolved bundle
	 * has exported and imported packages. An unresolved bundle neither
	 * exports nor imports packages.
	 *
	 */
	protected void resolveBundles() {
		long start = 0;
		if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN_TIMING)
			start = System.currentTimeMillis();
		/*
		 * Resolve the bundles. This will make there exported packages available.
		 */
		if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN) {
			Debug.println("refreshBundles: resolve bundles");
		}

		Vector notify = new Vector();
		synchronized (framework.bundles) {
			boolean resolveNeeded = false;
			List allBundles = framework.bundles.getBundles();
			int size = allBundles.size();

			// first check to see if there is anything to resolve
			for (int i = 0; i < size; i++) {
				if (!((AbstractBundle) allBundles.get(i)).isResolved())
					resolveNeeded = true;
			}
			if (!resolveNeeded)
				return;

			// get the state and resolve it.
			framework.adaptor.getState().resolve(false);
			for (int i = 0; i < size; i++) {
				AbstractBundle bundle = (AbstractBundle) allBundles.get(i);
				BundleDescription changedBundleDes = bundle.getBundleDescription();
				boolean previouslyResolved = bundle.isResolved();

				if (bundle != framework.systemBundle && changedBundleDes != null) {
					if (changedBundleDes.isResolved() && !previouslyResolved) {
						if (bundle.isFragment()) {
							BundleHost host = (BundleHost) framework.getBundle(changedBundleDes.getHost().getSupplier().getBundleId());
							if (((BundleFragment) bundle).setHost(host)) {
								bundle.resolve();
							}
						} else {
							bundle.resolve();
						}
						if (bundle.isResolved()) {
							notify.add(bundle);
						}
					} else if (!changedBundleDes.isResolved() && previouslyResolved) {
						// Need to log error.  This should not happen since the state should not touch
						// bundles that we did not pass in to the resolve() call.
						framework.publishFrameworkEvent(FrameworkEvent.ERROR, bundle, new BundleException(Msg.formatter.getString("STATE_UNRESOLVED_WRONG_BUNDLE", bundle.getLocation()))); //$NON-NLS-1$
					}
				} else {
					if (bundle != framework.systemBundle) {
						framework.publishFrameworkEvent(FrameworkEvent.ERROR, bundle, new BundleException(Msg.formatter.getString("BUNDLE_NOT_IN_STATE", bundle.getLocation()))); //$NON-NLS-1$
					}
				}
			}

			// update the exported package and bundle lists.
			exportedPackages = getExportedPackages(exportedPackages);
			exportedBundles = getExportedBundles(exportedBundles);
		}
		for (int i = 0; i < notify.size(); i++) {
			AbstractBundle bundle = (AbstractBundle) notify.elementAt(i);
			if (bundle != null) {
				framework.publishBundleEvent(bundle.isResolved() ? BundleEvent.RESOLVED : BundleEvent.UNRESOLVED, bundle);
			}
		}
		if (Debug.DEBUG && Debug.DEBUG_PACKAGEADMIN_TIMING) {
			cumulativeTime = cumulativeTime + System.currentTimeMillis() - start;
			DebugOptions.getDefault().setOption(Debug.OPTION_DEBUG_PACKAGEADMIN_TIMING + "/value", Long.toString(cumulativeTime)); //$NON-NLS-1$
		}
	}

	protected void unexportResources(BundleLoaderProxy proxy) {
		KeyedElement[] bundles = exportedBundles.elements();
		for (int i = 0; i < bundles.length; i++) {
			BundleLoaderProxy loaderProxy = (BundleLoaderProxy) bundles[i];
			if (loaderProxy == proxy) {
				exportedBundles.remove(proxy);
			}
		}

		KeyedElement[] packages = exportedPackages.elements();
		for (int i = 0; i < packages.length; i++) {
			PackageSource source = (PackageSource) packages[i];
			BundleLoaderProxy sourceProxy = source.getSupplier();
			if (sourceProxy == proxy) {
				exportedPackages.remove(source);
			}
		}
		// make the proxy stale
		proxy.setStale();
	}

	protected BundleDescription[] getBundleDescriptions(Vector graph) {
		ArrayList result = new ArrayList();
		int size = graph.size();
		for (int i = 0; i < size; i++) {
			AbstractBundle bundle = (AbstractBundle) graph.elementAt(i);
			BundleDescription bundleDes = bundle.getBundleDescription();
			if (bundleDes != null) {
				result.add(bundleDes);
			}
		}
		return (BundleDescription[]) result.toArray(new BundleDescription[result.size()]);
	}

	public NamedClassSpace[] getNamedClassSpaces(String symbolicName) {
		if (exportedBundles == null || exportedBundles.size() == 0)
			return null;

		// need to make sure the dependacies are marked before this call.
		framework.bundles.markDependancies();

		KeyedElement[] allSymbolicBundles = exportedBundles.elements();
		if (symbolicName == null) {
			if (allSymbolicBundles.length == 0) {
				return null;
			}
			NamedClassSpace[] result = new NamedClassSpace[allSymbolicBundles.length];
			System.arraycopy(allSymbolicBundles, 0, result, 0, result.length);
			return result;
		} else {
			ArrayList result = new ArrayList();
			for (int i = 0; i < allSymbolicBundles.length; i++) {
				NamedClassSpace symBundle = (NamedClassSpace) allSymbolicBundles[i];
				if (symBundle.getName().equals(symbolicName))
					result.add(symBundle);
			}
			return (NamedClassSpace[]) result.toArray(new NamedClassSpace[result.size()]);
		}
	}

	public org.osgi.framework.Bundle[] getBundles(String symbolicName, String version, String match) {
		if (symbolicName == null) {
			throw new IllegalArgumentException();
		}

		AbstractBundle bundles[] = framework.getBundleByUniqueId(symbolicName);
		if (bundles == null)
			return null;

		if (version == null)
			return bundles;

		// This code depends on the array of bundles being in descending
		// version order.
		ArrayList result = new ArrayList();
		Version ver = new Version(version);
		for (int i = 0; i < bundles.length; i++) {
			if (matchBundle(bundles[i], ver, match)) {
				result.add(bundles[i]);
			}
		}

		if (result.size() == 0)
			return null;
		else
			return (AbstractBundle[]) result.toArray(new AbstractBundle[result.size()]);
	}

	private boolean matchBundle(AbstractBundle bundle, Version version, String match) {
		match = match == null ? Constants.VERSION_MATCH_GREATERTHANOREQUAL : match;
		boolean result = false;
		if (match.equalsIgnoreCase(Constants.VERSION_MATCH_QUALIFIER))
			result = bundle.getVersion().matchQualifier(version);
		else if (match.equalsIgnoreCase(Constants.VERSION_MATCH_MICRO))
			result = bundle.getVersion().matchMicro(version);
		else if (match.equalsIgnoreCase(Constants.VERSION_MATCH_MINOR))
			result = bundle.getVersion().matchMinor(version);
		else if (match.equalsIgnoreCase(Constants.VERSION_MATCH_MAJOR))
			result = bundle.getVersion().matchMajor(version);
		else if (match.equalsIgnoreCase(Constants.VERSION_MATCH_GREATERTHANOREQUAL))
			result = bundle.getVersion().matchGreaterOrEqualTo(version);

		return result;
	}

	public org.osgi.framework.Bundle[] getFragments(org.osgi.framework.Bundle bundle) {
		return ((AbstractBundle) bundle).getFragments();
	}

	public org.osgi.framework.Bundle[] getHosts(org.osgi.framework.Bundle bundle) {
		org.osgi.framework.Bundle host = ((AbstractBundle) bundle).getHost();
		if (host == null)
			return null;
		else
			return new org.osgi.framework.Bundle[] {host};
	}

	public int getBundleType(org.osgi.framework.Bundle bundle) {
		return ((AbstractBundle) bundle).isFragment() ? PackageAdminImpl.BUNDLE_TYPE_FRAGMENT : 0;
	}

	protected Class loadServiceClass(String className, AbstractBundle bundle) {
		try {
			if (restrictServiceClasses || bundle == null)
				return framework.adaptor.getBundleClassLoaderParent().loadClass(className);
			else
				return bundle.loadClass(className, false);
		} catch (ClassNotFoundException e) {
			// do nothing; try exported packages
		}

		// try exported packages; SERVICE class space
		String pkgname = BundleLoader.getPackageName(className);
		if (pkgname != null) {
			PackageSource exporter = (PackageSource) exportedPackages.getByKey(pkgname);
			if (exporter != null) {
				Class serviceClass = exporter.getSupplier().getBundleLoader().findLocalClass(className);
				if (serviceClass != null)
					return serviceClass;
			}
		}

		// try bundle's PRIVATE class space if we are restricting service classes
		if (restrictServiceClasses && bundle != null)
			return bundle.getBundleLoader().findLocalClass(className);

		return null;
	}
}