*** empty log message ***
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF
index e84450a..d7734fc 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk/META-INF/MANIFEST.MF
@@ -7,6 +7,7 @@
 Bundle-Version: 0.1.0.qualifier
 Bundle-Activator: org.eclipse.equinox.internal.p2.ui.sdk.ProvSDKUIActivator
 Import-Package: org.eclipse.equinox.internal.p2.core.helpers,
+ org.eclipse.equinox.internal.p2.publisher,
  org.eclipse.equinox.internal.provisional.p2.artifact.repository,
  org.eclipse.equinox.internal.provisional.p2.core,
  org.eclipse.equinox.internal.provisional.p2.core.eventbus,
@@ -14,7 +15,6 @@
  org.eclipse.equinox.internal.provisional.p2.director,
  org.eclipse.equinox.internal.provisional.p2.engine,
  org.eclipse.equinox.internal.provisional.p2.metadata,
- org.eclipse.equinox.internal.provisional.p2.metadata.generator,
  org.eclipse.equinox.internal.provisional.p2.metadata.query,
  org.eclipse.equinox.internal.provisional.p2.metadata.repository,
  org.eclipse.equinox.internal.provisional.p2.query,
diff --git a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/externalFiles/ExternalFileHandler.java b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/externalFiles/ExternalFileHandler.java
index bf2affb..6f1f04a 100644
--- a/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/externalFiles/ExternalFileHandler.java
+++ b/bundles/org.eclipse.equinox.p2.ui.sdk/src/org/eclipse/equinox/internal/p2/ui/sdk/externalFiles/ExternalFileHandler.java
@@ -18,11 +18,11 @@
 import java.util.zip.ZipInputStream;
 import org.eclipse.core.runtime.*;
 import org.eclipse.equinox.internal.p2.core.helpers.FileUtils;
+import org.eclipse.equinox.internal.p2.publisher.BundleDescriptionFactory;
 import org.eclipse.equinox.internal.p2.ui.sdk.ProvSDKMessages;
 import org.eclipse.equinox.internal.p2.ui.sdk.ProvSDKUIActivator;
 import org.eclipse.equinox.internal.p2.ui.sdk.prefs.PreferenceConstants;
 import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
-import org.eclipse.equinox.internal.provisional.p2.metadata.generator.BundleDescriptionFactory;
 import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository;
 import org.eclipse.equinox.internal.provisional.p2.ui.ProvUI;
 import org.eclipse.equinox.internal.provisional.p2.ui.ProvisioningOperationRunner;
@@ -31,13 +31,10 @@
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
 import org.eclipse.osgi.service.datalocation.Location;
-import org.eclipse.osgi.service.resolver.PlatformAdmin;
-import org.eclipse.osgi.service.resolver.StateObjectFactory;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.custom.BusyIndicator;
 import org.eclipse.swt.widgets.Shell;
 import org.eclipse.ui.statushandlers.StatusManager;
