diff --git a/plugins/org.eclipse.wtp.releng.tools/META-INF/MANIFEST.MF b/plugins/org.eclipse.wtp.releng.tools/META-INF/MANIFEST.MF
index 03b1091af3c1fa3635c8e4f93e94fd0f6debfcd3..a0fbc2ec41ef443eb9b7a2d9feee9ad1e2d7e44c 100644
--- a/plugins/org.eclipse.wtp.releng.tools/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.wtp.releng.tools/META-INF/MANIFEST.MF
@@ -4,7 +4,7 @@ Bundle-Name: %Bundle-Name.0
 Bundle-SymbolicName: org.eclipse.wtp.releng.tools;singleton:=true
 Bundle-Activator: org.eclipse.wtp.releng.tools.Activator
 Bundle-ActivationPolicy: lazy
-Bundle-Version: 1.1.3.qualifier
+Bundle-Version: 1.1.4.qualifier
 Require-Bundle: org.eclipse.core.runtime,
  org.apache.ant;bundle-version="[1.6.5,2.0.0)",
  org.eclipse.equinox.p2.publisher,
@@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.core.runtime,
  org.eclipse.osgi,
  org.eclipse.equinox.p2.repository,
  org.eclipse.equinox.p2.metadata,
- org.eclipse.equinox.p2.artifact.repository
+ org.eclipse.equinox.p2.artifact.repository,
+ org.eclipse.equinox.p2.metadata.repository
 Bundle-Localization: plugin
 Bundle-ClassPath: wtpRelengTools.jar
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/AddRepoProperties.java b/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/AddRepoProperties.java
index b52a95b8d2043d8b08cdb2fc7c5f4b474f9ab483..ee0ac8a059d2f3d7d10840ddf527c1e45dc6b467 100644
--- a/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/AddRepoProperties.java
+++ b/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/AddRepoProperties.java
@@ -9,6 +9,8 @@ import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.Task;
 import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.equinox.internal.p2.artifact.repository.simple.SimpleArtifactRepositoryFactory;
+import org.eclipse.equinox.internal.p2.metadata.repository.SimpleMetadataRepositoryFactory;
+import org.eclipse.equinox.p2.core.IProvisioningAgent;
 import org.eclipse.equinox.p2.core.ProvisionException;
 import org.eclipse.equinox.p2.publisher.IPublisherAction;
 import org.eclipse.equinox.p2.publisher.IPublisherInfo;
@@ -22,33 +24,43 @@ import org.eclipse.equinox.p2.repository.artifact.ArtifactDescriptorQuery;
 import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor;
 import org.eclipse.equinox.p2.repository.artifact.IArtifactRepository;
 import org.eclipse.equinox.p2.repository.artifact.spi.ArtifactDescriptor;
