[Releng] StatsCleaner
diff --git a/plugins/org.eclipse.oomph.setup.core/StatsCleaner.launch b/plugins/org.eclipse.oomph.setup.core/StatsCleaner.launch
new file mode 100644
index 0000000..b752f13
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.core/StatsCleaner.launch
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="org.eclipse.pde.ui.RuntimeWorkbench">
+<booleanAttribute key="append.args" value="true"/>
+<stringAttribute key="application" value="org.eclipse.oomph.setup.core.StatsCleaner"/>
+<booleanAttribute key="askclear" value="false"/>
+<booleanAttribute key="automaticAdd" value="false"/>
+<booleanAttribute key="automaticValidate" value="false"/>
+<stringAttribute key="bad_container_name" value="\org.eclipse.oomph.setup.insta"/>
+<stringAttribute key="bootstrap" value=""/>
+<stringAttribute key="checked" value="[NONE]"/>
+<booleanAttribute key="clearConfig" value="true"/>
+<booleanAttribute key="clearws" value="true"/>
+<booleanAttribute key="clearwslog" value="false"/>
+<stringAttribute key="configLocation" value="${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/StatsCleaner"/>
+<booleanAttribute key="default" value="false"/>
+<booleanAttribute key="includeOptional" value="false"/>
+<stringAttribute key="location" value="${workspace_loc}/../ws-stats-cleaner"/>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
+<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog&#13;&#10;-queryLocation ${resource_loc:/org.eclipse.oomph.setup.core/stats.txt}"/>
+<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.pde.ui.workbenchClasspathProvider"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Declipse.p2.mirrors=false"/>
+<stringAttribute key="pde.version" value="3.3"/>
+<stringAttribute key="product" value="org.eclipse.sdk.ide"/>
+<stringAttribute key="selected_target_plugins" value="com.ibm.icu@default:default,javax.annotation@default:default,javax.inject@default:default,javax.xml@default:default,org.apache.batik.css*1.7.0.v201011041433@default:default,org.apache.batik.util*1.7.0.v201011041433@default:default,org.apache.batik.util.gui*1.7.0.v200903091627@default:default,org.apache.commons.codec@default:default,org.apache.commons.jxpath@default:default,org.apache.commons.logging@default:default,org.apache.httpcomponents.httpclient@default:default,org.apache.httpcomponents.httpcore@default:default,org.eclipse.ant.core@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.java7@default:false,org.eclipse.core.filesystem.win32.x86_64@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.net.win32.x86_64@default:false,org.eclipse.core.net@default:default,org.eclipse.core.resources.win32.x86_64@default:false,org.eclipse.core.resources@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.runtime@default:true,org.eclipse.core.variables@default:default,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.ecf.filetransfer@default:default,org.eclipse.ecf.identity@default:default,org.eclipse.ecf.provider.filetransfer.ssl@default:false,org.eclipse.ecf.provider.filetransfer@default:default,org.eclipse.ecf.ssl@default:false,org.eclipse.ecf@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.emf.edit@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.frameworkadmin.equinox@default:default,org.eclipse.equinox.frameworkadmin@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,org.eclipse.equinox.p2.console@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.director.app@default:default,org.eclipse.equinox.p2.director@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.p2.garbagecollector@default:default,org.eclipse.equinox.p2.jarprocessor@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.p2.operations@default:default,org.eclipse.equinox.p2.publisher.eclipse@default:default,org.eclipse.equinox.p2.publisher@default:default,org.eclipse.equinox.p2.repository.tools@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.p2.touchpoint.eclipse@default:default,org.eclipse.equinox.p2.touchpoint.natives@default:default,org.eclipse.equinox.p2.updatesite@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.security.win32.x86_64@default:false,org.eclipse.equinox.security@default:default,org.eclipse.equinox.simpleconfigurator.manipulator@default:default,org.eclipse.equinox.simpleconfigurator@1:true,org.eclipse.equinox.util@default:default,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.win32.win32.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.team.core@default:default,org.eclipse.ui.trace@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.sat4j.core@default:default,org.sat4j.pb@default:default,org.tukaani.xz@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil@default:default,org.w3c.dom.svg@default:default"/>
+<stringAttribute key="selected_workspace_plugins" value="org.eclipse.oomph.base.edit@default:default,org.eclipse.oomph.base@default:default,org.eclipse.oomph.p2.core@default:default,org.eclipse.oomph.p2@default:default,org.eclipse.oomph.preferences@default:default,org.eclipse.oomph.setup.core@default:default,org.eclipse.oomph.setup.p2@default:default,org.eclipse.oomph.setup@default:default,org.eclipse.oomph.util@default:default"/>
+<booleanAttribute key="show_selected_only" value="false"/>
+<stringAttribute key="templateConfig" value="${target_home}\configuration\config.ini"/>
+<booleanAttribute key="tracing" value="false"/>
+<booleanAttribute key="useCustomFeatures" value="false"/>
+<booleanAttribute key="useDefaultConfig" value="true"/>
+<booleanAttribute key="useDefaultConfigArea" value="true"/>
+<booleanAttribute key="useProduct" value="false"/>
+</launchConfiguration>
diff --git a/plugins/org.eclipse.oomph.setup.core/plugin.xml b/plugins/org.eclipse.oomph.setup.core/plugin.xml
index e0adbba..8e45349 100644
--- a/plugins/org.eclipse.oomph.setup.core/plugin.xml
+++ b/plugins/org.eclipse.oomph.setup.core/plugin.xml
@@ -15,4 +15,17 @@
 
    <extension-point id="stringFilters" name="String Filters" schema="schema/stringFilters.exsd"/>
 