-import org.osgi.framework.ServiceReference;
 
 /**
  * Utility class that handles files or folders that are not recognized as valid
@@ -179,29 +176,12 @@
 	boolean isBundle() {
 		if (file == null)
 			return false;
-		BundleDescriptionFactory factory = getBundleDescriptionFactory();
+		BundleDescriptionFactory factory = BundleDescriptionFactory.getBundleDescriptionFactory(ProvSDKUIActivator.getContext());
 		if (factory == null)
 			return false;
 		return factory.getBundleDescription(file) != null;
 	}
 
-	private BundleDescriptionFactory getBundleDescriptionFactory() {
-
-		ServiceReference reference = ProvSDKUIActivator.getContext().getServiceReference(PlatformAdmin.class.getName());
-		if (reference == null)
-			return null;
-		PlatformAdmin platformAdmin = (PlatformAdmin) ProvSDKUIActivator.getContext().getService(reference);
-		if (platformAdmin == null)
-			return null;
-
-		try {
-			StateObjectFactory stateObjectFactory = platformAdmin.getFactory();
-			return new BundleDescriptionFactory(stateObjectFactory, null);
-		} finally {
-			ProvSDKUIActivator.getContext().ungetService(reference);
-		}
-	}
-
 	boolean isArchive() {
 		if (file == null)
 			return false;
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF
index 471bbe4..4fdb4dc 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.p2.updatesite/META-INF/MANIFEST.MF
@@ -8,12 +8,13 @@
 Bundle-Activator: org.eclipse.equinox.internal.p2.updatesite.Activator
 Eclipse-LazyStart: true
 Import-Package: org.eclipse.equinox.internal.p2.core.helpers,
- org.eclipse.equinox.internal.p2.metadata.generator.features,
+ org.eclipse.equinox.internal.p2.publisher,
+ org.eclipse.equinox.internal.p2.publisher.actions,
+ org.eclipse.equinox.internal.p2.publisher.features,
  org.eclipse.equinox.internal.provisional.p2.artifact.repository,
  org.eclipse.equinox.internal.provisional.p2.core,
  org.eclipse.equinox.internal.provisional.p2.core.repository,
  org.eclipse.equinox.internal.provisional.p2.metadata,
- org.eclipse.equinox.internal.provisional.p2.metadata.generator,
  org.eclipse.equinox.internal.provisional.p2.metadata.repository,
  org.eclipse.equinox.internal.provisional.p2.query,
  org.eclipse.equinox.internal.provisional.spi.p2.artifact.repository,
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/Messages.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/Messages.java
index 0d85653..fce0094 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/Messages.java
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/Messages.java
@@ -20,10 +20,6 @@
 	private static final String BUNDLE_NAME = "org.eclipse.equinox.internal.p2.updatesite.messages"; //$NON-NLS-1$
 
 	public static String ErrorCreatingRepository;
-	public static String ErrorReadingDigest;
-	public static String ErrorReadingFeature;
-	public static String ErrorReadingSite;
-	public static String InvalidRepositoryLocation;
 	public static String MalformedArchiveURL;
 	public static String PlatformAdminNotRegistered;
 
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/RemoteFeaturesAction.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/RemoteFeaturesAction.java
new file mode 100644
index 0000000..d68be12
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/RemoteFeaturesAction.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Code 9 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 http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: 
+ *   Code 9 - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.internal.p2.updatesite;
+
+import java.util.Dictionary;
+import java.util.Properties;
+import org.eclipse.equinox.internal.p2.publisher.*;
+import org.eclipse.equinox.internal.p2.publisher.actions.FeaturesAction;
+import org.eclipse.equinox.internal.p2.publisher.features.Feature;
+import org.eclipse.equinox.internal.p2.publisher.features.FeatureEntry;
+import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey;
+import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
+import org.eclipse.osgi.service.resolver.BundleDescription;
+
+public class RemoteFeaturesAction extends FeaturesAction {
+
+	public RemoteFeaturesAction(Feature[] features) {
+		super(features);
+	}
+
+	protected void generateFeatureIUs(Feature[] features, IPublisherResult result, IPublisherInfo info) {
+		Properties extraProperties = new Properties();
+		extraProperties.put(IInstallableUnit.PROP_PARTIAL_IU, Boolean.TRUE.toString());
+		BundleDescriptionFactory bundleDesciptionFactory = BundleDescriptionFactory.getBundleDescriptionFactory(Activator.getBundleContext());
+
+		for (int i = 0; i < features.length; i++) {
+			Feature feature = features[i];
+			FeatureEntry[] featureEntries = feature.getEntries();
+			for (int j = 0; j < featureEntries.length; j++) {
+				FeatureEntry entry = featureEntries[j];
+				if (entry.isPlugin() && !entry.isRequires()) {
+					Dictionary mockManifest = new Properties();
+					mockManifest.put("Manifest-Version", "1.0"); //$NON-NLS-1$ //$NON-NLS-2$
+					mockManifest.put("Bundle-ManifestVersion", "2"); //$NON-NLS-1$ //$NON-NLS-2$
+					mockManifest.put("Bundle-SymbolicName", entry.getId()); //$NON-NLS-1$
+					mockManifest.put("Bundle-Version", entry.getVersion()); //$NON-NLS-1$
+					BundleDescription bundleDescription = bundleDesciptionFactory.getBundleDescription(mockManifest, null);
+					IArtifactKey key = MetadataGeneratorHelper.createBundleArtifactKey(entry.getId(), entry.getVersion());
+					IInstallableUnit[] bundleIUs = MetadataGeneratorHelper.createEclipseIU(bundleDescription, null, entry.isUnpack(), key, extraProperties);
+					for (int n = 0; n < bundleIUs.length; n++)
+						result.addIU(bundleIUs[n], IPublisherResult.ROOT);
+				}
+			}
+			IInstallableUnit featureIU = createFeatureJarIU(feature, null, true, null);
+			IInstallableUnit groupIU = createGroupIU(feature, featureIU, null);
+			result.addIU(featureIU, IPublisherResult.ROOT);
+			result.addIU(groupIU, IPublisherResult.ROOT);
+		}
+	}
+}
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/RemoteUpdateSiteAction.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/RemoteUpdateSiteAction.java
new file mode 100644
index 0000000..a8bed60
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/RemoteUpdateSiteAction.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Code 9 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 http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors: 
+ *   Code 9 - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.equinox.internal.p2.updatesite;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.equinox.internal.p2.publisher.*;
+import org.eclipse.equinox.internal.p2.publisher.actions.SiteXMLAction;
+import org.eclipse.equinox.internal.p2.publisher.features.UpdateSite;
+import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
+
+/**
+ * A publishing action that processes a remote (URL-based) update site and generates
+ * metadata and artifacts for the features, bundles and site index (categories etc).  The 
+ * IUs generated for the bundles are "partial" as the bundles themselves are not downloaded.
+ */
+public class RemoteUpdateSiteAction implements IPublishingAction {
+	protected String source;
+	private UpdateSite updateSite;
+
+	public RemoteUpdateSiteAction(UpdateSite updateSite) {
+		this.updateSite = updateSite;
+	}
+
+	public RemoteUpdateSiteAction(String source) {
+		this.source = source;
+	}
+
+	public IStatus perform(IPublisherInfo info, IPublisherResult results) {
+		IPublishingAction[] actions = createActions();
+		for (int i = 0; i < actions.length; i++)
+			actions[i].perform(info, results);
+		return Status.OK_STATUS;
+	}
+
+	protected IPublishingAction[] createActions() {
+		try {
+			ArrayList result = new ArrayList();
+			result.add(new RemoteFeaturesAction(updateSite.loadFeatures()));
+			result.add(createSiteXMLAction());
+			return (IPublishingAction[]) result.toArray(new IPublishingAction[result.size()]);
+		} catch (ProvisionException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return new IPublishingAction[0];
+	}
+
+	private IPublishingAction createSiteXMLAction() {
+		if (updateSite != null)
+			return new SiteXMLAction(updateSite);
+		if (source != null) {
+			try {
+				return new SiteXMLAction(new URL(source + "/site.xml")); //$NON-NLS-1$
+			} catch (MalformedURLException e) {
+				// never happens
+				return null;
+			}
+		}
+		return null;
+	}
+}
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/artifact/UpdateSiteArtifactRepository.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/artifact/UpdateSiteArtifactRepository.java
index 41bb6f0..b2c5934 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/artifact/UpdateSiteArtifactRepository.java
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/artifact/UpdateSiteArtifactRepository.java
@@ -16,12 +16,14 @@
 import java.net.URL;
 import java.util.*;
 import org.eclipse.core.runtime.*;
-import org.eclipse.equinox.internal.p2.updatesite.*;
+import org.eclipse.equinox.internal.p2.publisher.MetadataGeneratorHelper;
+import org.eclipse.equinox.internal.p2.publisher.features.*;
+import org.eclipse.equinox.internal.p2.updatesite.Activator;
+import org.eclipse.equinox.internal.p2.updatesite.Messages;
 import org.eclipse.equinox.internal.provisional.p2.artifact.repository.*;
 import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
 import org.eclipse.equinox.internal.provisional.p2.core.repository.IRepository;
 import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey;
-import org.eclipse.equinox.internal.provisional.p2.metadata.generator.*;
 import org.eclipse.equinox.internal.provisional.spi.p2.artifact.repository.SimpleArtifactRepositoryFactory;
 import org.eclipse.equinox.internal.provisional.spi.p2.core.repository.AbstractRepository;
 import org.osgi.framework.BundleContext;
@@ -147,7 +149,7 @@
 	}
 
 	public OutputStream getOutputStream(IArtifactDescriptor descriptor) throws ProvisionException {
-		return artifactRepository.getOutputStream(descriptor);
+		return getOutputStream(descriptor, true);
 	}
 
 	public void removeAll() {
@@ -165,4 +167,8 @@
 	public void addDescriptors(IArtifactDescriptor[] descriptors) {
 		artifactRepository.addDescriptors(descriptors);
 	}
+
+	public OutputStream getOutputStream(IArtifactDescriptor descriptor, boolean overwrite) throws ProvisionException {
+		return artifactRepository.getOutputStream(descriptor, overwrite);
+	}
 }
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/artifact/UpdateSiteArtifactRepositoryFactory.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/artifact/UpdateSiteArtifactRepositoryFactory.java
index 2ffe8e7..3e8c223 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/artifact/UpdateSiteArtifactRepositoryFactory.java
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/artifact/UpdateSiteArtifactRepositoryFactory.java
@@ -11,18 +11,86 @@
 package org.eclipse.equinox.internal.p2.updatesite.artifact;
 
 import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
 import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.equinox.internal.provisional.p2.artifact.repository.IArtifactRepository;
