561460: More comparison queries

Help and progress tracking

Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=561460

Change-Id: I9f479e36d2c4e0ef6fba5d408e2fe9dd52abbe51
diff --git a/plugins/org.eclipse.mat.api/plugin.properties b/plugins/org.eclipse.mat.api/plugin.properties
index c72f0ec..942c3fc 100644
--- a/plugins/org.eclipse.mat.api/plugin.properties
+++ b/plugins/org.eclipse.mat.api/plugin.properties
@@ -50,7 +50,7 @@
 

 # plugin.xml

 report.suspects.name = Leak Suspects

-report.suspects.help = includes leak suspects and a system overview

+report.suspects.help = includes leak suspects and a system overview.

 report.overview.name = Heap Dump Overview

 report.overview.help = includes class histogram, system properties and top consumers.

 report.top_components.name = Top Components

@@ -58,8 +58,8 @@
 report.compare.name = __hidden__/Compare Snapshots

 report.compare.help = Compare two snapshots and generate a histogram of differences in objects by class.

 

-report.suspects2.name = __hidden__/Leak Suspects by snapshot comparison

-report.suspects2.help = includes leak suspects and a system overview

+report.suspects2.name = __hidden__/Leak Suspects by Snapshot Comparison

+report.suspects2.help = includes leak suspects and a system overview from comparing two snapshots.

 report.overview2.name = __hidden__/Heap Dump Overview comparison

 report.overview2.help = includes class histogram, system properties and top consumers.

 

diff --git a/plugins/org.eclipse.mat.api/plugin.xml b/plugins/org.eclipse.mat.api/plugin.xml
index 0fb7834..177dfb5 100644
--- a/plugins/org.eclipse.mat.api/plugin.xml
+++ b/plugins/org.eclipse.mat.api/plugin.xml
Binary files differ
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/ComparisonReport.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/ComparisonReport.java
index 1373c16..bc4054e 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/ComparisonReport.java
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/ComparisonReport.java
@@ -16,14 +16,15 @@
 import org.eclipse.mat.query.IQuery;

 import org.eclipse.mat.query.IResult;

 import org.eclipse.mat.query.annotations.Argument;

+import org.eclipse.mat.query.annotations.CommandName;

 import org.eclipse.mat.query.annotations.Argument.Advice;

 import org.eclipse.mat.query.annotations.HelpUrl;

 import org.eclipse.mat.query.annotations.Icon;

 import org.eclipse.mat.snapshot.ISnapshot;

-import org.eclipse.mat.snapshot.SnapshotFactory;

 import org.eclipse.mat.snapshot.query.SnapshotQuery;

 import org.eclipse.mat.util.IProgressListener;

 

+@CommandName("comparison_report")

 @Icon("/META-INF/icons/compare.gif")

 @HelpUrl("/org.eclipse.mat.ui.help/tasks/comparingdata.html")

 public class ComparisonReport implements IQuery

@@ -34,7 +35,7 @@
     @Argument(advice = Advice.SECONDARY_SNAPSHOT)

     public ISnapshot baseline;

 

-    @Argument

+    @Argument(flag = Argument.UNFLAGGED)

     public String report = "org.eclipse.mat.api:suspects2"; //$NON-NLS-1$

 

     public IResult execute(IProgressListener listener) throws Exception

diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/annotations.properties b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/annotations.properties
index 4837a26..ad94dde 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/annotations.properties
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/inspections/annotations.properties
@@ -42,7 +42,7 @@
 
 ComparisonReport.name = Compare Snapshots Leak Report
 ComparisonReport.category = Leak Identification
-ComparisonReport.help = Runs a report designed to compare two snapshots.\
+ComparisonReport.help = Runs a report designed to compare two snapshots. \
 The default report includes leak suspects based on the growth in memory usage \
 and a system overview comparison.
 ComparisonReport.report.help = The report identifier.
diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/messages.properties b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/messages.properties
index 6edb9e9..bc44628 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/messages.properties
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/messages.properties
@@ -151,7 +151,7 @@
 ComponentReportQuery_Msg_NoCollisionRatiosFound=No maps found with collision ratios greater than 80%.

 ComponentReportQuery_Msg_NoExcessiveEmptyCollectionsFound=No excessive usage of empty collections found.

 ComponentReportQuery_Msg_NoFinalizerFound=Component does not keep object with Finalizer methods alive.

