314144  -  need to add 'download.stats' to a few features/bundles
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 b6a9cf1..8540d5e 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
@@ -25,26 +25,42 @@
 
 public class AddRepoProperties extends Task {
 
-    private static final String       IREPOSITORY_P2_STATS_URI = "p2.statsURI";
-    private static final String       ARTIFACT_REPO_DIRECTORY  = "artifactRepoDirectory";
-    private static final String       P2_MIRRORS_URL           = "p2MirrorsURL";
-    private static final String       P2_STATS_URI             = "p2StatsURI";
+    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       P2_MIRRORS_URL                   = "p2MirrorsURL";
+    private static final String       P2_STATS_URI                     = "p2StatsURI";
+    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                    p2MirrorsURL;
     private String                    p2StatsURI;
     private Hashtable<String, String> bundleTable;
 
-    public void rewriteMirrorURL() throws ProvisionException, URISyntaxException {
+    /**
+     * 
+     * Example arguments:
+     * -DartifactRepoDirectory=D:/buildzips/RC3/
+     * -Dp2MirrorsURL=""
+     * -Dp2StatsURI -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
+     * 
+     */
+
+    public void addRepoProperties() throws ProvisionException, URISyntaxException {
         try {
             IPublisherInfo info = createPublisherInfo();
             if (info != null) {
                 IPublisherAction[] actions = createActions();
                 Publisher publisher = new Publisher(info);
                 publisher.publish(actions, new NullProgressMonitor());
-                infoOutput("artifact repository rewritten");
+                infoOutput("INFO: artifact repository rewritten");
             }
             else {
-                infoOutput("artifact repository was not rewritten");
+                infoOutput("WARNING: artifact repository was not rewritten");
             }
         }
         catch (ProvisionException e) {
@@ -89,46 +105,54 @@
 
         String existingMirrorURL = artifactRepository.getProperty(IRepository.PROP_MIRRORS_URL);
         if (existingMirrorURL != null) {
-            infoOutput("the repository had existing mirrorURL: " + existingMirrorURL);
+            infoOutput("INFO: the repository had existing mirrorURL: " + existingMirrorURL);
         }
         else {
-            infoOutput("the repository had no existing mirrorURL");
+            infoOutput("INFO: the repository had no existing mirrorURL");
         }
 
         String newMirrorURL = getP2MirrorsURL();
-        // if property given to us is empty string, assume that is
-        // the same as "removal" which is done by passing in null.
-        if ((newMirrorURL != null) && (newMirrorURL.length() == 0)) {
-            newMirrorURL = null;
-        }
-        boolean needrewrite = false;
-        String reasonForNoWrite = null;
-        if (newMirrorURL != null) {
-            // if they are the same, don't bother
-            if (!newMirrorURL.equals(existingMirrorURL)) {
-                needrewrite = true;
-            }
-            else {
-                reasonForNoWrite = "new value and existing value of mirrorURL are the same";
-            }
+        // 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 (newMirrorURL == null) {
+            infoOutput("INFO: " + P2_MIRRORS_URL + " was not specified. Any existing values not changed.");
         }
         else {
-            // newMirror is null, means removal is desired
-            if (existingMirrorURL != null) {
-                needrewrite = true;
+
+            if (newMirrorURL.length() == 0) {
+                newMirrorURL = null;
+            }
+            boolean needrewrite = false;
+            String reasonForNoWrite = null;
+            if (newMirrorURL != null) {
+                // if they are the same, don't bother
+                if (!newMirrorURL.equals(existingMirrorURL)) {
+                    needrewrite = true;
+                }
+                else {
+                    reasonForNoWrite = "INFO: new value and existing value of mirrorURL are the same";
+                }
             }
             else {
-                reasonForNoWrite = "removal of mirrorURL was indicated, but repository has no existing value.";
+                // newMirror is null, means removal is desired
+                if (existingMirrorURL != null) {
+                    needrewrite = true;
+                }
+                else {
+                    reasonForNoWrite = "INFO: removal of mirrorURL was indicated, but repository has no existing value.";
+                }
             }
-        }
-        if (needrewrite) {
-            if (result == null) {
-                result = initRepoOverwrite(artifactRepository);
+            if (needrewrite) {
+                if (result == null) {
+                    result = initRepoOverwrite(artifactRepository);
+                }
+                artifactRepository.setProperty(IRepository.PROP_MIRRORS_URL, newMirrorURL);
             }
-            artifactRepository.setProperty(IRepository.PROP_MIRRORS_URL, newMirrorURL);
-        }
-        else {
-            infoOutput(reasonForNoWrite);
+            else {
+                infoOutput(reasonForNoWrite);
+            }
         }
         return result;
     }
@@ -147,7 +171,7 @@
             // repositories ... but could also do metadata and/or accept other
             // input forms, such as p2.buildRepo.
             artifactRepoDirectory = System.getProperty(ARTIFACT_REPO_DIRECTORY);
-            infoOutput("repository directory set from '" + ARTIFACT_REPO_DIRECTORY + "': " + artifactRepoDirectory);
+            infoOutput("INFO: repository directory set from '" + ARTIFACT_REPO_DIRECTORY + "': " + artifactRepoDirectory);
         }
         return artifactRepoDirectory;
     }
@@ -163,7 +187,7 @@
     public String getP2MirrorsURL() {
         if (p2MirrorsURL == null) {
             p2MirrorsURL = System.getProperty(P2_MIRRORS_URL);
-            infoOutput("mirror URL value set from '" + P2_MIRRORS_URL + "': " + p2MirrorsURL);
+            infoOutput("INFO: mirror URL value set from '" + P2_MIRRORS_URL + "': " + p2MirrorsURL);
 
         }
         return p2MirrorsURL;
@@ -180,7 +204,7 @@
     @Override
     public void execute() throws BuildException {
         try {
-            rewriteMirrorURL();
+            addRepoProperties();
         }
         catch (ProvisionException e) {
             // e.printStackTrace();
@@ -196,52 +220,57 @@
     private PublisherInfo processStatsURI(PublisherInfo result, IArtifactRepository artifactRepository) {
 
         /*
-         * <property name='p2.statsURI'
-         * value='http://your.stats.server/stats'/>
+         * <property name='p2.statsURI' value='http://your.stats.server/stats'/>
          */
         String existingStatsURI = artifactRepository.getProperty(IREPOSITORY_P2_STATS_URI);
         if (existingStatsURI != null) {
-            infoOutput("the repository had existing statsURI: " + existingStatsURI);
+            infoOutput("INFO: the repository had existing statsURI: " + existingStatsURI);
         }
         else {
-            infoOutput("the repository had no existing statsURI");
+            infoOutput("INFO: the repository had no existing statsURI");
         }
 
         String newStatsURI = getP2StatsURI();
+        // if the property is null, that is, not specified, do nothing.
         // if property given to us is empty string, assume that is
         // the same as "removal" which is done by passing in null.
-        if ((newStatsURI != null) && (newStatsURI.length() == 0)) {
-            newStatsURI = null;
-        }
-        boolean needrewrite = false;
-        String reasonForNoWrite = null;
-        if (newStatsURI != null) {
-            // if they are the same, don't bother
-            if (!newStatsURI.equals(existingStatsURI)) {
-                needrewrite = true;
-            }
-            else {
-                reasonForNoWrite = "new value and existing value of statsURI are the same";
-            }
+        if (newStatsURI == null) {
+            infoOutput("INFO: " + P2_STATS_URI + " was not specified. Any existing values not changed.");
         }
         else {
-            // newStatsURI is null, means removal is desired
-            if (existingStatsURI != null) {
-                needrewrite = true;
+            if (newStatsURI.length() == 0) {
+                newStatsURI = null;
+            }
+            boolean needrewrite = false;
+            String reasonForNoWrite = null;
+            if (newStatsURI != null) {
+                // if they are the same, don't bother
+                if (!newStatsURI.equals(existingStatsURI)) {
+                    needrewrite = true;
+                }
+                else {
+                    reasonForNoWrite = "INFO: new value and existing value of statsURI are the same";
+                }
             }
             else {
-                reasonForNoWrite = "removal of statusURI was indicated, but repository has no existing value.";
+                // newStatsURI is null, means removal is desired
+                if (existingStatsURI != null) {
+                    needrewrite = true;
+                }
+                else {
+                    reasonForNoWrite = "INFO: removal of statusURI was indicated, but repository has no existing value.";
+                }
             }
-        }
-        if (needrewrite) {
-            if (result == null) {
-                result = initRepoOverwrite(artifactRepository);
-            }
-            artifactRepository.setProperty(IREPOSITORY_P2_STATS_URI, newStatsURI);
+            if (needrewrite) {
+                if (result == null) {
+                    result = initRepoOverwrite(artifactRepository);
+                }
+                artifactRepository.setProperty(IREPOSITORY_P2_STATS_URI, newStatsURI);
 
-        }
-        else {
-            infoOutput(reasonForNoWrite);
+            }
+            else {
+                infoOutput(reasonForNoWrite);
+            }
         }
         return result;
     }
@@ -249,7 +278,7 @@
     public String getP2StatsURI() {
         if (p2StatsURI == null) {
             p2StatsURI = System.getProperty(P2_STATS_URI);
-            infoOutput("stats URI value set from '" + P2_STATS_URI + "': " + p2StatsURI);
+            infoOutput("INFO: stats URI value set from '" + P2_STATS_URI + "': " + p2StatsURI);
 
         }
         return p2StatsURI;
@@ -264,8 +293,7 @@
     }
 
     /*
-     * This method was original based on code attached to bug 310132
-     * https://bugs.eclipse.org/bugs/show_bug.cgi?id=310132
+     * This method was original based on code attached to bug 310132 https://bugs.eclipse.org/bugs/show_bug.cgi?id=310132
      */
     private PublisherInfo processArtifactProperties(PublisherInfo result, IArtifactRepository artifactRepository) {
 
@@ -283,13 +311,16 @@
                     // 'setProperty' is not on IArtifactDescriptor?
                     if (artifact instanceof ArtifactDescriptor) {
                         String descriptiveValue = getStatsValue(bundleId);
-                        ((ArtifactDescriptor) artifact).setProperty("download.stats", descriptiveValue);
-                        infoOutput("set download.stats property for: " + artifact);
-                        infoOutput("                            to:  " + descriptiveValue);
+                        ((ArtifactDescriptor) artifact).setProperty(DOWNLOAD_STATS, descriptiveValue);
+                        infoOutput("INFO: set " + DOWNLOAD_STATS + " property for: " + artifact);
+                        infoOutput("INFO:                              to:  " + descriptiveValue);
                     }
                 }
             }
         }
+        else {
+            infoOutput("INFO: No artifacts requested to be tracked");
+        }
         return result;
     }
 
@@ -300,32 +331,76 @@
         return bundleTable.keySet();
     }
 
+
+    /*
+     * Example arguments
+     * -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
+     */
     private void initBundleTable() {
         if (bundleTable == null) {
             bundleTable = new Hashtable<String, String>();
 
-            // TODO get from properties later
-            bundleTable.put("org.eclipse.wst.jsdt.feature", "org.eclipse.wst.jsdt.feature_helios_sr0");
-            bundleTable.put("org.eclipse.wst.xml_ui.feature", "org.eclipse.wst.xml_ui.feature_helios_sr0");
-            bundleTable.put("org.eclipse.wst.web_ui.feature", "org.eclipse.wst.web.ui.feature_helios_sr0");
-            bundleTable.put("org.eclipse.jst.enterprise_ui.feature", "org.eclipse.jst.enterprise_ui.feature_helios_sr0");
+            String trackedArtifacts = getStatsTrackedArtifacts();
+            String[] trackedStringsArray = null;
+            if (trackedArtifacts != null) {
+                trackedStringsArray = trackedArtifacts.split("[,;: ]");
 
 
-            int nArtifacts = bundleTable.size();
-            infoOutput("Artifact stats processing: " + nArtifacts + " were requested for tagging.");
-            for (String bundleId : bundleTable.keySet()) {
-                infoOutput(bundleId + "\t\t" + bundleTable.get(bundleId));
+                String suffix = getStatsArtifactsSuffix();
+
+                // ISSUE: technically suffix can be empty (no version info)
+                // What is a good default, if none provided?
+                if ((suffix == null) || (suffix.length() == 0)) {
+                    suffix = "";
+                    infoOutput("WARNING: artifacts suffix was null or empty. No suffix will be used.");
+                }
+
+                for (int i = 0; i < trackedStringsArray.length; i++) {
+                    String artifactitem = trackedStringsArray[i];
+                    bundleTable.put(artifactitem, artifactitem + suffix);
+                }
+
+                int nArtifacts = bundleTable.size();
+                infoOutput("INFO: Artifact stats processing: " + nArtifacts + " were requested for tagging.");
+                for (String bundleId : bundleTable.keySet()) {
+                    infoOutput("INFO: " + bundleId + "\t\t" + bundleTable.get(bundleId));
+                }
             }
         }
         else {
-            infoOutput("Warning: bundleTable already exsisted when asked to initialize. Check program to see if there is a calling sequence error.");
+            infoOutput("WARNING: bundleTable already exsisted when asked to initialize. Check program to see if there is a calling sequence error.");
         }
     }
 
     private String getStatsValue(String bundleId) {
+        // technically, may be impossible, or an error, for bundleTable to be null here,
+        // but just in case, we'll handle.
         if (bundleTable == null) {
             initBundleTable();
         }
         return bundleTable.get(bundleId);
     }
+
+    public String getStatsTrackedArtifacts() {
+        if (statsTrackedArtifacts == null) {
+            statsTrackedArtifacts = System.getProperty(STATS_TRACKED_ARTIFACTS_PROPERTY);
+        }
+        return statsTrackedArtifacts;
+    }
+
+    public void setStatsTrackedArtifacts(String statsTrackedArtifacts) {
+        this.statsTrackedArtifacts = statsTrackedArtifacts;
+    }
+
+    public String getStatsArtifactsSuffix() {
+        if (statsArtifactsSuffix == null) {
+            statsArtifactsSuffix = System.getProperty(STATS_ARTIFACTS_SUFFIX);
+        }
+        return statsArtifactsSuffix;
+    }
+
+    public void setStatsArtifactsSuffix(String statsArtifactsSuffix) {
+        this.statsArtifactsSuffix = statsArtifactsSuffix;
+    }
 }
diff --git a/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/AddRepoPropertiesApplication.java b/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/AddRepoPropertiesApplication.java
index 7cfef7a..6b2ee4b 100644
--- a/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/AddRepoPropertiesApplication.java
+++ b/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/AddRepoPropertiesApplication.java
@@ -11,7 +11,7 @@
     public Object start(IApplicationContext context) throws Exception {
         Object result = null;
         try {
-            new AddRepoProperties().rewriteMirrorURL();
+            new AddRepoProperties().addRepoProperties();
             result = IApplication.EXIT_OK;
         }
         catch (ProvisionException e) {
diff --git a/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/handy.jpage b/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/handy.jpage
index 94964f0..61e8081 100644
--- a/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/handy.jpage
+++ b/plugins/org.eclipse.wtp.releng.tools/src/org/eclipse/wtp/releng/tools/handy.jpage
@@ -25,3 +25,13 @@
 System.out.println(a);
 
 
+String trackedArtifacts = "one,two,three four:five";
+String[] trackedStringsArray = null;
+if (trackedArtifacts != null) {
+    trackedStringsArray = trackedArtifacts.split("[,;: ]");
+}
+for (int i = 0; i < trackedStringsArray.length; i++) {
+System.out.println(trackedStringsArray[i]);
+}
+
+