+import org.eclipse.equinox.internal.p2.publisher.MetadataGeneratorHelper;
+import org.eclipse.equinox.internal.p2.publisher.actions.FeaturesAction;
+import org.eclipse.equinox.internal.p2.publisher.features.*;
+import org.eclipse.equinox.internal.p2.updatesite.metadata.UpdateSiteMetadataRepositoryFactory;
+import org.eclipse.equinox.internal.provisional.p2.artifact.repository.*;
 import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
+import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey;
 import org.eclipse.equinox.internal.provisional.spi.p2.artifact.repository.IArtifactRepositoryFactory;
+import org.eclipse.equinox.internal.provisional.spi.p2.artifact.repository.SimpleArtifactRepositoryFactory;
 
 public class UpdateSiteArtifactRepositoryFactory implements IArtifactRepositoryFactory {
 
+	private static final String PROP_ARTIFACT_REFERENCE = "artifact.reference"; //$NON-NLS-1$
+	private static final String PROP_FORCE_THREADING = "eclipse.p2.force.threading"; //$NON-NLS-1$
+	private static final String PROP_SITE_CHECKSUM = "site.checksum"; //$NON-NLS-1$
+	private static final String PROTOCOL_FILE = "file"; //$NON-NLS-1$
+
 	public IArtifactRepository create(URL location, String name, String type) {
 		return null;
 	}
 
 	public IArtifactRepository load(URL location, IProgressMonitor monitor) throws ProvisionException {
-		return new UpdateSiteArtifactRepository(location, monitor);
+		IArtifactRepository repository = loadRepository(location, monitor);
+		initializeRepository(repository, location, monitor);
+		return repository;
+	}
+
+	public IArtifactRepository loadRepository(URL location, IProgressMonitor monitor) throws ProvisionException {
+		URL localRepositoryURL = UpdateSiteMetadataRepositoryFactory.getLocalRepositoryLocation(location);
+		SimpleArtifactRepositoryFactory factory = new SimpleArtifactRepositoryFactory();
+		try {
+			return factory.load(localRepositoryURL, null);
+		} catch (ProvisionException e) {
+			//fall through and create a new repository
+		}
+		String repositoryName = "update site: " + location.toExternalForm(); //$NON-NLS-1$
+		return factory.create(localRepositoryURL, repositoryName, null);
+	}
+
+	public void initializeRepository(IArtifactRepository repository, URL location, IProgressMonitor monitor) throws ProvisionException {
+		UpdateSite updateSite = UpdateSite.load(location, null);
+		String savedChecksum = (String) repository.getProperties().get(PROP_SITE_CHECKSUM);
+		if (savedChecksum != null && savedChecksum.equals(updateSite.getChecksum()))
+			return;
+
+		if (!location.getProtocol().equals(PROTOCOL_FILE))
+			repository.setProperty(PROP_FORCE_THREADING, "true"); //$NON-NLS-1$
+		repository.setProperty(PROP_SITE_CHECKSUM, updateSite.getChecksum());
+		repository.removeAll();
+		generateMetadata(updateSite, repository);
+	}
+
+	private void generateMetadata(UpdateSite updateSite, IArtifactRepository repository) throws ProvisionException {
+		Feature[] features = updateSite.loadFeatures();
+		Set allSiteArtifacts = new HashSet();
+		for (int i = 0; i < features.length; i++) {
+			Feature feature = features[i];
+			IArtifactKey featureKey = FeaturesAction.createFeatureArtifactKey(feature.getId(), feature.getVersion());
+			ArtifactDescriptor featureArtifactDescriptor = new ArtifactDescriptor(featureKey);
+			URL featureURL = updateSite.getFeatureURL(null, feature.getId(), feature.getVersion());
+			featureArtifactDescriptor.setRepositoryProperty(PROP_ARTIFACT_REFERENCE, featureURL.toExternalForm());
+			allSiteArtifacts.add(featureArtifactDescriptor);
+
+			FeatureEntry[] featureEntries = feature.getEntries();
+			for (int j = 0; j < featureEntries.length; j++) {
+				FeatureEntry entry = featureEntries[j];
+				if (entry.isPlugin() && !entry.isRequires()) {
+					IArtifactKey key = MetadataGeneratorHelper.createBundleArtifactKey(entry.getId(), entry.getVersion());
+					ArtifactDescriptor artifactDescriptor = new ArtifactDescriptor(key);
+					URL pluginURL = updateSite.getPluginURL(entry);
+					artifactDescriptor.setRepositoryProperty(PROP_ARTIFACT_REFERENCE, pluginURL.toExternalForm());
+					allSiteArtifacts.add(artifactDescriptor);
+				}
+			}
+		}
+
+		IArtifactDescriptor[] descriptors = (IArtifactDescriptor[]) allSiteArtifacts.toArray(new IArtifactDescriptor[allSiteArtifacts.size()]);
+		repository.addDescriptors(descriptors);
 	}
 }
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/messages.properties b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/messages.properties
index d37905e..dd8b7c4 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/messages.properties
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/messages.properties
@@ -9,9 +9,5 @@
 #     IBM Corporation - initial API and implementation
 ###############################################################################
 ErrorCreatingRepository=Error occurred while creating repository.