-ComponentReportQuery_Msg_NoFinalizerObjects=Heap dump contains no java.lang.ref.Finalizer objects.<br>IBM VMs implement Finalizer differently and are currently not supported by this report.
+ComponentReportQuery_Msg_NoFinalizerObjects=Heap dump contains no java.lang.ref.Finalizer objects.<br>IBM VMs implement Finalizer differently and are currently not supported by this report.

 ComponentReportQuery_Msg_NoLowFillRatiosFound=No serious amount of collections with low fill ratios found.

 ComponentReportQuery_Msg_NoSoftReferencesFound=Heap dump contains no soft references.

 ComponentReportQuery_Msg_NoWeakReferencesFound=Heap dump contains no weak references.

diff --git a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/CompareTablesQuery.java b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/CompareTablesQuery.java
index d37150e..25ed483 100644
--- a/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/CompareTablesQuery.java
+++ b/plugins/org.eclipse.mat.api/src/org/eclipse/mat/internal/snapshot/inspections/CompareTablesQuery.java
@@ -2508,7 +2508,7 @@
                     op = Operation.NONE;

             }

             this.setOp = op;

-            updateColumns();

+            // No need to update columns

         }

 

         private void addPositiveIndicator(Format formatter)

diff --git a/plugins/org.eclipse.mat.ui.help/tasks/comparingdata.dita b/plugins/org.eclipse.mat.ui.help/tasks/comparingdata.dita
index 816a259..094f4d4 100644
--- a/plugins/org.eclipse.mat.ui.help/tasks/comparingdata.dita
+++ b/plugins/org.eclipse.mat.ui.help/tasks/comparingdata.dita
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>

 <!--

-    Copyright (c) 2011 SAP AG and IBM Corporation.

+    Copyright (c) 2011, 2020 SAP AG and IBM Corporation.

     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

@@ -17,7 +17,7 @@
 		<copyright>

 			<copyryear year=""></copyryear>

 			<copyrholder>

-				Copyright (c) 2011, 2012 SAP AG and IBM Corporation.

+				Copyright (c) 2011, 2020 SAP AG and IBM Corporation.

 			    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

@@ -42,8 +42,8 @@
 

 			<p>

 				Memory Analyzer offers the possibility to compare not only the global class histograms of two different

-				heap dumps, but an arbitrary number of table-formatted results - for example the 

-				retained sets of three different objects. It doesn't matter if the tables which 

+				heap dumps, but an arbitrary number of table-formatted or tree-formatted results - for example the 

+				retained sets of three different objects. It doesn't matter if the tables or trees which 

 				are compared come from one and the same or different heap dumps.

 			</p>

 			<p>

@@ -72,14 +72,16 @@
 				tables from different heap dumps then they have to be added one by one.

 				Multiple tables from one heap dump can be added at a time.

 			</p>

-			<p>Trees can be compared as well, though they are converted to tables

-			for the purposes of the comparison. 

+			<p>Trees can be compared as well, and the comparison result is then a tree.

 			<xref href="queryingheapobjects.dita">Object Query Language (OQL)</xref> results

 			can also be compared, though only the last result from each OQL editor can be 

 			added to the Compare Basket. If another query is issued then the previous result

 			will be removed from the basket. If two OQL results need to be compared then

 			two OQL editors should be opened.</p>

-			</info>			

+			<p>If the tables or trees are filtered then the filtered result will be used for the

+			comparison. If there are derived data columns such calculated retained sizes then these

+			will be included in the comparison.</p>

+			</info>

 			<stepresult>

 				<image href="../mimes/nn_add_to_compare_basket.png">

 					<alt>Move from Navigation History to Compare Basket</alt>

@@ -167,14 +169,31 @@
 				<b>Context menu with set operations</b>

 			</cmd>

 			<info>

-				<p>If the tables have been compared using <menucascade><uicontrol>Compare Tables with all set operations</uicontrol>

-					</menucascade> then it is possible to perform different set operations on the comparison result.

+				<p>If the tables have been compared using <menucascade><uicontrol>Compare tables and trees with all set operations</uicontrol>

+					</menucascade> then it is possible to perform different set operations on the comparison result using the

+					context menu.

+					Set operations only operate when there are two or more tables or trees from the current snapshot.

+					In this situation, even if other comparison query has been chosen, then the menu toolbar contain a <menucascade><uicontrol>Choose set operation ...</uicontrol></menucascade>

+					menu which will select which set operations appear on the context menu.

 				</p>

 				<image href="../mimes/setops_menu.png">

 					<alt>Set Operations context menu</alt>

 				</image>

 			</info>

 			</step>

+			<step>

+			<cmd>

+				<b>Comparison reports</b>

+			</cmd>

+			<info>

+				There are some reports which operate by comparing two snapshots.