+import org.eclipse.equinox.p2.repository.metadata.IMetadataRepository;
 
 public class AddRepoProperties extends Task {
 
     private static final String       DOWNLOAD_STATS                   = "download.stats";
     private static final String       IREPOSITORY_P2_STATS_URI         = "p2.statsURI";
     private static final String       ARTIFACT_REPO_DIRECTORY          = "artifactRepoDirectory";
+    private static final String       METADATA_REPO_DIRECTORY          = "metadataRepoDirectory";
     private static final String       P2_MIRRORS_URL                   = "p2MirrorsURL";
     private static final String       P2_STATS_URI                     = "p2StatsURI";
+    private static final String       P2_ARTIFACT_REPOSITORY_NAME      = "p2ArtifactRepositoryName";
+    private static final String       P2_METADATA_REPOSITORY_NAME      = "p2MetadataRepositoryName";
     private static final String       STATS_TRACKED_ARTIFACTS_PROPERTY = "statsTrackedArtifacts";
     private static final String       STATS_ARTIFACTS_SUFFIX           = "statsArtifactsSuffix";
 
     private String                    statsTrackedArtifacts;
     private String                    statsArtifactsSuffix;
     private String                    artifactRepoDirectory;
+    private String                    metadataRepoDirectory;
     private String                    p2MirrorsURL;
     private String                    p2StatsURI;
+    private String                    p2ArtifactsRepositoryName;
+    private String                    p2MetadataRepositoryName;
     private Hashtable<String, String> bundleTable;
+    private static final long         SERVICE_TIMEOUT                  = 5000;
 
     /**
-     * 
      * Example arguments:
+     * 
+     * <pre>
      * -DartifactRepoDirectory=D:/buildzips/RC3/
      * -Dp2MirrorsURL="http://www.eclipse.org/downloads/download.php?format=xml&file=/webtools/downloads/drops/R3.2.0/S-3.2.0RC3-20100527211052/repository/&protocol=http"
-     * -Dp2StatsURI=http://download.eclipse.org/stats/webtools/repository/helios
+     * -Dp2StatsURI=http://download.eclipse.org/stats/webtools/repository/helios 
      * -DstatsArtifactsSuffix=_helios_sr0
      * -DstatsTrackedArtifacts=org.eclipse.wst.jsdt.feature,org.eclipse.wst.xml_ui.feature,org.eclipse.wst.web_ui.feature,org.eclipse.jst.enterprise_ui.feature
-     * 
+     * -Dp2ArtifactsRepositoryName="Web Tools Platform Repository Helios SR0"
+     * </pre>
      */
 
     public void addRepoProperties() throws ProvisionException, URISyntaxException {
@@ -58,10 +70,10 @@ public class AddRepoProperties extends Task {
                 IPublisherAction[] actions = createActions();
                 Publisher publisher = new Publisher(info);
                 publisher.publish(actions, new NullProgressMonitor());
-                infoOutput("INFO: artifact repository rewritten");
+                infoOutput("INFO: repository rewritten");
             }
             else {
-                infoOutput("WARNING: artifact repository was not rewritten");
+                infoOutput("WARNING: repository was not rewritten");
             }
         }
         catch (ProvisionException e) {
@@ -77,26 +89,179 @@ public class AddRepoProperties extends Task {
     private IPublisherInfo createPublisherInfo() throws ProvisionException, URISyntaxException {
         PublisherInfo result = null;
 
-        String pathPart = getArtifactRepoDirectory();
-        if ((pathPart == null) || (pathPart.length() == 0)) {
-            infoOutput("The repository directory needs to be specified for this task. Try setting system property '" + ARTIFACT_REPO_DIRECTORY + "'?");
+        String pathPartArtifacts = getArtifactRepoDirectory();
+        if ((pathPartArtifacts == null) || (pathPartArtifacts.length() == 0)) {
+            infoOutput("The artifact repository directory needs to be specified for this task. Try setting system property '" + ARTIFACT_REPO_DIRECTORY + "'?");
         }
         else {
-            String repoURI = "file:/" + pathPart;
+
+            String pathPartMetadata = getMetadataRepoDirectory();
+            if ((pathPartMetadata == null) || (pathPartMetadata.length() == 0)) {
+                infoOutput("INFO: No metadata repository was specified. If desired, set the system property '" + METADATA_REPO_DIRECTORY + "'.");
+            }
+
+            String repoURIArtifacts = "file:/" + pathPartArtifacts;
+            String repoURIMetadata = null;
+            if (pathPartMetadata != null) {
+                repoURIMetadata = "file:/" + pathPartMetadata;
+            }
 
 
             SimpleArtifactRepositoryFactory simpleArtifactRepositoryFactory = new SimpleArtifactRepositoryFactory();
+
+            SimpleMetadataRepositoryFactory simpleMetadataRepositoryFactory = null;
+            if (repoURIMetadata != null) {
+                simpleMetadataRepositoryFactory = new SimpleMetadataRepositoryFactory();
+            }
+
+
             // NPE is thrown during "reload" if repository is written, and
             // agent is not set
             simpleArtifactRepositoryFactory.setAgent(Activator.getProvisioningAgent());
-            IArtifactRepository artifactRepository = simpleArtifactRepositoryFactory.load(new URI(repoURI), IRepositoryManager.REPOSITORY_HINT_MODIFIABLE, new NullProgressMonitor());
+            if (simpleMetadataRepositoryFactory != null) {
+                simpleMetadataRepositoryFactory.setAgent(Activator.getProvisioningAgent());
+            }
+            IArtifactRepository artifactRepository = simpleArtifactRepositoryFactory.load(new URI(repoURIArtifacts), IRepositoryManager.REPOSITORY_HINT_MODIFIABLE, new NullProgressMonitor());
             if (artifactRepository != null) {
+
+                result = processP2ArtifactRepositoryName(result, artifactRepository);
                 result = processMirrorsURL(result, artifactRepository);
                 result = processStatsURI(result, artifactRepository);
                 result = processArtifactProperties(result, artifactRepository);
+                if (simpleMetadataRepositoryFactory != null) {
+                    IMetadataRepository metadataRepository = simpleMetadataRepositoryFactory.load(new URI(repoURIMetadata), IRepositoryManager.REPOSITORY_HINT_MODIFIABLE, new NullProgressMonitor());
+                    if (metadataRepository != null) {
+                        result = processP2MetadataRepositoryName(result, metadataRepository);
+                    }
+                    else {
+                        infoOutput("metadata repository was null, not local, or otherwise not modifiable");
+                    }
+                }
+            }
+            else {
+                infoOutput("artifact repository was null, not local, or otherwise not modifiable");
+            }
+        }
+        return result;
+    }
+
+    private PublisherInfo processP2MetadataRepositoryName(PublisherInfo result, IMetadataRepository metadataRepository) {
+        //String existingP2MetadataRepositoryName = metadataRepository.getProperty(IRepository.PROP_NAME);
+        String existingP2MetadataRepositoryName = metadataRepository.getName();
+        if (existingP2MetadataRepositoryName != null) {
+            infoOutput("INFO: the metadata repository had existing name: " + existingP2MetadataRepositoryName);
+        }
+        else {
+            infoOutput("INFO: the metadata repository had no existing name");
+        }
+
+        String newName = getP2MetadataRepositoryName();
+        // if the property given to us is null (i.e. no specified, then do
+        // nothing to touch any existing values.
+        // if property given to us is empty string, assume that it means
+        // to remove any existing properties.
+        if (newName == null) {
+            infoOutput("INFO: " + P2_METADATA_REPOSITORY_NAME + " was not specified. Any existing values not changed.");
+        }
+        else {
+
+            if (newName.length() == 0) {
+                newName = null;
+            }
+            boolean needrewrite = false;
+            String reasonForNoWrite = null;
+            if (newName != null) {
+                // if they are the same, don't bother
+                if (!newName.equals(existingP2MetadataRepositoryName)) {
+                    needrewrite = true;
+                }
+                else {
+                    reasonForNoWrite = "INFO: new value and existing value of metadata repository name are the same";
+                }
             }
             else {
-                infoOutput("repository was null, not local, or otherwise not modifiable");
+                // value of null, means removal is desired
+                if (existingP2MetadataRepositoryName != null) {
+                    needrewrite = true;
+                }
+                else {
+                    reasonForNoWrite = "INFO: removal of metadata repository name was indicated, but repository has no existing value.";
+                }
+            }
+            if (needrewrite) {
+                if (result == null) {
+                    result = initRepoOverwrite(metadataRepository);
+                }
+                metadataRepository.setProperty(IRepository.PROP_NAME, newName);
+            }
+            else {
+                infoOutput(reasonForNoWrite);
+            }
+        }
+        return result;
+    }
+
+    private PublisherInfo processP2ArtifactRepositoryName(PublisherInfo result, IArtifactRepository artifactRepository) {
+
+//        IProvisioningAgent agent = Activator.getProvisioningAgent();
+//        IArtifactRepositoryManager manager = getService(agent, IArtifactRepositoryManager.SERVICE_NAME);
+//        String existingP2ArtifactRepositoryName  = manager.getRepositoryProperty(artifactRepository.getLocation(), IRepository.PROP_NAME);
+//        String existingP2ArtifactRepositoryName = artifactRepository.getProperty(IRepository.PROP_NAME);
+        String existingP2ArtifactRepositoryName = artifactRepository.getName();
+
+        // String existingP2ArtifactRepositoryName = artifactRepository.getProperty(IRepository.PROP_NAME);
+        if (existingP2ArtifactRepositoryName != null) {
+            infoOutput("INFO: the artifact repository had existing name: " + existingP2ArtifactRepositoryName);
+        }
+        else {
+            infoOutput("INFO: the artifact repository had no existing name");
+        }
+
+//        Map<String, String> repoInfo = artifactRepository.getProperties();
+//        System.out.println(repoInfo);
+
+
+        String newName = getP2ArtifactRepositoryName();
+        // if the property given to us is null (i.e. no specified, then do
+        // nothing to touch any existing values.
+        // if property given to us is empty string, assume that it means
+        // to remove any existing properties.
+        if (newName == null) {
+            infoOutput("INFO: " + P2_ARTIFACT_REPOSITORY_NAME + " was not specified. Any existing values not changed.");
+        }
+        else {
+
+            if (newName.length() == 0) {
+                newName = null;
+            }
+            boolean needrewrite = false;
+            String reasonForNoWrite = null;
+            if (newName != null) {
+                // if they are the same, don't bother
+                if (!newName.equals(existingP2ArtifactRepositoryName)) {
+                    needrewrite = true;
+                }
+                else {
+                    reasonForNoWrite = "INFO: new value and existing value of artifact repository name are the same";
+                }
+            }
+            else {
+                // newMirror is null, means removal is desired
+                if (existingP2ArtifactRepositoryName != null) {
+                    needrewrite = true;
+                }
+                else {
+                    reasonForNoWrite = "INFO: removal of artifact repository name was indicated, but the repository has no existing value.";
+                }
+            }
+            if (needrewrite) {
+                if (result == null) {
+                    result = initRepoOverwrite(artifactRepository);
+                }
+                artifactRepository.setProperty(IRepository.PROP_NAME, newName);
+            }
+            else {
+                infoOutput(reasonForNoWrite);
             }
         }
         return result;
@@ -172,11 +337,25 @@ public class AddRepoProperties extends Task {
             // repositories ... but could also do metadata and/or accept other
             // input forms, such as p2.buildRepo.
             artifactRepoDirectory = System.getProperty(ARTIFACT_REPO_DIRECTORY);
-            infoOutput("INFO: repository directory set from '" + ARTIFACT_REPO_DIRECTORY + "': " + artifactRepoDirectory);
+            infoOutput("INFO: artifact repository directory set from '" + ARTIFACT_REPO_DIRECTORY + "': " + artifactRepoDirectory);
         }
         return artifactRepoDirectory;
     }
 
+    public String getMetadataRepoDirectory() {
+        // if null, that is not explicitly 'set', then see if it was
+        // passed in as a system property. TODO: Does this contradict
+        // ant task rules? (That is, system property is to take priority?)
+        if (metadataRepoDirectory == null) {
+            // for now, be explicit we are working with "artifact"
+            // repositories ... but could also do metadata and/or accept other
+            // input forms, such as p2.buildRepo.
+            metadataRepoDirectory = System.getProperty(METADATA_REPO_DIRECTORY);
+            infoOutput("INFO: metadata repository directory set from '" + METADATA_REPO_DIRECTORY + "': " + metadataRepoDirectory);
+        }
+        return metadataRepoDirectory;
+    }
+
     private void infoOutput(String info) {
         System.out.println("\t" + info);
     }
@@ -293,6 +472,14 @@ public class AddRepoProperties extends Task {
         return result;
     }
 
+    private PublisherInfo initRepoOverwrite(IMetadataRepository metadataRepository) {
+        PublisherInfo result;
+        result = new PublisherInfo();
+        result.setMetadataRepository(metadataRepository);
+        result.setArtifactOptions(IPublisherInfo.A_OVERWRITE);
+        return result;
+    }
+
     /*
      * This method was original based on code attached to bug 310132 https://bugs.eclipse.org/bugs/show_bug.cgi?id=310132
      */
@@ -404,4 +591,46 @@ public class AddRepoProperties extends Task {
     public void setStatsArtifactsSuffix(String statsArtifactsSuffix) {
         this.statsArtifactsSuffix = statsArtifactsSuffix;
     }
+
+    public String getP2ArtifactRepositoryName() {
+        if (p2ArtifactsRepositoryName == null) {
+            p2ArtifactsRepositoryName = System.getProperty(P2_ARTIFACT_REPOSITORY_NAME);
+            infoOutput("INFO: p2ArtifactRepositoryName value set from '" + P2_ARTIFACT_REPOSITORY_NAME + "': " + p2ArtifactsRepositoryName);
+        }
+        return p2ArtifactsRepositoryName;
+    }
+
+    public String getP2MetadataRepositoryName() {
+        if (p2MetadataRepositoryName == null) {
+            p2MetadataRepositoryName = System.getProperty(P2_METADATA_REPOSITORY_NAME);
+            infoOutput("INFO: p2MetadataRepositoryName value set from '" + P2_METADATA_REPOSITORY_NAME + "': " + p2MetadataRepositoryName);
+        }
+        return p2MetadataRepositoryName;
+    }
+
+    public void setP2RepositoryName(String p2ArtifactsRepositoryName) {
+        this.p2ArtifactsRepositoryName = p2ArtifactsRepositoryName;
+    }
+
+    @SuppressWarnings("unchecked")
+    protected static <T> T getService(IProvisioningAgent agent, String serviceName) {
+        T service = (T) agent.getService(serviceName);
+        if (service != null)
+            return service;
+        long start = System.currentTimeMillis();
+        do {
+            try {
+                Thread.sleep(100);
+            }
+            catch (InterruptedException e) {
+                //ignore and keep waiting
+            }
+            service = (T) agent.getService(serviceName);
+            if (service != null)
+                return service;
+        }
+        while ((System.currentTimeMillis() - start) < SERVICE_TIMEOUT);
+        //could not obtain the service
+        throw new IllegalStateException("Unable to obtain required service: " + serviceName); //$NON-NLS-1$
+    }
 }