+   <extension
+         id="StatsCleaner"
+         point="org.eclipse.core.runtime.applications">
+      <application
+            cardinality="singleton-global"
+            thread="main"
+            visible="true">
+         <run
+               class="org.eclipse.oomph.setup.internal.core.StatsCleaner">
+         </run>
+      </application>
+   </extension>
+
 </plugin>
diff --git a/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/StatsCleaner.java b/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/StatsCleaner.java
new file mode 100644
index 0000000..e5a99f7
--- /dev/null
+++ b/plugins/org.eclipse.oomph.setup.core/src/org/eclipse/oomph/setup/internal/core/StatsCleaner.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2015 Eike Stepper (Berlin, Germany) 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:
+ *    Eike Stepper - initial API and implementation
+ */
+package org.eclipse.oomph.setup.internal.core;
+
+import org.eclipse.oomph.setup.Index;
+import org.eclipse.oomph.setup.Scope;
+import org.eclipse.oomph.setup.internal.core.util.SetupCoreUtil;
+import org.eclipse.oomph.util.IOUtil;
+
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+import org.eclipse.equinox.app.IApplication;
+import org.eclipse.equinox.app.IApplicationContext;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/*
+ * Usage:
+ *
+ * Copy the <b>source code</b> of the following two pages into the file /org.eclipse.oomph.setup.core/stats.txt :
+ *
+ *   https://dev.eclipse.org/committers/committertools/stats.php?filename=/stats/oomph/product/
+ *   https://dev.eclipse.org/committers/committertools/stats.php?filename=/stats/oomph/project/
+ *
+ * Then run this application.
+ *
+ * @author Eike Stepper
+ */
+public class StatsCleaner implements IApplication
+{
+  private static final int PATH_OFFSET = "http://download/eclipse.org".length();
+
+  private static final Pattern PATTERN = Pattern.compile("javascript:fnViewDaily\\('([^']*)', 'daily'\\);");
+
+  private final List<String> allowedURIs = new ArrayList<String>();
+
+  public Object start(IApplicationContext context) throws Exception
+  {
+    String queryLocation = null;
+
+    String[] arguments = (String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
+    if (arguments != null)
+    {
+      for (int i = 0; i < arguments.length; ++i)
+      {
+        String option = arguments[i];
+        if ("-queryLocation".equals(option))
+        {
+          queryLocation = arguments[++i];
+        }
+      }
+    }
+
+    if (queryLocation == null)
+    {
+      return null;
+    }
+
+    System.out.println("Stats Cleaner");
+    System.out.println("=============");
+    System.out.println();
+
+    ResourceSet resourceSet = SetupCoreUtil.createResourceSet();
+    Resource resource = resourceSet.getResource(SetupContext.INDEX_SETUP_URI, true);
+    Index index = (Index)resource.getContents().get(0);
+
+    for (TreeIterator<EObject> it = index.eAllContents(); it.hasNext();)
+    {
+      EObject object = it.next();
+      if (object instanceof Scope)
+      {
+        Scope scope = (Scope)object;
+
+        String name = scope.getQualifiedName();
+        if (name.startsWith("self") || name.startsWith("user"))
+        {
+          continue;
+        }
+
+        allow(true, scope);
+        allow(false, scope);
+      }
+    }
+
+    for (String line : IOUtil.readLines(new File(queryLocation), "UTF-8"))
+    {
+      Matcher matcher = PATTERN.matcher(line);
+      if (matcher.find())
+      {
+        String uri = matcher.group(1);
+        if (!isAllowed(uri))
+        {
+          System.out.println(uri);
+        }
+      }
+    }
+
+    return null;
+  }
+
+  public void stop()
+  {
+  }
+
+  private void allow(boolean success, Scope scope)
+  {
+    URI uri = SetupCoreUtil.getStatsURI(success, scope);
+    if (uri != null)
+    {
+      String str = uri.toString().substring(PATH_OFFSET);
+      allowedURIs.add(str);
+    }
+  }
+
+  private boolean isAllowed(String line)
+  {
+    for (String allowedURI : allowedURIs)
+    {
+      if (line.startsWith(allowedURI))
+      {
+        return true;
+      }
+    }
+
+    return false;
+  }
+}