+				The <cmdname>Leak Suspects by Snapshot Comparison</cmdname> report

+				available from the Overview pane runs a special <xref href="runningleaksuspectreport.dita">Leak Suspects report</xref>

+				which operates by comparing the dominator trees of the two snapshots and detects larger changes in retained sizes between

+				corresponding objects.

+				The query is also available from <menucascade><uicontrol>Leak Suspects</uicontrol><uicontrol>Compare Snapshots Leak Report</uicontrol></menucascade>.

+			</info>

+			</step>

 		</steps>

 	</taskbody>

 </task>

diff --git a/plugins/org.eclipse.mat.ui.help/tasks/comparingdata.html b/plugins/org.eclipse.mat.ui.help/tasks/comparingdata.html
index ad71230..007d65f 100644
--- a/plugins/org.eclipse.mat.ui.help/tasks/comparingdata.html
+++ b/plugins/org.eclipse.mat.ui.help/tasks/comparingdata.html
@@ -6,8 +6,8 @@
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <meta name="DC.Type" content="task"/>
 <meta name="DC.Title" content="Comparing Objects"/>
-<meta name="copyright" content="Copyright (c) 2011, 2012 SAP AG and IBM Corporation. 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 " type="primary"/>
-<meta name="DC.Rights.Owner" content="Copyright (c) 2011, 2012 SAP AG and IBM Corporation. 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 " type="primary"/>
+<meta name="copyright" content="Copyright (c) 2011, 2020 SAP AG and IBM Corporation. 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 " type="primary"/>
+<meta name="DC.Rights.Owner" content="Copyright (c) 2011, 2020 SAP AG and IBM Corporation. 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 " type="primary"/>
 <meta name="DC.Format" content="XHTML"/>
 <meta name="DC.Identifier" content="task_comparingdata"/>
 <meta name="DC.Language" content="en-us"/>
@@ -39,8 +39,8 @@
 
 			<p class="p">
 				Memory Analyzer offers the possibility to compare not only the global class histograms of two different
-				heap dumps, but an arbitrary number of table-formatted results - for example the 
-				retained sets of three different objects. It doesn't matter if the tables which 
+				heap dumps, but an arbitrary number of table-formatted or tree-formatted results - for example the 
+				retained sets of three different objects. It doesn't matter if the tables or trees which 
 				are compared come from one and the same or different heap dumps.
 			</p>
 
@@ -76,15 +76,18 @@
 				Multiple tables from one heap dump can be added at a time.
 			</p>
 
-			<p class="p">Trees can be compared as well, though they are converted to tables
-			for the purposes of the comparison. 
+			<p class="p">Trees can be compared as well, and the comparison result is then a tree.
 			<a class="xref" href="queryingheapobjects.html">Object Query Language (OQL)</a> results
 			can also be compared, though only the last result from each OQL editor can be 
 			added to the Compare Basket. If another query is issued then the previous result
 			will be removed from the basket. If two OQL results need to be compared then
 			two OQL editors should be opened.</p>
 
-			</div>			
+			<p class="p">If the tables or trees are filtered then the filtered result will be used for the
+			comparison. If there are derived data columns such calculated retained sizes then these
+			will be included in the comparison.</p>
+
+			</div>
 			<div class="itemgroup stepresult">
 				<img class="image" src="../mimes/nn_add_to_compare_basket.png" alt="Move from Navigation History to Compare Basket"/>
 			</div>
@@ -166,12 +169,29 @@
 				<strong class="ph b">Context menu with set operations</strong>
 			</span>
 			<div class="itemgroup info">
-				<p class="p">If the tables have been compared using <span class="ph menucascade"><span class="ph uicontrol">Compare Tables with all set operations</span></span> then it is possible to perform different set operations on the comparison result.
+				<p class="p">If the tables have been compared using <span class="ph menucascade"><span class="ph uicontrol">Compare tables and trees with all set operations</span></span> then it is possible to perform different set operations on the comparison result using the
+					context menu.
+					Set operations only operate when there are two or more tables or trees from the current snapshot.
+					In this situation, even if other comparison query has been chosen, then the menu toolbar contain a <span class="ph menucascade"><span class="ph uicontrol">Choose set operation ...</span></span>
+					menu which will select which set operations appear on the context menu.
 				</p>
 
 				<img class="image" src="../mimes/setops_menu.png" alt="Set Operations context menu"/>
 			</div>
 			</li>