-ErrorReadingDigest=Error reading site digest {0}.
-ErrorReadingFeature=Error reading feature {0}.
-ErrorReadingSite=Error reading update site {0}.
-InvalidRepositoryLocation=Invalid repository location {0}.
 PlatformAdminNotRegistered=PlatformAdmin not registered.
 MalformedArchiveURL=Malformed URL {0} for path {1} in site at {2}.
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepository.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepository.java
index 4037101..e867f3d 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepository.java
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepository.java
@@ -15,22 +15,22 @@
 import java.net.URL;
 import java.util.*;
 import org.eclipse.core.runtime.*;
-import org.eclipse.equinox.internal.p2.metadata.generator.features.*;
-import org.eclipse.equinox.internal.p2.updatesite.*;
+import org.eclipse.equinox.internal.p2.publisher.BundleDescriptionFactory;
+import org.eclipse.equinox.internal.p2.publisher.MetadataGeneratorHelper;
+import org.eclipse.equinox.internal.p2.publisher.features.*;
+import org.eclipse.equinox.internal.p2.updatesite.Activator;
 import org.eclipse.equinox.internal.p2.updatesite.Messages;
 import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
 import org.eclipse.equinox.internal.provisional.p2.core.repository.IRepository;
 import org.eclipse.equinox.internal.provisional.p2.metadata.IArtifactKey;
 import org.eclipse.equinox.internal.provisional.p2.metadata.IInstallableUnit;