+<li class="li step stepexpand">
+			<span class="ph cmd">
+				<strong class="ph b">Comparison reports</strong>
+			</span>
+			<div class="itemgroup info">
+				There are some reports which operate by comparing two snapshots.
+				The <span class="keyword cmdname">Leak Suspects by Snapshot Comparison</span> report
+				available from the Overview pane runs a special <a class="xref" href="runningleaksuspectreport.html">Leak Suspects report</a>
+				which operates by comparing the dominator trees of the two snapshots and detects larger changes in retained sizes between
+				corresponding objects.
+				The query is also available from <span class="ph menucascade"><span class="ph uicontrol">Leak Suspects</span> &gt; <span class="ph uicontrol">Compare Snapshots Leak Report</span></span>.
+			</div>
+			</li>
 </ol>
 
 	</div>
diff --git a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/compare/CompareBasketView.java b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/compare/CompareBasketView.java
index 70a1598..bba396b 100644
--- a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/compare/CompareBasketView.java
+++ b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/compare/CompareBasketView.java
@@ -15,6 +15,10 @@
 import java.util.List;

 import java.util.Set;

 

+import org.eclipse.core.runtime.IProgressMonitor;

+import org.eclipse.core.runtime.IStatus;

+import org.eclipse.core.runtime.Status;

+import org.eclipse.core.runtime.jobs.Job;

 import org.eclipse.jface.action.Action;

 import org.eclipse.jface.action.IMenuListener;

 import org.eclipse.jface.action.IMenuManager;

@@ -31,6 +35,7 @@
 import org.eclipse.jface.viewers.TableViewer;

 import org.eclipse.jface.viewers.TableViewerColumn;

 import org.eclipse.jface.viewers.Viewer;

+import org.eclipse.mat.SnapshotException;

 import org.eclipse.mat.query.IQueryContext;

 import org.eclipse.mat.query.IResult;

 import org.eclipse.mat.query.IResultTable;

@@ -49,6 +54,7 @@
 import org.eclipse.mat.ui.accessibility.AccessibleCompositeAdapter;

 import org.eclipse.mat.ui.actions.QueryDropDownMenuAction;

 import org.eclipse.mat.ui.editor.AbstractEditorPane;

+import org.eclipse.mat.ui.editor.AbstractPaneJob;

 import org.eclipse.mat.ui.editor.CompositeHeapEditorPane;

 import org.eclipse.mat.ui.editor.MultiPaneEditor;

 import org.eclipse.mat.ui.internal.panes.QueryResultPane;

@@ -60,7 +66,7 @@
 import org.eclipse.mat.ui.util.NavigatorState.IStateChangeListener;

 import org.eclipse.mat.ui.util.PaneState;

 import org.eclipse.mat.ui.util.PopupMenu;

-import org.eclipse.mat.util.VoidProgressListener;

+import org.eclipse.mat.ui.util.ProgressMonitorWrapper;

 import org.eclipse.swt.SWT;

 import org.eclipse.swt.events.MenuAdapter;

 import org.eclipse.swt.events.MenuEvent;