-import org.eclipse.equinox.internal.provisional.p2.metadata.generator.*;
 import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository;
 import org.eclipse.equinox.internal.provisional.p2.query.Collector;
 import org.eclipse.equinox.internal.provisional.p2.query.Query;
 import org.eclipse.equinox.internal.provisional.spi.p2.core.repository.AbstractRepository;
 import org.eclipse.equinox.internal.provisional.spi.p2.metadata.repository.SimpleMetadataRepositoryFactory;
-import org.eclipse.osgi.service.resolver.*;
+import org.eclipse.osgi.service.resolver.BundleDescription;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
 
 public class UpdateSiteMetadataRepository extends AbstractRepository implements IMetadataRepository {
 
@@ -85,7 +85,7 @@
 		Properties extraProperties = new Properties();
 		extraProperties.put(IInstallableUnit.PROP_PARTIAL_IU, Boolean.TRUE.toString());
 		Set allSiteIUs = new HashSet();
-		BundleDescriptionFactory bundleDesciptionFactory = initializeBundleDescriptionFactory(Activator.getBundleContext());
+		BundleDescriptionFactory bundleDesciptionFactory = BundleDescriptionFactory.getBundleDescriptionFactory(Activator.getBundleContext());
 
 		for (int i = 0; i < features.length; i++) {
 			Feature feature = features[i];
@@ -107,7 +107,7 @@
 				}
 			}
 