@@ -448,7 +454,7 @@
 		{

 		    try

 		    {

-                MultiPaneEditor editor = getEditor();

+                final MultiPaneEditor editor = getEditor();

 

                 final List<IStructuredResult> tables = new ArrayList<IStructuredResult>(results.size());

                 final List<ISnapshot> snapshots = new ArrayList<ISnapshot>(results.size());

@@ -459,14 +465,34 @@
                 }

 

                 String query = "comparetablesquery"; //$NON-NLS-1$

-                SnapshotQuery compareQuery = SnapshotQuery.lookup(query,

+                final SnapshotQuery compareQuery = SnapshotQuery.lookup(query,

                                 (ISnapshot) editor.getQueryContext().get(ISnapshot.class, null));

                 compareQuery.setArgument("tables", tables); //$NON-NLS-1$

                 compareQuery.setArgument("snapshots", snapshots); //$NON-NLS-1$

-                IResult absolute = compareQuery.execute(new VoidProgressListener());

-                QueryResult queryResult = new QueryResult(null, Messages.CompareBasketView_ComparedTablesResultTitle,

-                                absolute);

-                QueryExecution.displayResult(editor, null, null, queryResult, false);

+                // Asynchronous as may take a while

+                Job job = new AbstractPaneJob(compareQuery.getDescriptor().getIdentifier(), null)

+                {

+                    @Override

+                    protected IStatus doRun(IProgressMonitor monitor)

+                    {

+                        try

+                        {

+                            ProgressMonitorWrapper listener = new ProgressMonitorWrapper(monitor);

+                            IResult absolute = compareQuery.execute(listener);

+                            QueryResult queryResult = new QueryResult(null, Messages.CompareBasketView_ComparedTablesResultTitle,

+                                            absolute);

+                            QueryExecution.displayResult(editor, null, null, queryResult, false);

+                            return Status.OK_STATUS;

+                        }

+                        catch (SnapshotException e)

+                        {

+                            return ErrorHelper.createErrorStatus(e);

+                        }

+                    }

+

+                };

+                job.setUser(true);

+                job.schedule();

             }

             catch (Exception e)

             {

diff --git a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/viewer/RefinedTreeViewer.java b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/viewer/RefinedTreeViewer.java
index f5e884f..f318946 100644
--- a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/viewer/RefinedTreeViewer.java
+++ b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/internal/viewer/RefinedTreeViewer.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2008, 2012 SAP AG and IBM Corporation.

+ * Copyright (c) 2008, 2020 SAP AG and IBM Corporation.

  * 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

@@ -31,7 +31,7 @@
 import org.eclipse.mat.ui.editor.AbstractEditorPane;

 import org.eclipse.mat.ui.editor.AbstractPaneJob;

 import org.eclipse.mat.ui.editor.MultiPaneEditor;

-import org.eclipse.mat.util.VoidProgressListener;

+import org.eclipse.mat.ui.util.ProgressMonitorWrapper;

 import org.eclipse.swt.SWT;

 import org.eclipse.swt.custom.ControlEditor;

 import org.eclipse.swt.custom.TreeEditor;

@@ -279,7 +279,8 @@
                 @Override

                 protected IStatus doRun(IProgressMonitor monitor)

                 {

-                    viewer.result.calculateTotals(elements, ctrl.totals, new VoidProgressListener());

+                    ProgressMonitorWrapper listener = new ProgressMonitorWrapper(monitor);

+                    viewer.result.calculateTotals(elements, ctrl.totals, listener);

 

                     if (!viewer.control.isDisposed()) viewer.control.getDisplay().asyncExec(new Runnable()

                     {

diff --git a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/snapshot/panes/OverviewPane.java b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/snapshot/panes/OverviewPane.java
index d82f08b..9897315 100644
--- a/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/snapshot/panes/OverviewPane.java
+++ b/plugins/org.eclipse.mat.ui/src/org/eclipse/mat/ui/snapshot/panes/OverviewPane.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2008, 2010 SAP AG and others.

+ * Copyright (c) 2008, 2020 SAP AG, IBM Corporation 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

@@ -7,6 +7,7 @@
  *

  * Contributors:

  *    SAP AG - initial API and implementation

+ *    Andrew Johnson (IBM Corporation) - comparisons

  *******************************************************************************/

 package org.eclipse.mat.ui.snapshot.panes;

 

@@ -27,6 +28,7 @@
 import org.eclipse.mat.SnapshotException;

 import org.eclipse.mat.internal.snapshot.SnapshotQueryContext;

 import org.eclipse.mat.query.IResult;

+import org.eclipse.mat.query.annotations.Category;

 import org.eclipse.mat.query.registry.CommandLine;

 import org.eclipse.mat.query.registry.QueryDescriptor;

 import org.eclipse.mat.query.registry.QueryRegistry;

@@ -259,6 +261,7 @@
 

         addReportsByPattern(text, buf, Pattern.compile(".*:suspects"));//$NON-NLS-1$

         addReportsByPattern(text, buf, Pattern.compile(".*:top_components"));//$NON-NLS-1$

+        addReportsByPattern2(text, buf, Pattern.compile(".*:suspects2"));//$NON-NLS-1$

 

         buf.append("</form>");//$NON-NLS-1$

         text.setText(buf.toString(), true, false);

@@ -278,6 +281,22 @@
         }

     }

 

+    private void addReportsByPattern2(FormText text, StringBuilder buf, Pattern pattern)

+    {

+        for (SpecFactory.Report report : SpecFactory.instance().delegates())

+        {

+            if (pattern.matcher(report.getExtensionIdentifier()).matches())

+            {

+                String name = report.getName();

+                // Allow hidden category report, but remove category

+                if (name.startsWith(Category.HIDDEN + "/")) //$NON-NLS-1$

+                    name = name.substring(Category.HIDDEN.length() + 1);

+                addButton(buf, text, "create_report", "comparison_report " + report.getExtensionIdentifier(), name, //$NON-NLS-1$//$NON-NLS-2$

+                                report.getDescription());

+            }

+        }

+    }

+

     private Section createStepByStepSection()

     {

         Section section = toolkit.createSection(form.getBody(), Section.TITLE_BAR | Section.EXPANDED | Section.TWISTIE);