-			IInstallableUnit featureIU = MetadataGeneratorHelper.createFeatureJarIU(feature, true);
+			IInstallableUnit featureIU = MetadataGeneratorHelper.createFeatureJarIU(feature, null, true, null);
 			IInstallableUnit groupIU = MetadataGeneratorHelper.createGroupIU(feature, featureIU);
 
 			String featureKey = feature.getId() + FEATURE_VERSION_SEPARATOR + feature.getVersion();
@@ -135,13 +135,6 @@
 		metadataRepository.addInstallableUnits(ius);
 	}
 
-	/*(non-Javadoc)
-	 * @see IMetadataRepositoryFactory#validate(URL, IProgressMonitor)
-	 */
-	public static void validate(URL url, IProgressMonitor monitor) throws ProvisionException {
-		UpdateSite.validate(url, monitor);
-	}
-
 	private IMetadataRepository initializeMetadataRepository(BundleContext context, URL stateDirURL, String repositoryName) {
 		SimpleMetadataRepositoryFactory factory = new SimpleMetadataRepositoryFactory();
 		try {
@@ -152,22 +145,6 @@
 		return factory.create(stateDirURL, repositoryName, null);
 	}
 
-	private BundleDescriptionFactory initializeBundleDescriptionFactory(BundleContext context) {
-		ServiceReference reference = context.getServiceReference(PlatformAdmin.class.getName());
-		if (reference == null)
-			throw new IllegalStateException(Messages.PlatformAdminNotRegistered);
-		PlatformAdmin platformAdmin = (PlatformAdmin) context.getService(reference);
-		if (platformAdmin == null)
-			throw new IllegalStateException(Messages.PlatformAdminNotRegistered);
-
-		try {
-			StateObjectFactory stateObjectFactory = platformAdmin.getFactory();
-			return new BundleDescriptionFactory(stateObjectFactory, null);
-		} finally {
-			context.ungetService(reference);
-		}
-	}
-
 	public Map getProperties() {
 		Map result = new HashMap(metadataRepository.getProperties());
 		result.remove(IRepository.PROP_SYSTEM);
diff --git a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepositoryFactory.java b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepositoryFactory.java
index 7eda55e..1eece25 100644
--- a/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepositoryFactory.java
+++ b/bundles/org.eclipse.equinox.p2.updatesite/src/org/eclipse/equinox/internal/p2/updatesite/metadata/UpdateSiteMetadataRepositoryFactory.java
@@ -10,36 +10,83 @@
  *******************************************************************************/
 package org.eclipse.equinox.internal.p2.updatesite.metadata;
 
+import java.io.File;
+import java.net.MalformedURLException;
 import java.net.URL;
 import org.eclipse.core.runtime.*;
+import org.eclipse.equinox.internal.p2.publisher.*;
+import org.eclipse.equinox.internal.p2.publisher.features.UpdateSite;
+import org.eclipse.equinox.internal.p2.updatesite.*;
+import org.eclipse.equinox.internal.p2.updatesite.Activator;
+import org.eclipse.equinox.internal.p2.updatesite.Messages;
 import org.eclipse.equinox.internal.provisional.p2.core.ProvisionException;
 import org.eclipse.equinox.internal.provisional.p2.metadata.repository.IMetadataRepository;
 import org.eclipse.equinox.internal.provisional.spi.p2.metadata.repository.IMetadataRepositoryFactory;
+import org.eclipse.equinox.internal.provisional.spi.p2.metadata.repository.SimpleMetadataRepositoryFactory;
 
 public class UpdateSiteMetadataRepositoryFactory implements IMetadataRepositoryFactory {
+	private static final String PROP_SITE_CHECKSUM = "site.checksum"; //$NON-NLS-1$
+
+	public static URL getLocalRepositoryLocation(URL location) throws ProvisionException {
+		URL localRepositoryURL = null;
+		try {
+			String stateDirName = Integer.toString(location.toExternalForm().hashCode());
+			File bundleData = Activator.getBundleContext().getDataFile(null);
+			File stateDir = new File(bundleData, stateDirName);
+			localRepositoryURL = stateDir.toURL();
+		} catch (MalformedURLException e) {
+			throw new ProvisionException(new Status(IStatus.ERROR, Activator.ID, Messages.ErrorCreatingRepository, e));
+		}
+		return localRepositoryURL;
+	}
 
 	public IMetadataRepository create(URL location, String name, String type) {
 		return null;
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * @see org.eclipse.equinox.internal.provisional.spi.p2.metadata.repository.IMetadataRepositoryFactory#validate(java.net.URL, org.eclipse.core.runtime.IProgressMonitor)
-	 */
-
 	public IStatus validate(URL location, IProgressMonitor monitor) {
 		try {
-			UpdateSiteMetadataRepository.validate(location, monitor);
+			UpdateSite.validate(location, monitor);
 		} catch (ProvisionException e) {
 			return e.getStatus();
 		}
 		return Status.OK_STATUS;
 	}
 
-	/* (non-Javadoc)
-	 * @see org.eclipse.equinox.internal.provisional.spi.p2.metadata.repository.IMetadataRepositoryFactory#load(java.net.URL, org.eclipse.core.runtime.IProgressMonitor)
-	 */
 	public IMetadataRepository load(URL location, IProgressMonitor monitor) throws ProvisionException {
-		return new UpdateSiteMetadataRepository(location, monitor);
+		IMetadataRepository repository = loadRepository(location, monitor);
+		initializeRepository(repository, location, monitor);
+		return repository;
 	}
+
+	public IMetadataRepository loadRepository(URL location, IProgressMonitor monitor) throws ProvisionException {
+		URL localRepositoryURL = getLocalRepositoryLocation(location);
+		SimpleMetadataRepositoryFactory factory = new SimpleMetadataRepositoryFactory();
+		try {
+			return factory.load(localRepositoryURL, null);
+		} catch (ProvisionException e) {
+			//fall through and create a new repository
+		}
+		String repositoryName = "update site: " + location.toExternalForm(); //$NON-NLS-1$
+		return factory.create(localRepositoryURL, repositoryName, null);
+	}
+
+	public void initializeRepository(IMetadataRepository repository, URL location, IProgressMonitor monitor) throws ProvisionException {
+		UpdateSite updateSite = UpdateSite.load(location, null);
+		String savedChecksum = (String) repository.getProperties().get(PROP_SITE_CHECKSUM);
+		if (savedChecksum != null && savedChecksum.equals(updateSite.getChecksum()))
+			return;
+		repository.setProperty(PROP_SITE_CHECKSUM, updateSite.getChecksum());
+		repository.removeAll();
+		generateMetadata(updateSite, repository);
+	}
+
+	private void generateMetadata(UpdateSite updateSite, IMetadataRepository repository) {
+		PublisherInfo info = new PublisherInfo();
+		info.setMetadataRepository(repository);
+		IPublishingAction[] actions = new IPublishingAction[] {new RemoteUpdateSiteAction(updateSite)};
+		Publisher publisher = new Publisher(info);
+		IStatus result = publisher.publish(actions);
+	}
+
 }
diff --git a/bundles/org.eclipse.equinox.simpleconfigurator/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.simpleconfigurator/META-INF/MANIFEST.MF
index 2214467..7e673c3 100644
--- a/bundles/org.eclipse.equinox.simpleconfigurator/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.equinox.simpleconfigurator/META-INF/MANIFEST.MF
@@ -14,6 +14,9 @@
  org.osgi.service.packageadmin;version="1.2.0",
  org.osgi.service.startlevel;version="1.0.0",
  org.osgi.util.tracker;version="1.3.0"
-Export-Package: org.eclipse.equinox.internal.provisional.configurator
+Export-Package: org.eclipse.equinox.internal.provisional.configurator,
+ org.eclipse.equinox.internal.simpleconfigurator;x-internal:=true,
+ org.eclipse.equinox.internal.simpleconfigurator.console;x-internal:=true,
+ org.eclipse.equinox.internal.simpleconfigurator.utils;x-internal:=true
 Bundle-RequiredExecutionEnvironment: CDC-1.1/Foundation-1.1,
  J2SE-1.4